【TrueNAS】OpenVPN Setup

Posted by 西维蜀黍 on 2021-05-02, Last Modified on 2021-10-17

Approach 1 - via UI

Config CA, Server Certificate and Client Certificate

Certificate for the Server (OpenVPN_Server) and the Clients (OpenVPN_SW)

Setup OpenVPN Server

If you finish your setup, buy not able to run the OpenVPN Server with OpenVPN Server service failed to start.:

SSH to your TrueNAS server, you would see your setup just now located in /usr/local/etc/openvpn/server/openvpn_server.conf:

cat openvpn_server.conf
proto udp
port 1194
dev tun
#dev-type tun -FIXME: This does not work, it is an openvpn issue in FreeBSD
ca /etc/certificates/CA/OpenVPN_CA.crt
cert /etc/certificates/OpenVPN_Server.crt
key /etc/certificates/OpenVPN_Server.key
dh /data/dhparam.pem
crl-verify /etc/certificates/CA/OpenVPN_CA.crl
server 10.20.0.0 255.255.255.0
user nobody
group nobody
status /var/log/openvpn/openvpn-status.log
log-append  /var/log/openvpn/openvpn.log
verb 3
persist-tun
persist-key
remote-cert-tls client
topology subnet
cipher AES-256-CBC
auth SHA1
<tls-crypt>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
272ed409ccbc6d35435f866fd46428ec
05a83ea764985d699406ad12837d6827
6cdf04aaf17d234a9e61379a3287b6a2
9cc7ad8fd1d409a29c549ac2d8e35ef6
9d572384fce2717b70c7045d3ccda63e
d98f448880d13dc5edcc9c1104d69904
c768d133b99de0b7bc10981745e5647a
b46e9b21443e77924bc8c87736d18c50
726825856fb671e6170b084239815de7
d3ffbd66de1b23ba718b7afffdbd79c7
16a725fc052553636070ed4684684489
c213feddcdda9ec14168259f3df210bb
3ec1c416df5c8ed9f31eb607515f2988
6acc145ba68176f82370449a3ba87245
cabc050b6b191abfd58b5c9e08e4a1ec
7895d72de7c63e01eb52c674acae3118
-----END OpenVPN Static key V1-----
</tls-crypt>

Check the log:

$ cat /var/log/openvpn/openvpn.log
Sun May  2 23:40:33 2021 TUN/TAP device /dev/tun0 opened
Sun May  2 23:40:33 2021 /sbin/ifconfig tun0 10.20.0.1 10.20.0.2 mtu 1500 netmask 255.255.255.0 up
ifconfig: interface tun0 does not exist
Sun May  2 23:40:33 2021 FreeBSD ifconfig failed: external program exited with error status: 1
Sun May  2 23:40:33 2021 Exiting due to fatal error

于是我尝试把 Device Type 修改为 TAP,于是就可以正常启动了:

