How to Install OpenVPN Server on FreeBSD 14

In this guide, I will show you how to install OpenVPN on a FreeBSD 14 server, step-by-step. I also cover the integration of pf (Packet Filter) to set up routing for OpenVPN server, and configuration of OpenVPN client for Windows and Linux clients.

Prerequisites

Before you begin, make sure you have the following:

Installing OpenVPN and easy-rsa on FreeBSD

OpenVPN is an open-source VPN daemon for securing your networks and connections. OpenVPN is available for most operating systems, on FreeBSD, you can install it via pkg package manager or manually via Ports.

Follow these steps to install OpenVPN on your FreeBSD server:

1. First, run the command below to update your FreeBSD package index. By updating the package index, you will get the latest version of package information.

pkg update
Updating package index
Updating package index

2. Now, run the command below to install the openvpn, easy-rsa, and tree packages to your FreeBSD server.

pkg install openvpn easy-rsa tree

Enter y to confirm and proceed with the installation.

Installing OpenVPN and easy-rsa on FreeBSD
Installing OpenVPN and easy-rsa on FreeBSD

3. Once the installation is done, run the command below to enable the OpenVPN service. Then, set up OpenVPN to run in tun mode.

You can run OpenVPN in two modes: tun (virtual point-to-point IP link) and tap (virtual ethernet adapter). You cannot mix those two modes, use one and stick to it.

sysrc openvpn_enable=YES
sysrc openvpn_if=tun

4. Now, run the command below to set the default OpenVPN directory to /usr/local/etc/openvpn. Then, set up the default OpenVPN configuration to /usr/local/etc/openvpn/geekandnix.conf.

sysrc openvpn_dir=/usr/local/etc/openvpn
sysrc openvpn_configfile=/usr/local/etc/openvpn/geekandnix.conf
Configure and enable OpenVPN service on FreeBSD
Configure and enable OpenVPN service on FreeBSD

5. Lastly, run the command below to verify OpenVPN parameters in the rc.conf file.

sysrc -a | grep openvpn

Make sure you have OpenVPN parameters as highlighted like the following:

Checking OpenVPN service
Checking OpenVPN service

Initializing PKI (Public Key Infrastructure) via easy-rsa

After you have installed OpenVPN, you’ll generate PKI or Public Key Infrastructure for your OpenVPN server.

Public Key Infrastructure (PKI) is the place where you can generate, issue, sign, and revoke certificates for OpenVPN servers and clients. Here, you can utilize easyrsa for those tasks related to Public Key Infrastructure.

To initialize PKI (Public Key Infrastructure), complete the following actions:

1. First, run the command below to create a new directory /usr/local/etc/certificates and move into it. This directory will be used for storing the PKI (Public Key Infrastructure) of the OpenVPN server.

mkdir -p /usr/local/etc/certificates; cd /usr/local/etc/certificates

2. Now, run the following command to copy the file vars.example to the vars file. Then, modify the vars file using vim.

cp /usr/local/share/easy-rsa/vars.example vars
vim vars

Change the default EASYRSA_ALGO and EASYRSA_DIGEST with the following, and be sure to adjust the certificate information.

set_var EASYRSA_ALGO "ec"
set_var EASYRSA_DIGEST "sha512"

set_var EASYRSA_REQ_COUNTRY    "US"
set_var EASYRSA_REQ_PROVINCE   "Geekandnix"
set_var EASYRSA_REQ_CITY       "Geekandnix"
set_var EASYRSA_REQ_ORG        "GeekAndNix.Inc"
set_var EASYRSA_REQ_EMAIL      "[email protected]"
set_var EASYRSA_REQ_OU         "Admin Ops"

When done, save and exit the file.

3. Lastly, run the easyrsa command below to initialize your Public Key Infrastructure. This will generate a new directory pki, which contains the required configurations for your PKI. Also, your OpenVPN certificates will gen generated to the pki directory.

easyrsa init-pki
Initializing PKI (Public Key Infrastructure) via easy-rsa
Initializing PKI (Public Key Infrastructure) via easy-rsa

Generating CA (Certificate Authority)

Now that you’ve initialized PKI, let’s generate certificates for the OpenVPN server.

The first certificate that you must create is CA or Certificate Authority, which will be used to sign certificates for both the OpenVPN server and clients. The private key for CA is the most important certificate, you must keep it secret.

Execute the following tasks to generate CA (Certificate Authority):

1. To generate CA (Certificate Authority) for your OpenVPN server, run the easyrsa command below.

