Install and Configure OpenVPN Server FreeBSD 12

16
11907

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.

Install OpenVPN on pfSense - The Co...
Install OpenVPN on pfSense - The Complete Step-by-Step Guide
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.

16 COMMENTS

  1. 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é

  2. 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

  3. 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.?

  4. 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:

    [email protected] :/usr/local/etc/openvpn/server # tree
    .
    |– ca.crt
    |– dh.pem
    |– issued
    | `– nopass.crt
    |– private
    | |– ca.key
    | `– nopass.key
    |– server.conf
    `– ta.key

  5. 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.

  6. 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

  7. 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.

      • 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)

LEAVE A REPLY

Please enter your comment!
Please enter your name here