$ cat /var/log/openvpn/openvpn.log
Sun May  2 23:41:34 2021 OpenVPN 2.4.8 amd64-portbld-freebsd12.0 [SSL (OpenSSL)] [LZO] [LZ4] [MH/RECVDA] [AEAD] built on Feb 23 2021
Sun May  2 23:41:34 2021 library versions: OpenSSL 1.1.1h-freebsd  22 Sep 2020, LZO 2.10
Sun May  2 23:41:34 2021 WARNING: --keepalive option is missing from server config
Sun May  2 23:41:34 2021 Diffie-Hellman initialized with 2048 bit key
Sun May  2 23:41:34 2021 Failed to extract curve from certificate (UNDEF), using secp384r1 instead.
Sun May  2 23:41:34 2021 ECDH curve secp384r1 added
Sun May  2 23:41:34 2021 Outgoing Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key
Sun May  2 23:41:34 2021 Outgoing Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication
Sun May  2 23:41:34 2021 Incoming Control Channel Encryption: Cipher 'AES-256-CTR' initialized with 256 bit key
Sun May  2 23:41:34 2021 Incoming Control Channel Encryption: Using 256 bit message hash 'SHA256' for HMAC authentication
Sun May  2 23:41:34 2021 TUN/TAP device /dev/tap1 opened
Sun May  2 23:41:34 2021 /sbin/ifconfig tap1 10.20.0.1 netmask 255.255.255.0 mtu 1500 up
Sun May  2 23:41:34 2021 Could not determine IPv4/IPv6 protocol. Using AF_INET6
Sun May  2 23:41:34 2021 Socket Buffers: R=[42080->42080] S=[9216->9216]
Sun May  2 23:41:34 2021 setsockopt(IPV6_V6ONLY=0)
Sun May  2 23:41:34 2021 UDPv6 link local (bound): [AF_INET6][undef]:1194
Sun May  2 23:41:34 2021 UDPv6 link remote: [AF_UNSPEC]
Sun May  2 23:41:34 2021 GID set to nobody
Sun May  2 23:41:34 2021 UID set to nobody
Sun May  2 23:41:34 2021 MULTI: multi_init called, r=256 v=256
Sun May  2 23:41:34 2021 IFCONFIG POOL: base=10.20.0.2 size=253, ipv6=0
Sun May  2 23:41:34 2021 Initialization Sequence Completed

虽然我也不知道为什么,不过在注释中可以看到以下描述:

#dev-type tap -FIXME: This does not work, it is an openvpn issue in FreeBSD

总结来说,OpenVPN Server 的 config 需要这样设置

persist-tun
dev tap
#dev-type tap -FIXME: This does not work, it is an openvpn issue in FreeBSD

Try to restart it:

$ /usr/local/etc/rc.d/openvpn onestart

Approach 2 - Jail

Relevant data to use later in this tutorial ( use your own, this is just for reference )

  1. Home Network: 192.168.18.0/24 ( LAN where is your FreeNAS * Try to use at home different subnet than common ones to avoid conflicts when connecting from outside)
  2. NAT Network: 10.8.0.0/24 ( virtual LAN between VPN clients and your LAN )
  3. Domain: nas.swsmile.info
  4. VPN Server Port: 1194 UDP.
  5. VPN Outside Access Port: 1194 UDP
  6. Certificate Authority Password: fnGdNeC19K%Q
  7. mmQRXxMR8wD7 Client Certificate Password: 73M4NFw1Z!y8

Create a Jail Instance

Use FreeNAS Web GUI

  • Jails -> Add Jail ( Jail Name: OpenVPN, keep default settings )

SSH to your FreeNAS box

$ jls
JID     IP Address    Hostname      Path
...
4                     OpenVPN       /mnt/Vol1-Z2/jails/OpenVPN
$ sudo jexec 4 sh
Password:

Get everything updated and install necessary apps

$ pkg update; pkg upgrade -y; pkg install -y nano openvpn mpack vim
Edit /etc/rc.conf[.local] to start OpenVPN automatically at system
  startup. See /usr/local/etc/rc.d/openvpn for details.

  Connect to VPN server as a client with this command to include
  the client.up/down scripts in the initialization:
  openvpn-client <spec>.ovpn

OpenVPN Config

Create directories for OpenVPN

$ mkdir /usr/local/etc/openvpn /usr/local/etc/openvpn/keys

Copy necessary files

# openvpn server config example
$ cp /usr/local/share/examples/openvpn/sample-config-files/server.conf /usr/local/etc/openvpn/openvpn.conf
# easy-rsa config template
$ cp -r /usr/local/share/easy-rsa /usr/local/etc/openvpn/easy-rsa

Create CA

Config CA

Easy-RSA

$ cd /usr/local/etc/openvpn/easy-rsa
$ nano vars
set_var EASYRSA_REQ_COUNTRY "US"
set_var EASYRSA_REQ_PROVINCE "California"
set_var EASYRSA_REQ_CITY "San Francisco"
set_var EASYRSA_REQ_ORG "Copyleft Certificate Co"
set_var EASYRSA_REQ_EMAIL "me@mydomain.com"
set_var EASYRSA_REQ_OU "My Organizational Unit"

set_var EASYRSA_KEY_SIZE 2048


# The default crypto mode is rsa; ec can enable elliptic curve support.
# Note that not all software supports ECC, so use care when enabling it.
# Choices for crypto alg are: (each in lower-case)
# * rsa
# * ec
#set_var EASYRSA_ALGO rsa
# Define the named curve, used in ec mode only:
#set_var EASYRSA_CURVE secp384r1
# In how many days should the root CA key expire?
set_var EASYRSA_CA_EXPIRE 3650
# In how many days should certificates expire?
set_var EASYRSA_CERT_EXPIRE 3650

Generate Keys

$ ./easyrsa.real init-pki

Note: using Easy-RSA configuration from: /usr/local/etc/openvpn/easy-rsa/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 Certificate Authority

  • Your CA password: fnGdNeC19K%Q
$ ./easyrsa.real build-ca

Note: using Easy-RSA configuration from: /usr/local/etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1h-freebsd  22 Sep 2020

Enter New CA Key Passphrase:
Re-Enter New CA Key Passphrase:
Generating RSA private key, 2048 bit long modulus (2 primes)
................................................................+++++
..............................+++++
e is 65537 (0x010001)
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Common Name (eg: your user, host, or server name) [Easy-RSA CA]:

CA creation complete and you may now import and sign cert requests.
Your new CA certificate file for publishing is at:
/usr/local/etc/openvpn/easy-rsa/pki/ca.crt

Build Server Certificates

  • Input your CA password: fnGdNeC19K%Q
$  ./easyrsa.real build-server-full openvpn-server nopass

Note: using Easy-RSA configuration from: /usr/local/etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1h-freebsd  22 Sep 2020
Generating a RSA private key
....................................................................................+++++
..+++++
writing new private key to '/usr/local/etc/openvpn/easy-rsa/pki/easy-rsa-56581.TX3ymL/tmp.2DjlTw'
-----
Using configuration from /usr/local/etc/openvpn/easy-rsa/pki/easy-rsa-56581.TX3ymL/tmp.AhFAh8
Enter pass phrase for /usr/local/etc/openvpn/easy-rsa/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'openvpn-server'
Certificate is to be certified until Apr 30 16:59:44 2031 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

Build Client Certificate

Use unique name for each certificate, use mmQRXxMR8wD7 with 73M4NFw1Z!y8 and authorize with fnGdNeC19K%Q (CA passowrd)

$ ./easyrsa.real build-client-full mmQRXxMR8wD7

Note: using Easy-RSA configuration from: /usr/local/etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1h-freebsd  22 Sep 2020
Generating a RSA private key
......................................+++++
.........+++++
writing new private key to '/usr/local/etc/openvpn/easy-rsa/pki/easy-rsa-56711.DT6wrg/tmp.1mko66'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
Using configuration from /usr/local/etc/openvpn/easy-rsa/pki/easy-rsa-56711.DT6wrg/tmp.k8H9rL
Enter pass phrase for /usr/local/etc/openvpn/easy-rsa/pki/private/ca.key:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'mmQRXxMR8wD7'
Certificate is to be certified until Apr 30 17:01:15 2031 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

Generate Diffie Hellman Parameters

$ ./easyrsa.real gen-dh