easyrsa build-ca

2. When asked for passphrase, enter the new passphrase for your new CA and repeat. Then, enter the FreeBSD server hostname or fqdn as the Common Name.

Generating Certificate Authority or CA
Generating Certificate Authority or CA

Once the process is complete, your CA certificates will be available at:

  • Private key: /usr/local/etc/certificates/pki/private/ca.key
  • Public key: /usr/local/etc/certificates/pki/ca.crt

Generating OpenVPN server certificates

With Certificate Authority (CA) generated, move on to generate and sign the OpenVPN server certificate via the easyrsa utility.

Perform these actions to generate server certificates for your OpenVPN server:

1. First, run the command below to generate a certificate request for the OpenVPN server. In this example, I will use geekandnix as the base filename for server certificates and disable encryption in the private key via the nopass option.

easyrsa gen-req geekandnix nopass

When prompted, enter your OpenVPN server hostname or fqdn as the Common Name. Here, I will use geekandnix as the Common Name.

Generating OpenVPN server certificate
Generating OpenVPN server certificate

2. Now, run the easyrsa command below to sign your server certificate geekandnix with the CA (Certificate Authority).

easyrsa sign-req server geekandnix

Enter yes to sign your certificate. Then, type the password of your CA (Certificate Authority) when prompted.

Signing OpenVPN server certificate with CA or Certificate Authority
Signing OpenVPN server certificate with CA or Certificate Authority

3. Lastly, run the following command to generate the DHPARAM certificate.

easyrsa gen-dh
Generating DHPARAM certificate
Generating DHPARAM certificate

After everything is done, your OpenVPN server certificate and DHPARAM certificate should be available in the following:

  • OpenVPN server private key: /usr/local/etc/certificates/pki/private/geekandnix.key.
  • OpenVPN server public key: /usr/local/etc/certificates/pki/issued/geekandnix.crt.
  • DHPARAM certificate: /usr/local/etc/certificates/pki/dh.pem.

Generating OpenVPN client certificates

After you’ve generated the OpenVPN server certificate, proceed to the next stage to generate certificates for OpenVPN clients. It’s recommended to use one certificate for one client. Yes, you can use one certificate for multiple users, but it’s not recommended.

Follow these instructions to generate an OpenVPN client certificate:

1. First, run the command below to generate a certificate request for a client with the base filename john and disable encryption in the private key. So the idea here is to create certificates for user john.

easyrsa gen-req john nopass

When prompted for the Common Name configuration, input your client name.

Generating OpenVPN client certificate
Generating OpenVPN client certificate

2. Secondly, run the command below to sign the client certificate request john with your CA (Certificate Authority).

easyrsa sign-req client john

As seen below, enter yes to confirm, then input the password of your CA (Certificate Authority) when asked.

Signing OpenVPN client certificate with CA or Certificate Authority
Signing OpenVPN client certificate with CA or Certificate Authority

Once done, your client certificate should be available in the following:

  • Client private key: /usr/local/etc/certificates/pki/private/john.key.
  • Client public key: /usr/local/etc/certificates/pki/issued/john.crt.

Populating certificates for OpenVPN server and client

So far, you have generated certificates CA, server certificates, and client certificates. Next, you will populate those certificates for both the OpenVPN server and the client.

Here certificates that you need for each, server and client:

  • OpenVPN server: ca.crt, ta.key, dh.pem, geekandnix.crt (server certificate), and geekandnix.key (server key).
  • OpenVPN client: ca.crt, ta.key (you will generate this later), john.crt (client certificate), and john.key (client key).

Let’s move on to populate your OpenVPN certificates for server and client:

1. Before populating your certificates, run the openvpn command below to generate the ta.key certificate. The ta.key file will be used with the tls-auth or tls-crypt in both the OpenVPN server and clients.

openvpn --genkey tls-auth pki/ta.key

2. Now, run the command below to create new directories server and client within the /usr/local/etc/openvpn/. Those directories will be used to store required certificates for the OpenVPN server and client.

mkdir -p /usr/local/etc/openvpn/{server,client}

3. Afterward, run the command below to copy certificate files ca.crt, dh.pem, and ta.key to the /usr/local/etc/openvpn/ directory.

cp pki/{ca.crt,dh.pem,ta.key} /usr/local/etc/openvpn/

4. Then, copy certificates for the OpenVPN server to the /usr/local/etc/openvpn/server directory using the command below.

