VPN Solutions on FreeBSD and OpenBSD — OpenVPN approach

Mathieu Kerjouan
Oct 2, 2018 · 10 min read

Virtual Private Network (VPN) is a required solution in our current interconnected world to protect our own privacy and to interconnect different network through internet. Lot of commercial solutions exists around the world to deploy any kind of VPN, but, can we trust big corportation? In this series, I will show you how to deploy rapidly multiple VPN software on my two favorites operating systems: OpenBSD and FreeBSD.

Before starting, for newbies and new comers in marvelous VPN world, what is a VPN? A VPN is a link between one or many nodes on an pre-existing network. This link (you can call it a tunnel) between each nodes is authenticated and encrypted. This tunnel create a new network where all your communications are “secure” (the flow can’t be read by anyone except the two end-point).

In this article, I will present to you OpenVPN, probably one of the most known and used VPN around the world. This tool comes from Open-Source, is easy to use, easy to configure, easy to deploy and easy to hide too. I will show you how to configure it and create your own personal VPN network in different level of complexity. The first level, in this article, is straight forward, a simple VPN authenticated only with certificate. Here a map to show you an example of the final distributed OpenVPN project.

External client connected with OpenVPN, servers interconnected with tinc

Server Configuration on OpenBSD

Before starting and doing anything, our server need some custom configuration. Firstly, this server will now act as router, need to route network packets from different interfaces and different networks, in ipv4 but also in ipv6 (in a future article). net.inet.ip.forwarding kernel state is really important. If this one is not set to 1 (enabled), all packets from others interfaces or others networks will be not forwarded, and simply discarded. During all this tutorial, if you have some problem to ping or reach a specific ports, ensure this state is well configured.

Secondly, we can play with some TCP and UDP states in the OpenBSD network stack, increasing buffer space for our UDP/TCP packets.

After this little introduction, we can now install what we need: OpenVPN and Easy-RSA on our 2 OpenBSD servers. In this case, you can install them in multiple way:

  • Using official packages from OpenBSD repository with pkg_add ;
  • Building openvpn and easy-rsa ports ;
  • Using dpb (and create your own repository at the same time).

During this tutorial, I will try to use only official packages, freely available, and doing all we need.

openvpn package let you initialize your own openvpn directory, by default, I will create it under /etc/openvpn on OpenBSD. This directory will contain all our OpenVPN configuration, but, also all managed certificates and keys for our servers/clients.

Public Key Infrastructure (PKI) is a technic to store and manage (create, sign, remove or revoke) private, public keys and certificates. easyrsa can generate this easily with the help of init-pkisubcommand. If you want to create your own manually, you can find lot of tutorial on the web.

OpenVPN, using PKI, require a Certificate Authority (CA) to works as expected. A CA is used to trust other managed certificate. This certificate will sign all our generated server or client certificates, ensuring there are correctly managed by our PKI. This file can be generated with easyrsa and build-ca subcommand.

OpenVPN gives you the ability to use many different algorithms and methods to add security to your connection. Diffie-Hellman (DH) seed, is used to exchange keys between two entities (in our case, server and client). This file can also be generated by easyrsawith gen-dh subcommand.

We have a PKI, a CA, a DH, but we still don’t have our own certificate for our OpenVPN server. This certificate will be used only for our server. Again, easyrsa can create this file with build-server-full subcommand.

At this step, you have all information required to start your own server, if you try it now, you will be prompted for a password. This password protect your server key. Sometime, its pretty useful to have a protection on this kind of file, but, in other side, each time your service will be restarted (even at boot), a password will be required. This security can be removed by using openssl and rsa subcommand.

We have a server certificate, we need at least one client certificate for testing if our OpenVPN is working as expected and test our network.

OpenVPN support TLS auth key. This file will be shared with all client and ensure another layer of security based on a shared secret.

OpenVPN can be used in many ways. We can manually start it with a long argument list like any command, or just create configuration file containing our those arguments. The last one seems easier to understand and modify. This configuration will be stored in /etc/openvpn/server.conf.

For this example, I commented the push route directive. If you have multiple connected network to your server, enabling that could be a nice idea. OpenVPN server will share these routes to OpenVPN client, and your client will be able to talk to other network easily.

OpenBSD use rcctl command to manage internal services. This command will automatically edit for you /etc/rc.conf.local with your options.

Our OpenBSD service is now active, we can start it manually.