Note: using Easy-RSA configuration from: /usr/local/etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.1.1h-freebsd  22 Sep 2020
Generating DH parameters, 2048 bit long safe prime, generator 2
This is going to take a long time
..+..................................................+............................................+..............+................................................+..................................................................................................................................................+.................................................................+......+..........................................................................................+..................................................................................................................................................................................................................................................................................................................................................+....................................+............................................................+......+...........................................................................+.....................+..+................................................................+.....................................................+......+.........................................................................................................................................................................................................................................................................................+..............................+............................................................................................................................+......................+................................................+...............................+................................................................................+.....................................+....................................................................................................................................+...............................................................................................................................................................................................................................................................+......................................................................................................................................................................+.............+....................+..........................................................+..........+..............................................................................................................................+.......................+.......................................................................................................+....................................................................................................................+..............................................................................................+..........................................................++*++*++*++*

DH parameters of size 2048 created at /usr/local/etc/openvpn/easy-rsa/pki/dh.pem

Generate the TA key

$ openvpn --genkey --secret ta.key

Copy Keys into /usr/local/etc/openvpn/keys/

$ cp ta.key pki/dh.pem pki/ca.crt pki/issued/openvpn-server.crt pki/private/openvpn-server.key pki/issued/mmQRXxMR8wD7.crt pki/private/mmQRXxMR8wD7.key /usr/local/etc/openvpn/keys/

Config OpenVPN Config File

$ cd /usr/local/etc/openvpn/
$ nano openvpn.conf
# use tap
dev tap
#;dev-node MyTap


# Any X509 key management system can be used.
# OpenVPN can also use a PKCS #12 formatted key file
# (see "pkcs12" directive in man page).
ca /usr/local/etc/openvpn/keys/ca.crt
cert /usr/local/etc/openvpn/keys/openvpn-server.crt
key /usr/local/etc/openvpn/keys/openvpn-server.key # This file should be kept secret
# Diffie hellman parameters.
# Generate your own with:
# openssl dhparam -out dh2048.pem 2048
dh /usr/local/etc/openvpn/keys/dh.pem



# Push routes to the client to allow it
# to reach other private subnets behind
# the server. Remember that these
# private subnets will also need
# to know to route the OpenVPN client
# address pool (10.8.0.0/255.255.255.0)
# back to the OpenVPN server.

# ;push "route 192.168.10.0 255.255.255.0"
push "route 192.168.18.0 255.255.255.0"


# The second parameter should be '0'
# on the server and '1' on the clients.
tls-auth /usr/local/etc/openvpn/keys/ta.key 0 # This file is secret
remote-cert-tls client


# You can uncomment this out on
# non-Windows systems.
user nobody
group nobody

Alternative config

Client Config

$ cp /usr/local/share/examples/openvpn/sample-config-files/client.conf /usr/local/etc/openvpn/mmQRXxMR8wD7.conf
$ nano mmQRXxMR8wD7.conf
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote nas.swsmile.info 1194


# SSL/TLS parms.
# See the server config file for more
# description. It's best to use
# a separate .crt/.key file pair
# for each client. A single ca
# file can be used for all clients.
ca ca.crt
cert mmQRXxMR8wD7.crt
key mmQRXxMR8wD7.key


# Act as Gateway: Uncomment only if you need this
#dhcp-option DNS 192.168.222.1
#redirect-gateway def1

You can include everything in one file (client.ovpn) (useful on mobile and more convenient than keeping all certs appart)

client
client
dev tun
proto udp
remote nas.swsmile.info 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
cipher AES-256-CBC
verb 3
auth-user-pass

<ca>
-----BEGIN CERTIFICATE-----
add cert content here...
-----END CERTIFICATE-----
</ca>

<cert>
-----BEGIN CERTIFICATE-----
add cert content here...
-----END CERTIFICATE-----
</cert>

<key>
-----BEGIN ENCRYPTED PRIVATE KEY-----
add cert content here...
-----END ENCRYPTED PRIVATE KEY-----
</key>

key-direction 1
<tls-auth>
-----BEGIN OpenVPN Static key V1-----
add cert content here...
-----END OpenVPN Static key V1-----
</tls-auth>

# Act as Gateway: Uncomment only if you need this
#dhcp-option DNS 192.168.222.1
#redirect-gateway def1

Misc Config