cp pki/issued/geekandnix.crt /usr/local/etc/openvpn/server
cp pki/private/geekandnix.key /usr/local/etc/openvpn/server

5. Next, run the command below to copy client certificates, ca.crt, and ta.key to the /usr/local/etc/openvpn/client/ directory.

cp pki/{ca.crt,ta.key} /usr/local/etc/openvpn/client/
cp pki/issued/john.crt /usr/local/etc/openvpn/client/
cp pki/private/john.key /usr/local/etc/openvpn/client/
Populating certificates for OpenVPN server and client
Populating certificates for OpenVPN server and client

6. Lastly, run the command below to verify the list of certificates on the /usr/local/etc/openvpn/ directory.

tree /usr/local/etc/openvpn/

So far, the list contents of your /usr/local/etc/openvpn/ directory should be like following:

Listing current certificates for OpenVPN
Listing current certificates for OpenVPN

Creating OpenVPN server configuration on FreeBSD

Having certificates ready, let’s move on to configure the OpenVPN server by creating a new configuration file /usr/local/etc/openvpn/geekandnix.conf.

Navigate through these steps to configure the OpenVPN server on the FreeBSD server:

1. To configure the OpenVPN server, run the command below to copy the default configuration to /usr/local/etc/openvpn/geekandnix.conf. Then, edit the geekandnix.conf file using vim.

cp /usr/local/share/examples/openvpn/sample-config-files/server.conf
/usr/local/etc/openvpn/geekandnix.conf
vim /usr/local/etc/openvpn/geekandnix.conf

2. Enter your FreeBSD server IP address to the local option like the following. This is where you bind the OpenVPN service.

local 192.168.5.80

3. Here, you must provide the file name CA certificate ca.crt, OpenVPN server public key server/geekandnix.crt, OpenVPN server private key server/geekandnix.key, and the DHPARAM certificate dh.pem.

ca ca.crt
cert server/geekandnix.crt
key server/geekandnix.key # This file should be kept secret
dh dh.pem

4. Now, change the default network topology for clients to subnet. Then, disable the DCO (Data Channel Offload) function in your OpenVPN configuration.

topology subnet
disable-dco

5. Configure the IP address for VPN clients in the following line. In this case, I will leave the configuration default, and VPN clients should get the local IP address 10.8.0.0/24.

server 10.8.0.0 255.255.0.0

6. Make the IP address for clients persists and stored in file ipp.txt via the ifconfig-pool-persist option.

ifconfig-pool-persist ipp.txt

7. Enable the following configuration to set up OpenVPN as default gateway for clients. This means all client connections such as web browser and DNS requests, will go through the OpenVPN server.

push "redirect-gateway def1 bypass-dhcp"

8. Uncomment the following options to set up the default name server for clients. In this case, I will use Cloudflare public DNS 1.1.1.1 and Google DNS 8.8.8.8.

push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 8.8.8.8"

9. Uncomment the tls-auth option below to enable the HMAC firewall with the ta.key file in your OpenVPN server.

The tls-auth option will protect you from DoS attacks and UDP port flooding. On the OpenVPN server, the tls-auth must be 0, while on the client must be 1.

tls-auth ta.key 0

10. Lastly, replace the cipher option with the auth SHA256 option below. This will be used for data channel encryption, and both the OpenVPN server and clients must have the same option.

;cipher
auth SHA256

When done, save the file and exit the editor.

Managing OpenVPN service on FreeBSD

Now that you’ve configured the OpenVPN server, let’s move on to start and manage the OpenVPN service on the FreeBSD server.

Follow these actions to start and manage the OpenVPN service:

1. To start OpenVPN on FreeBSD, run the following command.

service openvpn start

2. Once OpenVPN starts, run the command below to verify the service. If OpenVPN is running, you should get the pid (process ID) of the OpenVPN service.

service openvpn status
Staring and verifying OpenVPN service on FreeBSD
Staring and verifying OpenVPN service on FreeBSD

3. Now, when you need to stop and terminate OpenVPN, run the command below.

service openvpn stop

4. Lastly, run the command below to restart OpenVPN when needed. For example, after editing the OpenVPN configuration geekandnix.conf file.

service openvpn restart

Setting up Port Forwarding on FreeBSD

To ensure VPN traffic from clients is routed by the server, you must enable port-forwarding on your FreeBSD server. This can be done through the /etc/rc.conf file to make the OpenVPN server a gateway, then enable the port-forwarding via kernel parameter /etc/sysctl.conf file.

To enable port-forwarding on FreeBSD, execute these tasks:

1. Firstly, run the command below to make your FreeBSD server the default gateway.

sysrc gateway_enable=YES

2. Then, run the command below to enable port-forwarding in FreeBSD. You will add the configuration net.inet.ip.forwarding=1 to the /etc/sysctl.conf file.

echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf

3. Finally, run the command below to restart the sysctl service. Through this, you will implement your modification to the /etc/sysctl.conf file without reboot.

service sysctl restart
Enable port-forwarding and host gateway on FreeBSD
Enable port-forwarding and host gateway on FreeBSD

Setting up routing OpenVPN via PF (Packet Filter) on FreeBSD

After you’ve enabled port-forwarding, let’s move on to set up routing for the OpenVPN server via the pf (Packet Filter) firewall. Implementing routing will ensure clients can connect to the internet and access resources behind the OpenVPN server.

Complete these actions to set up OpenVPN routing via pf (Packet Filter) firewalld on the FreeBSD server:

1. At first, run the command below to check the default gateway (internet gateway) on your FreeBSD server. You will be using this as a gateway for your VPN clients.

netstat -r -n

In this case, I have an internet gateway on interface em0.

Checking default gateway
Checking default gateway

2. Afterward, edit the default pf configuration /etc/pf.conf using vim.

vim /etc/pf.conf

3. Insert the following configuration to the top of the line. In this example, you will create three macros (variables) on pf:

  • vpnclients as subnet IP for VPN clients 10.8.0.0/24.
  • wanint as the default internet gateway em0.
  • vpnint as default OpenVPN tun interface tun0.
# default vpn network
vpnclients = "10.8.0.0/24"

# WAN interface - internet gateway
wanint = "em0"

# default vpn interface
vpnint = "tun0"

4. Add the openvpn service to the udp_services to allow traffic to the OpenVPN server. By default, OpenVPN running on UDP protocol with port 1194.

udp_services = "{ domain, openvpn }"

5. Under the set skip on lo, add the configuration below to enable NAT on your FreeBSD server.

In this case, you will enable NAT on the wanint interface em0. All connections from vpnclients 10.8.0.0/24 to the wantint interface.

set skip on lo

# enable NAT on em0 - connections from "10.8.0.0/24"
# will be thrown via em0
nat on $wanint from $vpnclients to any -> $wanint

6. Under the block in option, add the new configuration to allow connections to vpnclients subnet.

block in
pass out all keep state
# alternative: pass out quick

# (optional) you can make this stricter
pass in on $vpnint from any to any

When you’re done, save the file and exit.

7. Next, run the command below to reload pf service and take the effects of your changes.

service pf reload

8. Lastly, run the following command to verify NAT and the list of enabled rules in pf.

pfctl -v -s nat
pfctl -sr

You should get the following:

  • NAT on em0 is enabled and all connections from 10.8.0.0/24 will be routed through em0 via IP 10.0.2.15.
  • Traffic to openvpn service are allowed, as well for the tun0 interface.
Checking NAT and rules on pf (Packet Filter)
Checking NAT and rules on pf (Packet Filter)

Creating OpenVPN client configuration

As you’ve now enabled port-forwarding and routing on the OpenVPN server, move on to create a new OpenVPN configuration for the client. This configuration should be distributed to the client, as well as CA and client certificates.

Execute the following actions to create OpenVPN client configuration:

1. First, run the command below to copy the OpenVPN client configuration to /usr/local/etc/openvpn/client/client.ovpn. Then, open it using vim.

cp /usr/local/share/examples/openvpn/sample-config-files/client.conf
/usr/local/etc/openvpn/client/client.ovpn
sudo vim /usr/local/etc/openvpn/client/client.ovpn

2. On the remote option, enter your OpenVPN server IP address followed by the default port 1194.

remote 192.168.5.80 1194

3. Change the path for client certificates. For clients, you need the CA certificate ca.crt, user public key john.crt, and client private key john.key

ca ca.crt
cert john.crt
key john.key

4. Enable the tls-auth option followed by the ta.key file and the value 1. The tls-auth is used to enable an HMAC firewall that prevents DoS and UDP port flooding.

Remember, the tls-auth on the OpenVPN server should have a value of 0, while on the VPN client, the value should be 1.

;tls-auth
tls-auth ta.key 1

5. Now, replace the cipher option with the auth SHA256 option below. This will be used for data channel encryption, and both the OpenVPN server and client should have the same algorithm.

;cipher
auth SHA256

When done, save and exit the file.

6. Lastly, move to the /usr/local/etc/openvpn directory and run the tar command below to compress the client directory to the john.tar.gz file. This will make clients easier to download OpenVPN configuration as a single file.

cd /usr/local/etc/openvpn
tar -czvf john.tar.gz client

Connecting to OpenVPN server from client computers

Now it’s time to verify your OpenVPN server installation by connecting from the client computer.

Here, you will learn how to connect to the OpenVPN server from both Windows and Linux client computers. But before that, you will download OpenVPN certificates and configuration to the local computer.

Downloading OpenVPN client configuration

Before connecting to the OpenVPN server, you must download the client configuration and certificates john.tar.gz file. In this case, I will download the VPN client configuration john.tar.gz with the scp command.

1. On your client computer, run the scp command below to download the file /usr/local/etc/openvpn/john.tar.gz from the OpenVPN server.

scp root@server-ip://usr/local/etc/openvpn/john.tar.gz .

Once downloaded, extract the file john.tar.gz. Your VPN client configuration will be available in the client directory.

Downloading OpenVPN client configuration via scp
Downloading OpenVPN client configuration via scp

Connecting to OpenVPN from a Windows computer

If you’re using a Windows client, navigate through these actions to connect to OpenVPN via the OpenVPN GUI application:

1. Firstly, download the OpenVPN GUI application for Windows and install it. In Windows 10, the default installation folder should be located in the C:\Program Files\OpenVPN folder.

2. Then, copy VPN client certificates and configuration client.ovpn to the C:\Program Files\OpenVPN\config folder.

3. Lastly, open the OpenVPN GUI application and you should see the VPN icon on the taskbar. Right-click on the icon and select Connect.

Here, you can see the Windows client gets local IP address 10.8.0.2 from the OpenVPN server.

Connecting to OpenVPN server via OpenVPN GUI on Windows
Connecting to OpenVPN server via OpenVPN GUI on Windows

Connecting to the OpenVPN server from a Linux computer

For Linux desktop users, execute the following actions to connect to the OpenVPN server via NetworkManager:

1. Run the command below to install the openvpn and network-manager-openvpn-gnome packages.

sudo apt install -y openvpn network-manager-openvpn-gnome

2. Once installation completes, open the NetworkManager and import the client configuration client.ovpn.

3. You can now connect to the OpenVPN server.

Connecting to OpenVPN via terminal

To connect to OpenVPN via the terminal, follow these actions below:

1. To connect to the OpenVPN server from the terminal, run the openvpn command below with sudo/root privileges.

sudo openvpn --config client.conf

2. During the process, you should get the output like the following – Once connected, you should see a message at the bottom initialization complete.

Connecting to OpenVPN server via terminal Linux
Connecting to OpenVPN server via terminal Linux

How do I know if the VPN is working?

To verify if OpenVPN is working or not, you can utilize the tcpdump command to intercept the tun0 interface on your FreeBSD.

Navigate through these steps to ensure that your OpenVPN installation is working:

1. First, run the tcpdump command below on your OpenVPN server to intercept the tun0 interface.

tcpdump -i tun0

2. Next, move to the client computer and run the ping command below to verify your connection. If your OpenVPN installation is successful, you should get the ICMP reply from the target server.

ping 1.1.1.1
ping 10.8.0.1

3. Afterward, go back to the OpenVPN server terminal where tcpdump is running, and you should get the following:

In the following output, you can see the VPN client 10.8.0.2 successfully sent the ping or ICMP request to 1.1.1.1.

tcpdump - checking connections from OpenVPN client to internet
tcpdump – checking connections from OpenVPN client to internet

Also in the following, you can see the VPN client can connect to the VPN’s local IP address 10.8.0.1.

tcpdump - checking connections from OpenVPN client to other client
tcpdump – checking connections from OpenVPN client to other client

Conclusion

Fantastic work! If you have followed so far, you have installed OpenVPN on your FreeBSD 14 server. You’ve configured the OpenVPN server with pf (Packet Filter) firewall and learned how to connect to OpenVPN from a Windows client via OpenVPN GUI, and from a Linux desktop via NetworkManager and Terminal.

From here, you can try to implement client-based rules and policies for OpenVPN users or implement alternative authentication methods using username/password.

System administrator and devops enthusiast, leveraging over 10+ years of Linux expertise to optimize operations. Proficient in FreeBSD, VMWare, KVM, Proxmox, PfSense, Ansible, Docker, and Kubernetes.

Read Also: