This post is not about configuring FreeNAS to connect to a VPN, but about running a VPN server inside FreeNAS, so you will be able to access all your jails and every host on your local (home) network from the outside, using the secure VPN tunnel.
Using a VPN connection is like sending a mail envelope inside another one: the external envelope is addressed to your VPN endpoint (the server), and only the server can extract the internal envelope and process it (i.e., forward it to the specified address) as if it originated locally (thus you can access private addresses on your local network). Replies will be sent back on the tunnel by securely re-encapsulating them in an external envelope.
So, after you are connected to your VPN, you can for example
(or whatever addresses you are using) through the Internet.
Prepare a new Jail
The VPN server (OpenVPN) will run inside a Jail. I think that this is the cleanest method to create this setup and, in case of problems, you will not mess up your FreeNAS installation. Using VMs (Virtual Machines – similar in concept to jails/containers/zones or whatever) is also a very common approach in administering servers and it is a fundamental block in the IaaS model of cloud computing.
In the web interface of FreeNAS, go to “Jails” and press the “Add Jail” button.
Give it a name, select “standard” as type, assign an IP address (let’s assume 192.168.0.4) and a netmask (assume /24), then be sure that the “autostart” and “VIMAGE” boxes are checked and create the jail (leave everything else as default).
Now that you have the jail, SSH into your FreeNAS box (not to the jail you just created) and do
you should see the new jail in the output with its JID (first column). Take note of the JID and do (replace <JID> with the ID of the jail):
# jexec <JID> csh
Install the OpenVPN package with
# pkg install openvpn
Move at the root of the jail and create an openvpn folder where to work on the configuration
# cd / # mkdir openvpn # cd openvpn
Copy the easy_rsa folder from the OpenVPN installation to get the scripts to generate the keys
# cp -r /usr/local/share/easy-rsa /openvpn/ # cd easy-rsa
Edit the vars file so you avoid replying to the same configuration questions many times
# vi vars
(if you don’t feel comfortable with vi, install something else, e.g., nano with “pkg install nano”)
Go to the end of the file and assign values to these variables (the values are not really important in a home setup!)
KEY_COUNTRY= KEY_PROVINCE= KEY_CITY= KEY_ORG= KEY_EMAIL= KEY_CN= KEY_NAME= KEY_OU=
Now switch to the “sh” shell and generate the keys (note that since “source” is not available, we use the “.” operator to import the vars file into the current shell, do not omit the “.” (dot) at the beginning of the second command of this list!)
When generating the keys, consider using a passphrase, to sign the certificate and, at the end, answer yes to the “commit” question.
# sh # . vars # ./clean-all # ./build-ca # ./build-key-server <server-name> # ./build-dh # openvpn --genkey --secret keys/ta.key
And for each client that will access the vpn
# ./build-key <client-name>
Copy the key folder somewhere else to secure it from ./clean-all commands
# cp -r keys .. # cd ..
Now we need to configure the OpenVPN server by creating a configuration file. You can copy from this sample and create a local file “server.conf”.
# vi server.conf # <paste the sample in this file, then save and close>
Read the comments of the variables and change what you need. Approximately these should be the lines that need to be configured, the rest can remain as is, unless you have special needs
# put the IP address of your jail here, we assumed 192.168.0.4 # for this example local 192.168.0.4 # paths of the server certificates and keys ca /openvpn/keys/ca.crt cert /openvpn/keys/<server-name>.crt key /openvpn/keys/<server-name>.key # Diffie Helman key dh /openvpn/keys/dh1024.pem # Push the route to your local subnet, change address/mask # as needed push "route 192.168.0.0 255.255.255.0" # Use this if you want to route all clients traffic # through the VPN (we will use ipfw rules later to # forward this to the correct gateway) push "redirect-gateway" # Push a dns server address push "dhcp-option DNS 220.127.116.11" # tls-auth key tls-auth /openvpn/keys/ta.key 0
As James (see comments) suggested, if you don’t have the /usr/local/etc/openvpn/ folder or you prefer to consistently keep everything under /openvpn, also specify the path to the log files with these lines:
status /openvpn/openvpn-status.log ifconfig-pool-persist /openvpn/ipp.txt
Another useful suggestion from James is to set the verbosity level to 0 (default is 3), unless you have specific debug needs:
Now we need to configure the network to make sure that packets are routed correctly. We can do this by creating firewall rules.
First, identify the name of the interface on the local network, i.e., the one which has the 192.168.0.4 address (or the one you used for this setup):
In my case this was “epair0b”.
Then, create a file for the firewall rules
# vi /usr/local/etc/ipfw.rules
with this content (replace “epair0b” with what you found)
ipfw -q -f flush ipfw -q nat 1 config if epair0b ipfw -q add nat 1 all from 10.8.0.0/24 to any out via epair0b ipfw -q add nat 1 all from any to any in via epair0b
Put everything together
The last step is to tell openvpn and ipfw which configuration files to use and enable the services at boot.
Edit the file /etc/rc.conf and append the following lines
openvpn_enable="YES" openvpn_if="tun" openvpn_configfile="/openvpn/server.conf" cloned_interfaces="tun" gateway_enable="YES" firewall_enable="YES" firewall_script="/usr/local/etc/ipfw.rules"
Reboot the jail from the web interface to have everything running (check that the network interface name that you wrote in the ipfw.rules file didn’t change name, otherwise update the file with the new name and reboot again).
If you want to access the VPN from the Internet and you have a home router with NAT (this is highly probable), you will need to forward the VPN port so that those packets will be sent to the jail running the VPN server.
The default port that OpenVPN uses is 1194.
Go to the settings of your home router and forward port 1194 to 192.168.0.4 (or your actual address that you used for the jail).
If you don’t have a fixed public IP address, you should also consider subscribing to a free dynamic DNS service.
Configuring a client
The last step is that of configuring a client and testing the connection to the VPN.
Copy to your computer the following files (use scp or rsync or a usb stick, …)
ca.crt ta.key <client-name>.crt <client-name>.key
Create a vpn-client.conf file with the client sample configuration and change what is needed by reading the comments. If you don’t have any special need, these should be the lines that need editing
# Your server public IP and port. This may be a DDNS or a normal # IP address in case you have a fixed one from your ISP remote my-server.ddns.net 1194 # Wireless networks often produce a lot # of duplicate packets. Set this flag # to silence duplicate packet warnings. mute-replay-warnings # Adjust the paths as you need, but it's better to keep them # absolute ca /home/vince/.openvpn/ca.crt cert /home/vince/.openvpn/client.crt key /home/vince/.openvpn/client.key # We can use this option to increase our security ns-cert-type server # If a tls-auth key is used on the server # then every client must also have the key. tls-auth /home/vince/.openvpn/ta.key 1
Now you can try connecting to the VPN using the tools that are available to your OS. On Ubuntu, you will need to install the “network-manager-openvpn” package and then you will be able to configure a VPN from the network manager GUI.
If, even from the local network, the client will be able to establish the connection to the VPN server, then, unless there are other networking issues (e.g., port forwarding on the home router), everything should work even from the outside.
When facing the need of running a VPN for my FreeNAS box, I have found some very useful resources, consisting mainly on a blog post by Joe Paetzel and a post on the FreeNAS forum by user qwertymodo:
I have put this information together, made some slight changes and tested everything as most carefully as possible to be sure that this setup worked (e.g., Joe was configuring the VPN on the FreeNAS box directly, and not in a jail).
The credits for this post go to the authors of these two great contributions!