Server NAT Configuration

Create /usr/local/etc/ipfw.rules and add green text

$ nano /usr/local/etc/ipfw.rules
#!/bin/sh
EPAIR=$(/sbin/ifconfig -l | tr " " "\n" | /usr/bin/grep epair)
ipfw -q -f flush
ipfw -q nat 1 config if ${EPAIR}
ipfw -q add nat 1 all from 10.8.0.0/24 to any out via ${EPAIR}

ipfw -q add nat 1 all from any to any in via ${EPAIR}

TUN=$(/sbin/ifconfig -l | tr " " "\n" | /usr/bin/grep tun)
ifconfig ${TUN} name tap1

Onboot Config

More configuration ( edit /etc/rc.conf and add green text at the end of the file )

$ nano /etc/rc.conf
openvpn_enable="YES"
openvpn_if="tun"
openvpn_configfile="/usr/local/etc/openvpn/openvpn.conf"
openvpn_dir="/usr/local/etc/openvpn/"
cloned_interfaces="tun"
gateway_enable="YES"
firewall_enable="YES"
firewall_script="/usr/local/etc/ipfw.rules"

Logging Config

Setup Logging ( edit /etcsyslog.conf )

$ nano /etc/syslog.conf
!ppp
*.* /var/log/ppp.log
!openvpn
*.* /var/log/openvpn.log
!*

Setup log rotation ( edit /etcnewsyslog.conf )

$ nano /etc/newsyslog.conf
/var/log/weekly.log 640 5 * $W6D0 JN
/var/log/xferlog 600 7 100 * JC
/var/log/openvpn.log 600 30 * @T00 ZC

Validate

Use FreeNAS Web GUI

  • Jails -> Select OpenVPN Jail -> Restart

SSH to your FreeNAS box and make some checks

$ jls
JID  IP Address   Hostname        Path
...
5                 OpenVPN         /mnt/Vol1-Z2/jails/OpenVPN
4 sudo jexec 5 sh
Password:
$ ipfw list
00100 nat 1 ip from 10.8.0.0/24 to any out via epair0b
00200 nat 1 ip from any to any in via epair0b
65535 allow ip from any to any
$ sockstat -4 -l
USER    COMMAND  PID    FD  PROTO  LOCAL ADDRESS  FOREIGN ADDRESS
nobody  openvpn  64842  7   udp46  *:1194         *:*
root    syslogd  64803  7   udp4   *:514          *:*

If openvpn is not running, check logs

$ cat /var/log/openvpn.log 
...
May  3 00:27:21 OpenVPN openvpn[41595]: ROUTE_GATEWAY 192.168.18.1/255.255.255.0 IFACE=epair0b HWADDR=ae:9e:17:9b:c8:80
May  3 00:27:21 OpenVPN openvpn[41595]: Cannot allocate TUN/TAP dev dynamically
May  3 00:27:21 OpenVPN openvpn[41595]: Exiting due to fatal error

$ ifconfig
...
tun0: flags=8010<POINTOPOINT,MULTICAST> metric 0 mtu 1500
	options=80000<LINKSTATE>
	groups: tun
	nd6 options=1<PERFORMNUD>

因此,我们需要把 tun 调整为 tap,

手动启动

$ /usr/local/etc/rc.d/openvpn onestart

# 修改配置文件
$ vim /usr/local/etc/openvpn/openvpn.conf
# 设置显示尽可能多的log
verb 9

Let’s send our OpenVPN client files and test connection from outside

# cd /usr/local/etc/openvpn/
# tar cvf Bibi40k.tar Bibi40k.conf -C keys/ ca.crt Bibi40k.crt Bibi40k.key ta.key
a Bibi40k.conf
a ca.crt
a Bibi40k.crt
a Bibi40k.key
a ta.key
# service sendmail onestart
# mpack -s "Bibi40k OpenVPN files" Bibi40k.tar me@mydomain.com

Reference