qwertymodo
Contributor
- Joined
- Apr 7, 2014
- Messages
- 144
After much frustration with the available documentation, I've finally managed to get OpenVPN installed and configured inside a VIMAGE portjail that allows me to access my FreeNAS box over the internet, so I figured I'd document the process here. A lot of the issues I had were due to slight differences in the systems that the guides were written for, resulting in slightly different paths or other minor differences that I banged my head against the wall over for far too long, so to be clear, this guide was written for a portjail on FreeNAS 9.2.1.5. Things may change, so if you're on a different version, I can't guarantee you won't experience exactly the same kinds of issues as I had. Note, this is NOT a guide for setting up the FreeNAS box as a client, i.e. for VPN tunneling of bittorrent traffic or the like. This is for tunneling INTO your FN box remotely. For the sake of this guide, I'm using the 192.168.1.0/24 subnet as my actual home subnet (i.e. the FN box and all of its jails exist on that subnet), and I'm using the 172.16.1.0/24 subnet as the VPN subnet (i.e. VPN clients will be assigned addresses on that subnet). Any references to these subnets should be altered to match your network. Also, I just got it working last night, and I'm writing this guide having retraced my steps with a new jail this morning, but if I'm missing anything, let me know.
First things first, open the Jails tab in the Web GUI and click Add Jails. Give it a name, select portjail as the type, select Autostart and VIMAGE, and uncheck NAT and vanilla. The rest of the defaults should be sufficient.
If you want to be able to SSH into your jail instead of using the Web GUI's shell icon, follow the instructions here
Now, we install openvpn from the ports collection:
The defaults should be fine, just be sure that easy-rsa is selected for installation.
Now we can begin setting up our certificate authority. Basically every guide I've seen suggests copying the easy-rsa scripts outside of their default location so they don't get wiped out by an update. I chose /usr/local/etc/openvpn (this is also where I store my server config).
Now, we need to edit the vars file. Open it in your editor of choice, and edit the following lines
You can also change the KEY_SIZE to 2048 or 4096, if you're paranoid. This will cause the initial DH key generation to take much longer.
Now, we can set up our CA (these scripts don't like csh, so remain in sh for the rest of this guide, also note that the second command has two dots with a space between them)
Next is the server key
When it asks if you want to sign the certificate, say yes. Do the same when it asks if you want to commit the changes. A challenge password is optional, but recommended.
Now for the client keys. Run this once for each client.
Finally, we generate our Diffie-Hellman key. This will take awhile, especially if you increased the KEY_SIZE variable.
It's also a good idea to create an "HMAC firewall" to help block DoS attacks and UDP port flooding
Now, let's copy our keys out of the default directory so that they won't accidentally get deleted if you run ./clean-all
Next, you'll need to create your OpenVPN server config file. I named mine server.conf and placed it in /usr/local/etc/openvpn. You can find example config files here. Note that we're creating a routed connection, not a bridge, so ignore any lines dealing with bridged connections or the tap interface.
Now in order to allow traffic on the VPN subnet to access your main subnet, you'll either need a static route on your router or else you'll need to configure NAT using IPFW in your jail. I opted for the latter. First of all, you'll need to find the name of the jail's network interface. Since this is a VIMAGE jail, you should have an interface named epairNb, where N is dependent on the number of VIMAGE jails you currently have. In order to determine the actual name, just run
Create the file /usr/local/etc/ipfw.rules and add the following lines (modify them for your network and interface name)
Save ipfw.rules and open /etc/rc.conf.local and add these lines
Now, in order to apply all of your changes, stop and restart the jail. As the final step, you'll need to port forward the openvpn port (1174 by default, set by your config file) to the IP address of your jail. You'll also need to copy the ca.crt, ta.key, {clientname}.key, and {clientname}.crt to your client machine, as well as generating a client config file, which may need to be be given the .ovpn extension, depending on the client you're using.
If you've done everything correctly, you should now be able to access your VPN from your client machine. If you can't connect, check your port forwarding settings on the router. You should be forwarding the OpenVPN port to the jail's IP address, which is in your main subnet (in my example, that's 192.168.1.203), NOT the VPN address (i.e. 172.16.1.xxx). If you're able to connect to the VPN, but can't talk to your FreeNAS machine, check that you can ping the VPN subnet's gateway (in my case, 172.16.1.1). If you can do that, but can't access anything on the main subnet, it's an issue with the NAT/static route, or else you neglected to include a push route line in your server config.
First things first, open the Jails tab in the Web GUI and click Add Jails. Give it a name, select portjail as the type, select Autostart and VIMAGE, and uncheck NAT and vanilla. The rest of the defaults should be sufficient.
If you want to be able to SSH into your jail instead of using the Web GUI's shell icon, follow the instructions here
Now, we install openvpn from the ports collection:
Code:
cd /usr/ports/security/openvpn && make install clean
The defaults should be fine, just be sure that easy-rsa is selected for installation.
Now we can begin setting up our certificate authority. Basically every guide I've seen suggests copying the easy-rsa scripts outside of their default location so they don't get wiped out by an update. I chose /usr/local/etc/openvpn (this is also where I store my server config).
Code:
mkdir /usr/local/etc/openvpn cp -r /usr/local/share/easy-rsa /usr/local/etc/openvpn cd /usr/local/etc/openvpn/easy-rsa
Now, we need to edit the vars file. Open it in your editor of choice, and edit the following lines
Code:
KEY_COUNTRY KEY_PROVINCE KEY_CITY KEY_ORG KEY_EMAIL KEY_CN KEY_NAME KEY_OU
You can also change the KEY_SIZE to 2048 or 4096, if you're paranoid. This will cause the initial DH key generation to take much longer.
Now, we can set up our CA (these scripts don't like csh, so remain in sh for the rest of this guide, also note that the second command has two dots with a space between them)
Code:
sh . ./vars ./clean-all ./build-ca
Next is the server key
Code:
./build-key-server server
When it asks if you want to sign the certificate, say yes. Do the same when it asks if you want to commit the changes. A challenge password is optional, but recommended.
Now for the client keys. Run this once for each client.
Code:
./build-key {clientname}
Finally, we generate our Diffie-Hellman key. This will take awhile, especially if you increased the KEY_SIZE variable.
Code:
./build-dh
It's also a good idea to create an "HMAC firewall" to help block DoS attacks and UDP port flooding
Code:
openvpn --genkey --secret keys/ta.key
Now, let's copy our keys out of the default directory so that they won't accidentally get deleted if you run ./clean-all
Code:
cp -r keys ..
Next, you'll need to create your OpenVPN server config file. I named mine server.conf and placed it in /usr/local/etc/openvpn. You can find example config files here. Note that we're creating a routed connection, not a bridge, so ignore any lines dealing with bridged connections or the tap interface.
Now in order to allow traffic on the VPN subnet to access your main subnet, you'll either need a static route on your router or else you'll need to configure NAT using IPFW in your jail. I opted for the latter. First of all, you'll need to find the name of the jail's network interface. Since this is a VIMAGE jail, you should have an interface named epairNb, where N is dependent on the number of VIMAGE jails you currently have. In order to determine the actual name, just run
Code:
ifconfig -a
Create the file /usr/local/etc/ipfw.rules and add the following lines (modify them for your network and interface name)
Code:
IPFW -q -f flush IPFW -q nat 1 config if epairNb IPFW -q add nat 1 all from 172.16.1.0/24 to any out via epairNb IPFW -q add nat 1 all from any to any in via epairNb
Save ipfw.rules and open /etc/rc.conf.local and add these lines
Code:
openvpn_enable="YES" openvpn_if="tun" openvpn_configfile="/usr/local/etc/openvpn/server.conf" cloned_interfaces="tun" gateway_enable="YES" firewall_enable="YES" firewall_script="/usr/local/etc/ipfw.rules"
Now, in order to apply all of your changes, stop and restart the jail. As the final step, you'll need to port forward the openvpn port (1174 by default, set by your config file) to the IP address of your jail. You'll also need to copy the ca.crt, ta.key, {clientname}.key, and {clientname}.crt to your client machine, as well as generating a client config file, which may need to be be given the .ovpn extension, depending on the client you're using.
If you've done everything correctly, you should now be able to access your VPN from your client machine. If you can't connect, check your port forwarding settings on the router. You should be forwarding the OpenVPN port to the jail's IP address, which is in your main subnet (in my example, that's 192.168.1.203), NOT the VPN address (i.e. 172.16.1.xxx). If you're able to connect to the VPN, but can't talk to your FreeNAS machine, check that you can ping the VPN subnet's gateway (in my case, 172.16.1.1). If you can do that, but can't access anything on the main subnet, it's an issue with the NAT/static route, or else you neglected to include a push route line in your server config.