A typical home setup may involve running many services which a user may want to gain access to when away from the home, a common use is to view Plex media server content. It is possible to open a myriad of firewall ports and provide WAN access to all of your local services them but to my mind exposing more than is absolutely necessary is increasing the risk of a network intrusion. I prefer to provide a single VPN tunnel into my home network to access all local services.
This guide will take you through configuring pfSense and also a iOS device to enable access any internal servers remotely, including plex.
Most consumer internet connections provide service via a dynamic IP address which changes from time to time, Verizons is one of these. To ensure we can always access our network we need to setup a Dynamic DNS service which will keep a DNS name up to date with any changes.
For the purpose of this guide, I’ve created a test DNS entry in my Route53 DNS service for access.nguvu.org which points to my entry address. Depending on who you use to manage your DNS records with your settings may vary.
Navigate to Services > Dynamic DNS
If everything is correct, your Dynamic DNS record should be updated to that of your WAN interface. We will use this record in our VPN tunnel connection settings later.
We need a certificate authority to validate devices attemtping to gain access.
Navigate to System > Cert Manager > CAs
Create / Edit CA
Internal Certificate Authority
Verify your certificate authority looks like this when done
Navigate to System > Cert Manager > Certificates
Select Create an internal certificate
Add a new certificate
Verify your certificate looks like this when done
You’ll need a revocation list for if/when you need to expire any certificates you create. Although technically this isnt required to get this system up and running its pretty trivial so we may as well.
Navigate to System > Certificates > Certificate Revocation
Create new revocation list
Internal Certificate Revocation List
Now we’ll create the OpenVPN server which remote devices will connect to. We will change from the default pot of 1194 to 443 as this port is often closed on remote networks.
Navigate to VPN > OpenVPN > Server
Wireless networks often produce a lot of duplicate packets. Set
mute-replay-warnings in the custom options box if you need to mute those warnings.
We can now create an interface based on the OpenVPN server we just created.
Navigate to Interfaces > Assign
Select ‘ovpns4 (Roadwarrior VPN)’
Click on the OPTx interface next to Roadwarrior VPN Network port
Navigate to System > Routing
Click ‘copy’ icon next to RW_VPN_VPNV4 gateway
This section uses a few aliases which I used in my pfSense 2.3 baseline configuration, refer to that guide if this doesn’t make sense to you.
Setup the rules on the OpenVPN server interface to allow for the following access
Navigate to Firewall > RW_VPN
Allow Pings for network diagnostics
Allow traffic to local subnets (LOCAL_SUBNETS alias) on permitted ports only (Allowed_OUT_ports_LAN alias).
Pass approved internet bound traffic out the VPN gateway
Default Block & log IPv4
Block default IPv6
Your RW_VPN interface should look this this when done.
We will now open a port on our firewall to allow access to the OpenVPN server which is running on port 443.
Navigate to Firewall > WAN
Your WAN interface should look this this when done.
Navigate to Services > DNS Resolver
Under Network interfaces dropdown, add RW_VPN to the selection choice.
I use the LOCAL_SUBNETS alias to define traffic which is classed as internal or external so we need to add our new RW_VPN address range to this address to ensure we match traffic against the appropriate firewall rules.
Navigate to Firewall > Aliases
Click the pencil icon next to the LOCAL_SUBNETS alias to edit the list
Add the RW_VPN address range, i.e
Click Save & Apply
Your LOCAL_SUBNETS alias should look this this when done.
I’ll show you how to create a client certificate for an iOS device. Although you can set OpenVPN up to accept the same certificate from multiple clients its a less secure solution and not my preferred option. This option allows you to specify a certificate per user and/or per client and provides the ability to expire one at any time.
Navigate to System > Cert Manager > Certificates
Your certificate should look this this when done.
To get the certificate into your client device we’ll make use of the OpenVPN-client-export wizard.
Navigate to System > Packages >Available packages
Click Install next to the OpenVPN-client-export to install the utility.
You’ll see the window populate with a progress report…
>>> Installing pfSense-pkg-openvpn-client-export... Updating pfSense-core repository catalogue... pfSense-core repository is up-to-date. Updating pfSense repository catalogue... pfSense repository is up-to-date. All repositories are up-to-date. Updating database digests format: . done The following 4 package(s) will be affected (of 0 checked): New packages to be INSTALLED: pfSense-pkg-openvpn-client-export: 1.3.6_1 [pfSense] zip: 3.0_1 [pfSense] p7zip: 15.09 [pfSense] openvpn-client-export: 2.3.10 [pfSense] The process will require 14 MiB more space. 7 MiB to be downloaded. Fetching pfSense-pkg-openvpn-client-export-1.3.6_1.txz: .. done Fetching zip-3.0_1.txz: .......... done Fetching p7zip-15.09.txz: .......... done Fetching openvpn-client-export-2.3.10.txz: .......... done Checking integrity... done (0 conflicting) [1/4] Installing zip-3.0_1... [1/4] Extracting zip-3.0_1: .......... done [2/4] Installing p7zip-15.09... [2/4] Extracting p7zip-15.09: .......... done [3/4] Installing openvpn-client-export-2.3.10... [3/4] Extracting openvpn-client-export-2.3.10: .......... done [4/4] Installing pfSense-pkg-openvpn-client-export-1.3.6_1... [4/4] Extracting pfSense-pkg-openvpn-client-export-1.3.6_1: ...... done Saving updated package information... done. Loading package configuration... done. Configuring package components... Loading package instructions... Custom commands... Writing configuration... done. >>> Cleaning up cache... done. Success
Once it has finished, Navigate to VPN > Client Export
We will use the Dynamic DNS record we setup at the beginning of this guide to ensure we can always reach our network regardless of any updates to IP address.
Set up the options as follows:
There will be several options displayed alongside each certificate for exporting in various formats. The one we are looking for is the inline configuration for the OpenVPN Connect client.
Click on OpenVPN connect (Android or iOS)
A certificate file will be downloaded to your desktop which we can now transfer across to our iOS device.
The OpenVPN connect application provides OpenVPN functionality for a number of platforms. Install this on your device to provide the means to process .ovpn files.
In terms of getting the .ovpn file to your device, there are numerous ways to handle this. You can email the file to yourself, transfer it via a cloud service such as Dropbox however please be aware that this file contains all the details needed to access your network and hence its worthwhile taking extra care in how you transfer it to prevent it being compromised. A few methods which provide a secure method include SpiderOak which is an encrypted Dropbox alternative, iTunes or my favourite, Instashare which facilitates direct transfers from Mac > iOS devices.
In my case, once I have dragged the .ovpn file to my instashare folder the file appears on my iOS device.
I can now copy the file into the OpenVPN Connect Application which will begin the import process
OpenVPN will open and prompt you to import the certificate. Click the green + symbol to add it to your device.
Once imported, you can toggle the connection switch to initiate an connection.
If everything has gone correctly, you should see the display change to connected with associated IP, port and protocol details below
You can debug any errors or validate the connection is correct by inspecting the log by expanding the Connected box with the ‘>’ arrow.
Here’s my log relating to this connection example for reference
2016-03-05 19:07:05 EVENT: RESOLVE 2016-03-05 19:07:06 LZO-ASYM init swap=0 asym=0 2016-03-05 19:07:06 Contacting 71.***.***.***:443 via UDP 2016-03-05 19:07:06 EVENT: WAIT 2016-03-05 19:07:06 SetTunnelSocket returned 1 2016-03-05 19:07:06 Connecting to access.nguvu.org:443 (71.***.***.***) via UDPv4 2016-03-05 19:07:06 EVENT: CONNECTING 2016-03-05 19:07:06 Tunnel Options:V4,dev-type tun,link-mtu 1558,tun-mtu 1500,proto UDPv4,comp-lzo,keydir 1,cipher AES-256-CBC,auth SHA1,keysize 256,tls-auth,key-method 2,tls-client 2016-03-05 19:07:06 Peer Info: IV_GUI_VER=net.openvpn.connect.ios 1.0.5-177 IV_VER=3.0 IV_PLAT=ios IV_NCP=1 IV_LZO=1 2016-03-05 19:07:06 VERIFY OK: depth=1 cert. version : 3 serial number : 00 issuer name : C=US, ST=My State, L=My City, O=My org, emailAddressfirstname.lastname@example.org, CN=internal-ca subject name : C=US, ST=My State, L=My City, O=My org, emailAddressemail@example.com, CN=internal-ca issued on : 2016-03-02 01:32:46 expires on : 2026-02-28 01:32:46 signed using : RSA with SHA-256 RSA key size : 4096 bits basic constraints : CA=true key usage : Key Cert Sign, CRL Sign 2016-03-05 19:07:06 VERIFY OK: depth=0 cert. version : 3 serial number : 02 issuer name : C=US, ST=My State, L=My City, O=My org, emailAddressfirstname.lastname@example.org, CN=internal-ca subject name : C=US, ST=My State, L=My City, O=My org, emailAddressemail@example.com, CN=Roadwarrior_cert issued on : 2016-03-02 02:08:49 expires on : 2026-02-28 02:08:49 signed using : RSA with SHA-256 RSA key size : 4096 bits basic constraints : CA=false subject alt name : pfsense.local.lan cert. type : SSL Server key usage : Digital Signature, Key Encipherment ext key usage : TLS Web Server Authentication, ??? 2016-03-05 19:07:07 SSL Handshake: TLSv1.2/TLS-DHE-RSA-WITH-AES-256-CBC-SHA 2016-03-05 19:07:07 Session is ACTIVE 2016-03-05 19:07:07 EVENT: GET_CONFIG 2016-03-05 19:07:07 Sending PUSH_REQUEST to server... 2016-03-05 19:07:07 OPTIONS: 0 [dhcp-option] [DOMAIN] [local.lan] 1 [dhcp-option] [DNS] [192.168.100.1] 2 [redirect-gateway] [def1] 3 [route-gateway] [192.168.100.1] 4 [topology] [subnet] 5 [ping]  6 [ping-restart]  7 [ifconfig] [192.168.100.2] [255.255.255.0] 2016-03-05 19:07:07 LZO-ASYM init swap=0 asym=0 2016-03-05 19:07:07 EVENT: ASSIGN_IP 2016-03-05 19:07:07 TunPersist: saving tun context: Session Name: access.nguvu.org Remote Address: 71.***.***.*** Tunnel Addresses: 192.168.100.2/24 -> 192.168.100.1 Reroute Gateway: IPv4=1 IPv6=0 flags=[ ENABLE REROUTE_GW DEF1 IPv4 ] Block IPv6: no Add Routes: Exclude Routes: DNS Servers: 192.168.100.1 Search Domains: local.lan 2016-03-05 19:07:07 Connected via tun 2016-03-05 19:07:07 EVENT: CONNECTED @access.nguvu.org:443 (71.***.***.***) via /UDPv4 on tun/192.168.100.2/ 2016-03-05 19:07:07 SetStatus Connected
Navigate to >Status > OpenVPN
Verify the OpenVPN tunnel is connected as expected
At some stage you will want to expire a certificate.
Navigate to System > Cert Manager > Cert Revocation
Select the certificate you want to expire, and a reason why and select ‘Add’
The certificate will now be revoked and access denied. It is possible to reinstall the certificate by deleting the revocation with the blue ‘x’ on the right of the screen.