Our OpenVPN service should run now. We can check it by using rcctl again

If your server doesn’t run… You can start to debug it in standalone mode and try to understand what’s going on!

Don’t forget to use other command like ifconfig or netstat to investigate and see if you don’t have made a mistake in your server configuration.

I always enable OpenBSD Packet Filter firewall at startup, we will add some rules to

  • Allow our OpenVPN to listen on UDP/1194 port
  • Allow all traffic flow in our VPN network
  • NAT our traffic to the outside world

Our packet filter configuration was modified, but, can be sure about our syntax? The good way before reload our firewall configuration is to test it.

If our firewall configuration is okay… We can now start packet filter with the new configuration.

We have a working OpenVPN service, listening on UDP/1194 port, a working PKI, you can now generate all your server or client certificates based on previous commands and we have a working firewall configuration. Now, the client configuration…

Client Configuration on FreeBSD

This part will show you how to configure a simple OpenVPN client with certificate authentication only. In this article, I will not show you how to connect it to another kind of authentication (e.g. LDAP or PAM).

Installing and configuring OpenVPN as client is straight forward. The first thing to do, is to install OpenVPN, you can do it, like OpenBSD, in different ways:

On FreeBSD, OpenVPN package doesn’t create any kind of users or groups, you need to create them manually. To make things easier, you can create them with the same uid/gid present on OpenBSD (577). Just to be clear, _openvpn user and group, starting with an underscore, will not work on some systems (underscore is not allowed in names).

Like our server configuration, we need to create our directory, this one will contain OpenVPN client configuration.

OpenVPN can act as server or client only by enable a switch, the configuration file is practically the same than the server configuration.

Our configuration is ready but we need to copy our certificates and our keys from our server. This is not the good way, in practice, our client will give us a Certificate Signing Request (CSR), we will sign it with our Certificate Authority and give it the requested certificate (CRT).

If you want to create your OpenVPN tunnel at startup, you need to configure our service in /etc/rc.conf, sysrc gives your the ability to do that easily.

Everything seems good! It’s the time to start our OpenVPN client service and watch if all is working as expected!

If you don’t want to tip your password key every time when are starting your server or your client configuration, you can remove this protection with openssl command.

You can now create numbers of new client and connects them to your fresh OpenVPN server. Its a good start for our infrastructure!

Monitoring tunnel

I think a best practice is to monitor and automatize everything just after all is working. You can monitor your tunnel in multiple way, personally, I like monit, a small and open-source monitoring tool. Here 2 small examples to ensure our tunnel is up and running:

If our OpenVPN crash, or, for some reason, we can’t reach our listening address, monit will send you an alert (mail by default).

Monitoring connected client

Our VPN is now up and running! You have created lot of certificate, and all your hardware is connected to your new beautiful server! But… How to supervise your client on server side?

OpenVPN create a status file in /var/log/openvpn/openvpn-status.log containing all information about connected client by adding status openvpn-status.log parameter in its configuration file.

If you want to do more, you can also enable management interface by adding management ${hostname} ${port} in your OpenVPN configuration file. This will give you access to a dynamic command prompt accessible via telnet.

Android Clients

How to connect a mobile phone or a tablet on Android? You can use OpenVPN for Android, also available on FDroid. I think, if you did all the work before, configuring a graphical OpenVPN client will be not complicated.

Next Time

VPN is a really interesting topic! This is the first one of a probably long series. This part was dedicated to client/server tunnel based on OpenVPN. In another parts, I will show you how to create a distributed network with Tinc on OpenBSD/FreeBSD, and how to share route with OSPF and bird/openospfd. We will talk about some other tunnel technology like IPSec, OCServ, MLVPN, ll other small tools to make tunnel everywhere (like netcat, socat, stunnel…) and much more (hiding a VPN or a tunnel, automatic deploy with salt/ansible…)!


  • Thanks to Calomel website, help me a lot! ❤
  • Thanks to OpenBSD, its really easy to create anything on it! ❤
  • Thanks to OpenBSD Amsterdam, nice project, I’m using your server to build my distributed VPN, and it just works. ❤
  • Thanks to FreeBSD and HardenedBSD projects. ❤
  • Thanks to you, anonymous reader, to follow me and all my adventures in the digital world!


Mathieu Kerjouan

Written by

Distributed peasant, plants Erlang and Elixir nodes everywhere he can. Uses fertilized operating system like OpenBSD and FreeBSD.