Install OpenVPN in FreeNAS 11.1 jail has become much easier than it used to be.
This post explains how to do it my way, inspired by the mentioned posts below. I am writing this for my own use, adding some scripts. So I like to share this with the rest of the world.
I will not guarantee that this is the most secure way. But it gets the job done. You are free to use every info in this blog, but don’t come chasing me if it doesn’t work. 🙂
Before I go further I like to give a big thanks to the following people from the FreeNAS community:
robles – Which tutorial I have used lots of times in FreeNAS 9.x installations
Bibi40k – Which has made a tutorial that are more up to date regarding FreeNAS 11.1
Plus the rest of the community in both FreeNAS and FreeBSD.
Requirements for the installation:
- FreeNAS 11.1
- Root ssh access to the FreeNAS box
- Preferable access to Router to do the portforwarding.
Edits:
- 2018-03-27: Found that “comp-lzo” has been deprecated in latest version of OpenVPN and TunnelBlick for Mac. It has been replaced by “compress”.
Start:
Use FreeNAS WebUI to make a jail.
Go to Storage and create a dataset called “Jails”
Go to Jails –> Configuration and set the newly created dataset as jail root.
Click add Jail and give the Jail a name ex. “OpenVPN”
Before clicking OK, push the Advanced Mode button, and give the Jail a IP number, netmask and default gateway according to your LAN network. Click “OK”.
SSH into your FreeNAS box and get the details of the jail
$ jls JID IP Address Hostname Path 1 OpenVPN /mnt/NaStar/Jails/OpenVPN
$ jexec 1 sh
This takes you into the commandline interface of the Jail.
Start by updating everything in the Jail and install the needed programs. Out of habit I always install tmux.
# pkg update # pkg upgrade -y # pkg install -y nano tmux openvpn zip bash
Create directories for OpenVPN, to respect FreeBSD’s structure we will do everything in /usr/local/*
# mkdir -p /usr/local/etc/openvpn/keys
Copy all the files into your newly created folder structure.
# cp /usr/local/share/examples/openvpn/sample-config-files/server.conf /usr/local/etc/openvpn/openvpn.conf # cp -r /usr/local/share/easy-rsa /usr/local/etc/openvpn/easy-rsa
Lets setup easy-rsa (edit: /usr/local/etc/openvpn/easy-rsa/vars )
# cd /usr/local/etc/openvpn/easy-rsa # nano vars
Change the following lines to what fits your usecase and uncomment the lines to give it effect.
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 the Keys to be used.
# ./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 Certificate Authority
The passphrase will be needed to add new users to the OpenVPN server in the future.
# ./easyrsa.real build-ca Note: using Easy-RSA configuration from: ./vars Generating a 2048 bit RSA private key .......................................+++ ..+++ writing new private key to '/usr/local/etc/openvpn/easy-rsa/pki/private/ca.key.vpfhw9orph' Enter PEM pass phrase:Password1 Verifying - Enter PEM pass phrase:CAPassword ----- 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]: OpenVPN FreeNAS 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
# ./easyrsa.real build-server-full openvpn-server nopass Note: using Easy-RSA configuration from: ./vars Generating a 2048 bit RSA private key ...............................................+++ .................................+++ writing new private key to '/usr/local/etc/openvpn/easy-rsa/pki/private/openvpn-server.key.JKfgnZ3Ae8' ----- Using configuration from /usr/local/etc/openvpn/easy-rsa/openssl-1.0.cnf Enter pass phrase for /usr/local/etc/openvpn/easy-rsa/pki/private/ca.key:CAPassword 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 Feb 13 18:22:32 2028 GMT (3650 days) Write out database with 1 new entries Data Base Updated
Generate Diffie Hellman Parameters ( /usr/local/etc/openvpn/easy-rsa/pki/dh.pem )
# ./easyrsa.real gen-dh Note: using Easy-RSA configuration from: ./vars 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 together
# cp pki/dh.pem pki/ca.crt pki/issued/openvpn-server.crt pki/private/openvpn-server.key /usr/local/etc/openvpn/keys/ # cp ta.key /usr/local/etc/openvpn/keys/
Setup OpenVPN Server config file ( edit: /usr/local/etc/openvpn/openvpn.conf )
# cd /usr/local/etc/openvpn/ # nano openvpn.conf
# 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 route to your LAN network, in my case 10.0.10.0
# 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 10.0.10.0 255.255.255.0"
Setup ta.key in the tls section
# 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
Enable compression
# Enable compression on the VPN link and push the # option to the client (v2.4+ only, for earlier # versions see below) compress lz4-v2 push "compress lz4-v2"
# You can uncomment this out on # non-Windows systems. user nobody group nobody
Setup server NAT configuration ( Create /usr/local/etc/ipfw.rules and add teh following text )
#!/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 tun0
Setup rc.conf 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"
Setup Logging ( edit /etc/syslog.conf )
!ppp *.* /var/log/ppp.log !openvpn *.* /var/log/openvpn.log !*
Setup log rotation ( edit /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
Setup the Clients on the server.
This is done with the following BASH script ( /usr/local/etc/openvpn/adduser.sh )
The script adds the user, pack it as a encrypted zipfile and send it to https://transfer.sh/ here it can be downloaded.
#!/usr/local/bin/bash ### Change this before deployment server=<server-IP or Hostname> port=1194 internalDNS=10.0.10.254 ### if [ $# == 0 ]; then echo "Usage: $0 <USER>" exit 127 fi cd /usr/local/etc/openvpn/easy-rsa || exit 0 ./easyrsa.real build-client-full "$1" if [ $? == 1 ] then echo "see error from easyrsa." echo "Aborting..!!!" exit 1 fi clear cp pki/issued/*.crt/usr/local/etc/openvpn/keys/ cp pki/private/*.key /usr/local/etc/openvpn/keys/ mkdir -p /usr/local/etc/openvpn/users/"$1" cp /usr/local/etc/openvpn/keys/"$1".crt /usr/local/etc/openvpn/users/"$1" cp /usr/local/etc/openvpn/keys/"$1".key /usr/local/etc/openvpn/users/"$1" cp /usr/local/etc/openvpn/keys/ca.crt /usr/local/etc/openvpn/users/"$1" cp /usr/local/etc/openvpn/keys/ta.key /usr/local/etc/openvpn/users/"$1" echo "client dev tun proto udp remote "$server" "$port" resolv-retry infinite nobind persist-key persist-tun mute-replay-warnings ca ca.crt cert "$1".crt key "$1".key remote-cert-tls server tls-auth ta.key 1 cipher AES-256-CBC verb 3 dhcp-option DNS "$internalDNS" redirect-gateway def1" >>/usr/local/etc/openvpn/users/"$1"/OpenVPN\ "$1".ovpn cd /usr/local/etc/openvpn/users/ || exit 0 clear echo "Provide the password for the zip file:" zip -er "$1".zip "$1" clear echo "Uploading OpenVPN Package to transfer.sh:" transfer=$(curl --upload-file ./"$1".zip https://transfer.sh/"$1".zip) clear echo "" echo "Copy/paste this link in your browser to download full OpenVPN user packages:" echo "$transfer" exit 0
Status Script
Sometimes when you lots of clients using the OpenVPN, its nice to have some kind of status. This can be achieved by looking at the log file in /usr/local/etc/openvpn/openvpn-status.log
This can be a bit confusing for people not used to log files. I have made a small BASH script for this purpose.
#!/usr/local/bin/bash clear log=/usr/local/etc/openvpn/openvpn-status.log cat $log | awk '/OpenVPN CLIENT LIST/,/ROUTING TABLE/' | sed '$d' | sed "s/,/ /g" | sed -n '1p' #echo " " cat $log | awk '/OpenVPN CLIENT LIST/,/ROUTING TABLE/' | sed '$d' | sed "s/,/ /g" | sed -n '2p' echo " " cat $log | awk '/OpenVPN CLIENT LIST/,/ROUTING TABLE/' | sed '$d' | sed "s/,/ /g" | sed -n '3p' echo "------------------------------------------------------------------------------------------------------------------------------------------------" cat $log | awk '/OpenVPN CLIENT LIST/,/ROUTING TABLE/' | sed '$d' | sed "s/,/ /g" | sed -e '1,3d' echo "------------------------------------------------------------------------------------------------------------------------------------------------"
I have never really used a command line interface to install something this complex. The instructions might work well for someone that has command line experience, for me there are too many uncertainties to know what needs to be done. I can copy paste the text into Putty just fine, but it is unclear to me when I need to change something, or if there is pre-work to do.
What do the different colors mean?
Do I need to go to openVPN and create a login? Do I need to download something from openVPN for it to work?
I can see that its a mouth full if you are not comfortable in the command line. I recommend spinning up a virtual machine on your own computer with virtual box and start playing around. If you make a bridged network interface you will be able to connect to your VM when you are ready.
This tutorial is getting a bit old now with the new versions of OpenVPN and EasyRSA, in both applications there have been a lot of deprecated settings and new ways to do stuff in a better way. I will make a new article as soon I have the time to setup a new OpenVPN server.
btw. the colors are a bit confusing, but to present code in a good way in WordPress this is the best option I have found, if any one out there has a better solution I am all ears. 🙂
Thank Dennis. good writeup.
I’m almost there – I think.
With the current versions of the FreeNAS 11.2 and openVPN2.4.7:
for the adduser.sh script it is necessary to install the curl package:
pkg install -y curl
in the adduser.sh script change the following line
cp /usr/local/etc/openvpn/keys/”$1″.crt /usr/local/etc/openvpn/users/”$1″
to
cp /usr/local/etc/openvpn/easy-rsa/pki/issued/”$1″.crt /usr/local/etc/openvpn/users/”$1″
Thanks for the changes, I will try and find the time to go over it all again and make some updates to it. I have recently changed job, so I have been out of the loop for a while. 🙂
I am having an issue creating a jail in freenas 11. I tried using both the new and legacy interfaces and they are generating errors. freenas 11 is giving me The jail dataset was created on a share. error. I followed the instructions about creating a dataset. The new interface gives me an error in selecting the release. the error is Error: Displaying local fetched releases failed. Please help
This write up is a bit old, but the jail creation in FreeNAS is still a breeze. I use it all the time, so i recommend that you go over the initial setup in FreeNAS. Use the FreeNAS documentation, it is supreme.