Welcome to our yet another guide on how install and configure OpenVPN server FreeBSD 12. We learnt how to install and setup OpenVPN Server on Fedora 29/CentOS 7 on our previous guide.
Install and Configure OpenVPN Server FreeBSD 12
To kick off with, you need to update your FreeBSD 12 package repository.
pkg update
Install OpenVPN and Easy-RSA packages
pkg install openvpn easy-rsa
Create a directory to store the server configuration files, the CA, server keys and certificate files.
mkdir -p /usr/local/etc/openvpn/easy-rsa
mkdir /usr/local/etc/openvpn/server
Copy the sample OpenVPN and Easy-RSA sample configuration files to the respective configuration directories created above.
cp /usr/local/share/examples/openvpn/sample-config-files/server.conf /usr/local/etc/openvpn/server/
cp -r /usr/local/share/easy-rsa/* /usr/local/etc/openvpn/easy-rsa/
Generate the Local CA, Keys and Certificate files with EasyRSA
The certificate variables are set in the /usr/local/etc/openvpn/easy-rsa/vars
file. In order to ease the generation of the certificate, edit this file, uncomment and adjust the certificate values as follows;
vim /usr/local/etc/openvpn/easy-rsa/vars
set_var EASYRSA_REQ_COUNTRY "KE" set_var EASYRSA_REQ_PROVINCE "Nairobi" set_var EASYRSA_REQ_CITY "Nairobi" set_var EASYRSA_REQ_ORG "Kifarunix" set_var EASYRSA_REQ_EMAIL "[email protected]" set_var EASYRSA_REQ_OU "Infrastructure" set_var EASYRSA_KEY_SIZE 2048 set_var EASYRSA_CA_EXPIRE 3650 set_var EASYRSA_CERT_EXPIRE 3650
Easy-RSA ships with certificate generation script called easyrsa.real
. To generare the certificate files, navigate to /usr/local/etc/openvpn/easy-rsa/
directory and proceed as follows;
Initialize the PKI
cd /usr/local/etc/openvpn/easy-rsa
sh ./easyrsa.real init-pki Note: using Easy-RSA configuration from: ./vars init-pki complete; you may now create a CA or requests. Your newly created PKI dir is: /usr/local/etc/openvpn/easy-rsa/pki
Build the CA certificate by running the command below. Set the CN and encryption password when prompted.
sh ./easyrsa.real build-ca
Generate a key and certificate file for the server and client.
sh ./easyrsa.real build-server-full server nopass
sh ./easyrsa.real build-client-full client nopass
Generate Diffie-Hellman key file that can be used during the TLS handshake with connecting clients.
sh ./easyrsa.real gen-dh
In case you need to invalidate a previously signed certificate, generate a revocation certificate.
sh ./easyrsa.real gen-crl
Generate TLS/SSL pre-shared authentication key
openvpn --genkey --secret /usr/local/etc/openvpn/easy-rsa/pki/ta.key
Copy all the server keys and certificates from /usr/local/etc/openvpn/easy-rsa/pki/
to configuration directory created above.
cp -r /usr/local/etc/openvpn/easy-rsa/pki/{ca.crt,dh.pem,ta.key,issued,private} /usr/local/etc/openvpn/server/
Configure OpenVPN Server
Edit the server configuration file such that it looks the below without comments;
vim /usr/local/etc/openvpn/server/server.conf
port 1194 proto udp dev tun ca /usr/local/etc/openvpn/server/ca.crt cert /usr/local/etc/openvpn/server/issued/server.crt key /usr/local/etc/openvpn/server/private/server.key dh /usr/local/etc/openvpn/server/dh.pem topology subnet server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push "redirect-gateway def1 bypass-dhcp" push "dhcp-option DNS 208.67.222.222" push "dhcp-option DNS 208.67.220.220" keepalive 10 120 tls-auth ta.key 0 # This file is secret cipher AES-256-CBC comp-lzo user nobody group nobody persist-key persist-tun status /var/log/openvpn/openvpn-status.log log-append /var/log/openvpn/openvpn.log verb 3 explicit-exit-notify 1 auth sha512 remote-cert-tls client
Create the log directory;
mkdir /var/log/openvpn/
Configure Routing
Run the command below to configure IPv4 NAT routing. This enables the ipfw
firewall which is needed for natd
cat << EOF >> /etc/rc.conf firewall_enable="YES" firewall_type="open" gateway_enable="YES" natd_enable="YES" natd_interface="em1" natd_flags="-dynamic -m" EOF
Reboot the server to effect the changes made above.
reboot
Start and set OpenVPN start on boot.
sysrc openvpn_enable=YES sysrc openvpn_configfile="/usr/local/etc/openvpn/server/server.conf"
service openvpn start
Verify that OpenVPN is running and listening on UDP port 1194.
sockstat -4 -l | grep 1194 nobody openvpn 2824 6 udp46 *:1194 *:*
Verify that the interface has been created.
ifconfig ... tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500 options=80000<LINKSTATE> inet6 fe80::a00:27ff:fe06:ec18%tun0 prefixlen 64 tentative scopeid 0x4 inet 10.8.0.1 --> 10.8.0.2 netmask 0xffffff00 groups: tun nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL> Opened by PID 2824
Configure the Client
Copy the CA , TLS/SSL auth key file and the client key and certificate file to the client.
/usr/local/etc/openvpn/server/ca.crt /usr/local/etc/openvpn/server/issued/client.crt /usr/local/etc/openvpn/server/private/client.key /usr/local/etc/openvpn/server/ta.key
Create the client configuration file
cat << EOF > client.ovpn client tls-client pull dev tun proto udp remote 192.168.43.12 1194 resolv-retry infinite nobind dhcp-option DNS 208.67.222.222 user nobody group nogroup persist-key persist-tun key-direction 1 tls-auth ta.key 1 comp-lzo verb 3 ca ca.crt cert client.crt key client.key auth SHA512 remote-cert-tls server EOF
To connect to VPN server from a Linux system, run the command below;
sudo openvpn client.ovpn
Magnificent!! That is all it takes to install and configure OpenVPN server FreeBSD 12. Thank you for reading.
Hello,
thanks for this perfect howto, i found one small mistake, under _Configure OpenVPN Server_ in the line _tls-auth ta.key 0 # This file is secret_ you also should write the full Path 😉
best regards René
Thanks for the feedback Rene.
Good Day Amos
Thanks for your brilliant work.
Will this config work on freebsd 12 inside an iocage jail.
I am moving away from linux and implementing my customer service platform on Freebsd only going forward.
Best Regards
Johan van Huyssteen
Hey Johan. This is sth haven’t tried out. Will try and update as soon as possible.
Wondering if you have a reference using pf instead of ipfw rulesets?
You can check here.
Great guide. Worked first time!!
Wondering about the android openvpn app. It doesn’t accept the script and there is no obvious place to put the certs etc.?
My apologies – worked it out. There are two difference OpenVPN apps. OpenVPN and OpenVPN for android. The latter allows you to import certificates.
Thanks again for your guide. 🙂
Thanks for the feedback Alek.
Update (maybe?) for FreeNAS (/freebsd?) 11.2/11.3 — the issued crt and key from “Generate a key and certificate file for the server and client.” are (now?) named nopass.crt and nopass.key, so those lines of the conf need to be updated. This was my openvpn server hierarchy:
root@openvpn :/usr/local/etc/openvpn/server # tree
.
|– ca.crt
|– dh.pem
|– issued
| `– nopass.crt
|– private
| |– ca.key
| `– nopass.key
|– server.conf
`– ta.key
If running from a freenas jail, MAKE SURE TO enable the “allow_tun” parameter in the Jail’s “Custom Properties” config screen. You may need to restart your freenas server after setting this parameter.
Thanks for the great howto. Do you happen to have something about moinmoin wiki on 12.1?
tls-auth ta.key 0 is missing the full path to the ta.key file, so you have to change the line to tls-auth /usr/local/etc/openvpn/ta.key 0
I installed openvpn 2.5.5 on FreeBSD 12.2-RELEASE-p7 as a server in a data center.
I installed openvpn 2.5.5 on FreeBSD 12.2-RELEASE-p7 as a client in my home.
Differences I noticed between your server install and mine:
YOUR ifconfig: nd6 options=29
MY ifconfig: nd6 options=21
When trying to connect from the client to the server /var/log/openvpn/openvpn.log I see:
2022-01-10 15:04:38 setsockopt(IPV6_V6ONLY=0)
2022-01-10 15:04:38 UDPv6 link local (bound): [AF_INET6][undef]:1194
2022-01-10 15:04:38 UDPv6 link remote: [AF_UNSPEC]
2022-01-10 15:04:38 MULTI: multi_init called, r=256 v=256
2022-01-10 15:04:38 IFCONFIG POOL IPv4: base=10.8.0.2 size=253
2022-01-10 15:04:38 ifconfig_pool_read(), in=’client,10.8.0.2,’
2022-01-10 15:04:38 succeeded -> ifconfig_pool_set(hand=0)
2022-01-10 15:04:38 IFCONFIG POOL LIST
2022-01-10 15:04:38 client,10.8.0.2,
2022-01-10 15:04:38 Initialization Sequence Completed
2022-01-10 15:05:28 Authenticate/Decrypt packet error: packet HMAC authentication failed
2022-01-10 15:05:28 TLS Error: incoming packet authentication failed from [AF_INET6]::ffff:162.xxx.xx.xx:34388
2022-01-10 15:05:31 Authenticate/Decrypt packet error: packet HMAC authentication failed
2022-01-10 15:05:31 TLS Error: incoming packet authentication failed from [AF_INET6]::ffff:162.xxx.xx.xx:34388
I have tried adding “auth-user-pass” to client.ovpn and I am prompted for a username and password but I just get the same in the logfile.:
2022-01-10 15:08:55 Authenticate/Decrypt packet error: packet HMAC authentication failed
2022-01-10 15:08:55 TLS Error: incoming packet authentication failed from [AF_INET6]::ffff:162.xxxxxxxxxx:40184
2022-01-10 15:08:58 Authenticate/Decrypt packet error: packet HMAC authentication failed
2022-01-10 15:08:58 TLS Error: incoming packet authentication failed from [AF_INET6]::ffff:162.xxxxxxxxxx:40184
2022-01-10 15:09:01 Authenticate/Decrypt packet error: packet HMAC authentication failed
2022-01-10 15:09:01 TLS Error: incoming packet authentication failed from [AF_INET6]::ffff:162.xxxxxxxxxx:40184
…
Any help would be appreciated.
Any chance you have the HMAC key, ta.key, defined on the client and not defined on the server?
Thanks for the reply.
On the server in server.conf:
tls-auth /usr/local/etc/openvpn/server/ta.key 0
On the client in client.ovpn:
tls-auth ta.key 1
ta.key files on both systems are identical (verified using sdiff)
FYI – I am running as root on both systems.
Not sure why but today I am getting different messages in the server log:
2022-01-15 19:21:37 162.218.238.8:12702 Outgoing Control Channel Authentication: Using 512 bit message hash ‘SHA512’ for HMAC authentication
2022-01-15 19:21:37 162.218.238.8:12702 Incoming Control Channel Authentication: Using 512 bit message hash ‘SHA512’ for HMAC authentication
2022-01-15 19:21:37 162.218.238.8:12702 TLS: Initial packet from [AF_INET6]::ffff:162.218.238.8:12702, sid=e23836f0 6901b957
2022-01-15 19:21:37 162.218.238.8:12702 VERIFY OK: depth=0, CN=client
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_VER=2.5.5
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_PLAT=freebsd
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_PROTO=6
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_NCP=2
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_CIPHERS=AES-256-GCM:AES-128-GCM
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_LZ4=1
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_LZ4v2=1
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_LZO=1
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_COMP_STUB=1
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_COMP_STUBv2=1
2022-01-15 19:21:37 162.218.238.8:12702 peer info: IV_TCPNL=1
2022-01-15 19:21:37 162.218.238.8:12702 WARNING: ‘link-mtu’ is used inconsistently, local=’link-mtu 1602′, remote=’link-mtu 1586′
2022-01-15 19:21:37 162.218.238.8:12702 WARNING: ‘keysize’ is used inconsistently, local=’keysize 256′, remote=’keysize 128′
2022-01-15 19:21:37 162.218.238.8:12702 Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, peer certificate: 2048 bit RSA, signature: RSA-SHA256
2022-01-15 19:21:37 162.218.238.8:12702 [client] Peer Connection Initiated with [AF_INET6]::ffff:162.218.238.8:12702
2022-01-15 19:21:37 MULTI: new connection by client ‘client’ will cause previous active sessions by this client to be dropped. Remember to use the –duplicate-cn option if you want multiple clients using the same certificate or username to concurrently connect.
2022-01-15 19:21:37 MULTI_sva: pool returned IPv4=10.8.0.2, IPv6=(Not enabled)
2022-01-15 19:21:37 MULTI: Learn: 10.8.0.2 -> client/162.218.238.8:12702
2022-01-15 19:21:37 MULTI: primary virtual IP for client/162.218.238.8:12702: 10.8.0.2
2022-01-15 19:21:37 Data Channel: using negotiated cipher ‘AES-256-GCM’
2022-01-15 19:21:37 Outgoing Data Channel: Cipher ‘AES-256-GCM’ initialized with 256 bit key
2022-01-15 19:21:37 Incoming Data Channel: Cipher ‘AES-256-GCM’ initialized with 256 bit key
2022-01-15 19:21:37 SENT CONTROL [client]: ‘PUSH_REPLY,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 208.67.222.222,dhcp-option DNS 208.67.220.220,route-gateway 10.8.0.1,topology subnet,ping 10,ping-restart 120,ifconfig 10.8.0.2 255.255.255.0,peer-id 1,cipher AES-256-GCM’ (status=1)
From another shell window on the client pinging any site works until the command: openvpn client.ovpn (as root)
2022-01-15 19:25:28 WARNING: Compression for receiving enabled. Compression has been used in the past to break encryption. Sent packets are not compressed unless “allow-compression yes” is also set.
2022-01-15 19:25:28 –cipher is not set. Previous OpenVPN version defaulted to BF-CBC as fallback when cipher negotiation failed in this case. If you need this fallback please add ‘–data-ciphers-fallback BF-CBC’ to your configuration and/or add BF-CBC to –data-ciphers.
2022-01-15 19:25:28 WARNING: file ‘client.key’ is group or others accessible
2022-01-15 19:25:28 OpenVPN 2.5.5 amd64-portbld-freebsd12.2 [SSL (OpenSSL)] [LZO] [LZ4] [PKCS11] [MH/RECVDA] [AEAD] built on Dec 18 2021
2022-01-15 19:25:28 library versions: OpenSSL 1.1.1h-freebsd 24 Aug 2021, LZO 2.10
2022-01-15 19:25:28 Outgoing Control Channel Authentication: Using 512 bit message hash ‘SHA512’ for HMAC authentication
2022-01-15 19:25:28 Incoming Control Channel Authentication: Using 512 bit message hash ‘SHA512’ for HMAC authentication
2022-01-15 19:25:28 TCP/UDP: Preserving recently used remote address: [AF_INET]64.27.7.215:1194
2022-01-15 19:25:28 Socket Buffers: R=[42080->42080] S=[9216->9216]
2022-01-15 19:25:28 UDP link local: (not bound)
2022-01-15 19:25:28 UDP link remote: [AF_INET]64.27.7.215:1194
2022-01-15 19:25:28 NOTE: UID/GID downgrade will be delayed because of –client, –pull, or –up-delay
2022-01-15 19:25:28 TLS: Initial packet from [AF_INET]64.27.7.215:1194, sid=b83704fe 91cc5386
2022-01-15 19:25:28 VERIFY KU OK
2022-01-15 19:25:28 Validating certificate extended key usage
2022-01-15 19:25:28 ++ Certificate has EKU (str) TLS Web Server Authentication, expects TLS Web Server Authentication
2022-01-15 19:25:28 VERIFY EKU OK
2022-01-15 19:25:28 VERIFY OK: depth=0, CN=server
2022-01-15 19:25:28 WARNING: ‘link-mtu’ is used inconsistently, local=’link-mtu 1586′, remote=’link-mtu 1602′
2022-01-15 19:25:28 WARNING: ‘keysize’ is used inconsistently, local=’keysize 128′, remote=’keysize 256′
2022-01-15 19:25:28 Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, peer certificate: 2048 bit RSA, signature: RSA-SHA256
2022-01-15 19:25:28 [server] Peer Connection Initiated with [AF_INET]64.27.7.215:1194
2022-01-15 19:25:28 PUSH: Received control message: ‘PUSH_REPLY,redirect-gateway def1 bypass-dhcp,dhcp-option DNS 208.67.222.222,dhcp-option DNS 208.67.220.220,route-gateway 10.8.0.1,topology subnet,ping 10,ping-restart 120,ifconfig 10.8.0.2 255.255.255.0,peer-id 0,cipher AES-256-GCM’
2022-01-15 19:25:28 OPTIONS IMPORT: timers and/or timeouts modified
2022-01-15 19:25:28 OPTIONS IMPORT: –ifconfig/up options modified
2022-01-15 19:25:28 OPTIONS IMPORT: route options modified
2022-01-15 19:25:28 OPTIONS IMPORT: route-related options modified
2022-01-15 19:25:28 OPTIONS IMPORT: –ip-win32 and/or –dhcp-option options modified
2022-01-15 19:25:28 OPTIONS IMPORT: peer-id set
2022-01-15 19:25:28 OPTIONS IMPORT: adjusting link_mtu to 1625
2022-01-15 19:25:28 OPTIONS IMPORT: data channel crypto options modified
2022-01-15 19:25:28 Data Channel: using negotiated cipher ‘AES-256-GCM’
2022-01-15 19:25:28 Outgoing Data Channel: Cipher ‘AES-256-GCM’ initialized with 256 bit key
2022-01-15 19:25:28 Incoming Data Channel: Cipher ‘AES-256-GCM’ initialized with 256 bit key
2022-01-15 19:25:28 ROUTE_GATEWAY 192.168.2.1/255.255.0.0 IFACE=igb0 HWADDR=ac:1f:6b:02:d0:06
2022-01-15 19:25:28 TUN/TAP device tun0 exists previously, keep at program end
2022-01-15 19:25:28 TUN/TAP device /dev/tun0 opened
2022-01-15 19:25:28 /sbin/ifconfig tun0 10.8.0.2 10.8.0.1 mtu 1500 netmask 255.255.255.0 up
2022-01-15 19:25:28 /sbin/route add -net 10.8.0.0 10.8.0.1 255.255.255.0
add net 10.8.0.0: gateway 10.8.0.1
2022-01-15 19:25:28 /sbin/route add -net 64.27.7.215 192.168.2.1 255.255.255.255
add net 64.27.7.215: gateway 192.168.2.1 fib 0: route already in table
2022-01-15 19:25:28 ERROR: FreeBSD route add command failed: external program exited with error status: 1
2022-01-15 19:25:28 /sbin/route add -net 0.0.0.0 10.8.0.1 128.0.0.0
add net 0.0.0.0: gateway 10.8.0.1
2022-01-15 19:25:28 /sbin/route add -net 128.0.0.0 10.8.0.1 128.0.0.0
add net 128.0.0.0: gateway 10.8.0.1
2022-01-15 19:25:28 GID set to wheel
2022-01-15 19:25:28 UID set to op
2022-01-15 19:25:28 WARNING: this configuration may cache passwords in memory — use the auth-nocache option to prevent this
2022-01-15 19:25:28 Initialization Sequence Completed
(client seems to connect to server but pinging other shell windows stops until I CTRL-C from the client)
HI,
I followed the instructions however ‘sh ./easyrsa.real init-pki’ is not working. I get a sh: cannot open ./easyrsa.real: no such file or directory.
my ‘/usr/local/etc/openvpn/easy-rsa’ has the copied directories and I renamed vars.example to vars
/usr/local/etc/openvpn/easy-rsa#ls -lah
drwxr-xr-x 3 root wheel 512B .
drwxr-xr-x 4 root wheel 512B ..
-rw-r–r– 1 root wheel 4.9K openssl-easyrsa.cnf
-rw-r–r– 1 root wheel 4.9K openssl-easyrsa.cnf.example
-rw-r–r– 1 root wheel 9.2K vars
drwxr-xr-x 2 root wheel 512B x509-types
/usr/local/etc/openvpn/easy-rsa# sh ./easyrsa.real init-pki
sh: cannot open ./easyrsa.real: no such file or directory.
Great article. Thank you for sharing. Life became easier 🙂