Tuesday, 23 October 2018

How to Setup an OpenVPN Client with IPFW in an iocage Jail on FreeNAS 11.1

بسم الله الرحمن الرحيم


Tutorial on how to setup and configure an OpenVPN Client in an Transmission iocage jail on FreeNAS 11.1 with IPFW to implement a VPN Killswitch.

Assumptions and Prerequisites

  • OS: FreeNAS 11.1-U6
  • FreeNAS Host: fn
  • FreeNAS Network Interface: igb0
  • FreeNAS IP:
  • FreeNAS Subnet Mask: 24
  • Jail Container: iocage
  • iocage Version: 1.0 Alpha
  • Jail Release: 11.1-RELEASE
  • Jail Name: transmission
  • Jail Network Interface: vnet0
  • Jail Network Config: DHCP
  • Jail Default Route:
  • IP Version: IPv4
  • Bridge Network Interface: bridge0
  • DNS 1: 
  • Domain: example.com
  • ZPool Volume: tank
  • VPN Service Provider: Trust Zone VPN (https://trust.zone)
  • Setup iocage Jail
  • Firewall: IPFW

OpenVPN Pre-Setup Tasks

Allow Jail To Create TUN Network Devices

OpenVPN Client needs to create a TUN interface in order to establish a secure encrypted connection. According to the default iocage jail security settings (rule 4), it doesn't allow the jail to create a tun network interface device. Because of that, the OpenVPN client won't be able to create and establish a VPN Tunnel to your choice of a VPN Service Provider. So, in order for it to be able to do that, you would need to allow the devfs rule 4 to be able to create a tun device network interface for the OpenVPN. And the way to do that is to create a 'preinit' task on the FreeNAS to run the following command on reboot on the FreeNAS server.   
devfs rule -s 4 add path 'tun*' unhide

Reboot FreeNAS.

Download OpenVPN files from your VPN Provider

Download the necessary files from your VPN service provider. I downloaded and copied the *.ovpn and userpass.txt files from my vpn provider (trust.zone) to the (/usr/local/etc/openvpn/) directory, create the directory if it does not exist. Make sure all the certificates, keys and settings are listed in the (trust_zone_vpn.ovpn) file and the 'auth-user-pass' setting in the trust_zone_vpn.ovpn is set to point at 'userpass.txt'.The  'userpass.txt' file has your VPN account's  username and password listed in it. You will need this for OpenVPN to auto login when the jail start/restart.  
root@transmission:~ # mkdir -p /usr/local/etc/openvpn

Setup OpenVPN Client

Install the openvpn package
root@transmission:~ # pkg install openvpn

Set the location of the openvpn config file
root@transmission:~ # sysrc openvpn_configfile="/usr/local/etc/openvpn/openvpn.conf"

Enable OpenVPN to start on boot
root@transmission:~ # sysrc openvpn_enable="YES"

Create a symbolic link 'openvpn.conf' to your trustzone.ovpn settings file 
root@transmission:~ # ln -s /usr/local/etc/openvpn/trust_zone_vpn.ovpn /usr/local/etc/openvpn/openvpn.conf

Before starting the openvpn service, first check and note down your public IP. 
root@transmission:~ # host myip.opendns.com resolver1.opendns.com

Start the openvpn service
root@transmission:~ # service openvpn start

Wait a minute for the openvpn service to start and establish a connection. Check to see if the TUN device has been assigned a different IP. 
root@transmission:~ # ifconfig

Then check the public IP again. It should be different to the public IP you checked earlier before you started the openvpn service. 
root@transmission:~ # host myip.opendns.com resolver1.opendns.com 

If the vpn tunnel is not created or established or the public IP remains the same as before, then something went wrong. Check the messages log file. Look for the line where it says "openvpn[####]: Initialization Sequence Completed". The line "openvpn[####]: Initialization Sequence Completed" indicates the connection was successful and established.

root@transmission:~ # tail -f -n 30 /var/log/messages

Setup VPN Killswitch with IPFW

Create directory to hold the ipfw startup script(s)
root@transmission:~ # mkdir -p /usr/local/etc/ipfw

Create startup script for ipfw rules
root@transmission:~ # ee /usr/local/etc/ipfw/ipfw_rules

---------File "/usr/local/etc/ipfw/ipfw_rules"---------------
# Flush out the list before we begin
ipfw -q -f flush

# Set rules command prefix
cmd="ipfw -q add"

# allow all local traffic on the loopback interface
$cmd 00001 allow all from any to any via lo0

# allow any connection to/from VPN interface
$cmd 00010 allow all from any to any via $vpn

# allow connection to/from LAN by Transmission
$cmd 00101 allow all from me to uid transmission
$cmd 00102 allow all from to me uid transmission

# deny any Transmission connection outside LAN that does not use VPN
$cmd 00103 deny all from any to any uid transmission
--------------End of File-------------------------------------------

Enable IPFW to start on boot
root@transmission:~ # sysrc firewall_enable="YES"

Set the startup script for ipfw rules
root@transmission:~ # sysrc firewall_script="/usr/local/etc/ipfw/ipfw_rules"

Start the IPFW service
root@transmission:~ # service ipfw start

Note: Although, the listed IPFW rules above implements a VPN killswitch. But, the major disadvantage of these rules is that it also prevents the access to the web admin GUI interface of Transmission from the LAN for Torrent administration when VPN tunnel is active. If anyone can write better IPFW rules that would implement a VPN killswitch without losing access to the web interface of Transmission, then let me know.

On my personal setup, instead of placing the OpenVPN and the Firewall rules to implement a VPN killswitch within the Jail itself, I have placed the VPN client on my pfSense router and configured the firewall rules on the pfSense router for my Transmission jail accordingly. I will probably write up a tutorial on how to do that on a separate post.       

Helpful Commands

Check your Public IP

root@transmission:~ # host myip.opendns.com resolver1.opendns.com
root@transmission:~ # curl https://wtfismyip.com/text
root@transmission:~ # curl ifconfig.me

Create a Symbolic link

root@transmission:~ # ln -s /path/to/source/file /path/to/new/link/file

Watch/Monitor a log file in real-time up to 30 lines

root@transmission:~ # tail -f -n 30 /var/log/messages

Resource Links

No comments: