Back in July of 2012 I posted a write up on how to get OpenVPN running on FreeNas 8.2. That write up was really just notes to myself and I never really thought it would get much attention. Over the last year, it has seen enough traffic that I thought it deserved a re-write to try and make it easier to follow. So, here goes.
As always, if you find this super useful, I wouldn’t turn down paypal donations.
If you are going to do this on your FreeNAS box, please also check out my guide on getting hacks to FreeNAS to survive system upgrades.
Dynamic DNS
If you don’t have a static ip address, lets start by setting up a Dynamic DNS entry. There are several service providers that offer free dynamicDNS service…currently FreeNas supports: dyndns.org, freedns.afraid.org, zoneedit.com, no-ip.com, easydns.com and 3322.org. So, pick one, set up an account, configure your FreeNas gui to use it in the services panel and then come back.
Port Forwarding on your Router
Next you’ll need to forward UDP port 1194 on your router to your FreeNAS box. You’ll need to do a little google searching if you don’t know how to do that on your specific router. Generally it involves logging into the web interface on the router, going to the advanced section and looking for something that sounds like port forwarding.
OpenVPN
Server Certificates – OpenSSL
You can configure OpenVPN for password authorization, but I really don’t like that method. So I’ll tell you how to set it up with certificate authorization. Easy-RSA is included in FreeNas 9.1 and later. You can find it here: /usr/local/share/easy-rsa . If you don’t want to download my sample files or if you don’t trust me, then you should skip step 2 below and use the Easy-RSA files at /usr/local/share/easy-rsa and then also create your config files from scratch.
So, lets get started.
1. Mount the filesystem so we can make some changes.
su enter your root password mount -uw /
2. Now, download my openvpn.tar into the root of your data drive, so for me /mnt/Files.
cd /mnt/Files wget --no-check-certificate https://www.dropbox.com/s/14h2j1zslozotx8/openvpn.tar tar -xvf openvpn.tar cd openvpn
3. Now we need to create our CA.cert
chmod -R 755 easy-rsa/2.0/* cd easy-rsa/2.0 sh . ./vars ./clean-all ./build-ca
Your output from ./build-ca should look like this. Answer the questions with the appropriate answers.
Generating a 1024 bit RSA private key
...++++++
....................................++++++
writing new private key to
'ca.key'
-----
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.
-----
Country Name (2 letter code) [BG]:
State or Province Name (full name) [Sofia]:
Locality Name (eg, city) [Sofia]:
Organization Name (eg, company) [example.org]:
Organizational Unit Name (eg, section) [ ]:
Common Name (eg, your name or your server's
hostname
) [openvpn.example.org CA]:openvpn.example.org
Name [ ]:daemon
Email Address [
admin@example.org
]:
4. Now, we want to create a server key.
./build-key-server server
Your output from ./build-key-server should look like this. Answer the questions with the appropriate answers.
Generating a 1024 bit RSA private key
.......++++++..........................................++++++writing new private key to 'server.key'
-----
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.
-----
Country Name (2 letter code) [US]:
State or Province Name (full name) [MN]:
Locality Name (eg, city) [Coon Rapids]:
Organization Name (eg, company) [ ]:
Organizational Unit Name (eg, section) [ ]:
Common Name (eg, your name or your server's hostname) [server]:
Name [ ]:
Email Address [me@myhost.mydomain]:
Please enter the following 'extra' attributes to be sent with your certificate request
A challenge password [ ]:
An optional company name [ ]:
Using configuration from /mnt/Files/openvpn/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok The Subject's Distinguished Name is as follows
countryName : PRINTABLE:'US'
stateOrProvinceName : PRINTABLE:'MN'
localityName : PRINTABLE:'Coon Rapids'
organizationName : PRINTABLE:''
commonName : PRINTABLE:'server'
emailAddress : IA5STRING:'me@myhost.mydomain'
Certificate is to be certified until Sep 20 18:43:20 2023 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
5. Now let’s create the Diffie-Hellman parameters:
./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
………………………………………………………………………………+………………………………………………………………………….+…………………………………………………………………………………………++*++*++*
6. Now we might as well generate a client key.
./build-key joe.paetzel
Your output should look like this:
Generating a 1024 bit RSA private key
……………………………..++++++………++++++
writing new private key to ‘joe.paetzel.key’
—–
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.
—–
Country Name (2 letter code) [US]:
State or Province Name (full name) [MN]:
Locality Name (eg, city) [Coon Rapids]:
Organization Name (eg, company) [ ]:
Organizational Unit Name (eg, section) [ ]:
Common Name (eg, your name or your server’s hostname) [joe.paetzel]:
Name [ ]:
Email Address [me@myhost.mydomain]:Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password [ ]:
An optional company name [ ]:
Using configuration from /mnt/Files/openvpn/easy-rsa/2.0/openssl.cnf
Check that the request matches the signature
Signature ok
The Subject’s Distinguished Name is as follows
countryName : PRINTABLE:’US’
stateOrProvinceName : PRINTABLE:’MN’
localityName : PRINTABLE:’Coon Rapids’
organizationName : PRINTABLE:”
commonName : PRINTABLE:’joe.paetzel’
emailAddress : IA5STRING:’me@myhost.mydomain’
Certificate is to be certified until Sep 20 19:03:19 2023 GMT (3650 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
7. Now we can get out of the sh shell and move the keys and certificates into their place.
exit cp -R keys ../../
On my system, the place I want the certs and keys is /mnt/Files/openvpn/keys , I’m using shorthand above to backout two directories and place the keys folder there. So, the long hand version would be:
cp -R /mnt/Files/openvpn/easy-rsa/2.0/keys /mnt/Files/openvpn/
The reason we want the keys and config file on the data drive instead of the OS drive is FreeNas upgrades will wipe out our OpenVPN setup if we have everything installed on the OS drive.
Server Configuration File
1. Next we can create the openvpn.conf config file and edit it for our specific setup. If you didn’t download the openvpn.tar file from me, then you will need to create a openvpn.conf file from scratch. If you did download the openvpn.tar file, I’ve included a couple of Bare Bones sample configs.
cp BareBones_Server.conf.sample openvpn.conf chmod 440 openvpn.conf vi openvpn.conf
Side note, vi has lots of commands, we just need to know a few:
x will delete the character your cursor is over, i will insert, esc will exit insert mode and to save and quit we use :wq
You should get this on your screen:
# Sample OpenVPN 2.0 config file for
# multi-client server.#replace x.x.x.x with freenas ip
local x.x.x.x
port 1194
proto udp
dev tun
topology subnet
#change the paths and filenames below to match what you did
ca /mnt/Files/openvpn/keys/ca.crt
cert /mnt/Files/openvpn/keys/server.crt
key /mnt/Files/openvpn/keys/server.key
dh /mnt/Files/openvpn/keys/dh1024.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist ipp.txt
#change x.x.x.x to match your network ip range
#ie 192.168.0.0 or 10.0.0.0
push “route x.x.x.x 255.255.255.0”
#replace x.x.x.x with freenas ip
route x.x.x.x 255.255.255.0 10.8.0.1
keepalive 10 120
comp-lzo
persist-key
persist-tun
verb 3
We need to make a few changes to match our specific needs.
Change local x.x.x.x to the ip of your FreeNas box:
local 192.168.0.121
Check that your certs and keys match the lines here:
ca /mnt/Files/openvpn/keys/ca.crt
cert /mnt/Files/openvpn/keys/server.crt
key /mnt/Files/openvpn/keys/server.key
dh /mnt/Files/openvpn/keys/dh1024.pem
Change push “route x.x.x.x 255.255.255.0” to match your network setup:
push “route 192.168.0.0 255.255.255.0”
Change route x.x.x.x 255.255.255.0 10.8.0.1 to have the ip of your FreeNas box:
route 192.168.0.121 255.255.255.0 10.8.0.1
hit the ESC key, then type :wq to save and quit out of vi.
2. Now lets add a few things to rc.conf so we can start openvpn.
vi /etc/rc.conf
Add the following lines making sure that the openvpn_configfile is pointing to your config file location:
openvpn_enable=”YES”
openvpn_if=”tun”
openvpn_configfile=”/mnt/Files/openvpn/openvpn.conf”
openvpn_dir=”/mnt/Files/openvpn”
We also need to make these same changes to /conf/base/etc/rc.conf so they survive a restart.
vi /conf/base/etc/rc.conf
Again, add the following:
openvpn_enable=”YES”
openvpn_if=”tun”
openvpn_configfile=”/mnt/Files/openvpn/openvpn.conf”
openvpn_dir=”/mnt/Files/openvpn”
Cross Your Fingers and Fire It Up
1. Now we should be able to start the OpenVPN server.
service openvpn start
You should get something like this:
Starting openvpn.
route: writing to routing socket: File exists
add net 192.168.0.121: gateway 10.8.0.1: route already in table
add net 10.8.0.0: gateway 10.8.0.2
Clean Up
1. Make the filesystem read only again:
mount -ur /
2. Delete openvpn.tar
rm /mnt/Files/openvpn.tar
Set Up Your Client
1. Copy your client key(s), client crt(s) and ca.crt to the client computer you will be using to connect to the server. There are a bunch of ways you could do this, I just copied them to a shared folder on my FreeNas box and moved them from there onto my client computer.
2. Create a client config file. I’ve included a sample Bare Bones config for you to modify in the openvpn.tar file. It will look something like this:
# Sample client-side OpenVPN 2.0 config file #
client
dev tun
proto udp
#change remote to your static ip
#or domain name for your freenas server
remote something.dyndns.org 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca /Path/to/Some-ca.crt
cert /Path/to/laptop.crt
key /Path/to/laptop.key
ns-cert-type server
comp-lzo
You need to change the line remote something.dyndns.org 1194 to either your public static ip of your router or a dynamic or static domain name. You also need to change the ca, cert and key lines to the path of where those files will live on the client.
On OS X using Tunnelblick as the client application those paths will look something like this:
ca /Users/joe/Library/Application\ Support/Tunnelblick/Configurations/ca.crt
cert /Users/joe/Library/Application\ Support/Tunnelblick/Configurations/joe.paetzel.crt
key /Users/joe/Library/Application\ Support/Tunnelblick/Configurations/joe.paetzel.key
Wrapping It Up
With all of that, you should be good to go. I’ve tried to be as clear and accurate as possible. I hope you all enjoy the rewrite.
Also, check out my writeup on setting up a firewall on FreeNAS. It will help you get routing working properly so you can reach all the devices on your LAN over the VPN. https://joepaetzel.com/2014/03/04/secure-freenas-9-2-1-2-with-a-firewall/
Also, if you want to add an additional layer of security, check out my guide on getting OpenVPN working with Google Authenticator.
As always, donations are welcome via paypal.