A typical home setup may involve running many services which a user may want to gain access to when away from the home or office, security cameras, media collections and system minitoring tools for example. It is possible to open a myriad of firewall ports to provide remote access to all of your local services but exposing more than is absolutely necessary increases the risk of unauthorized intrusion. I provide a secure single VPN tunnel into my network which enables access to all my local services. This guide will build upon the previous pfSense baseline guides and demonstrate how to configure pfSense and an iOS device to enable access to internal servers remotely.
Most consumer internet connections provide service via a dynamic IP address rather than a static one, to enable us to locate our network we need to setup a Dynamic DNS service in pfSense that can be updated with our local WAN address as and when it changes. There are a number of Dynamic DNS providers supported by pfSense, navigate to Services > DynamicDNS and open up the service type drop down to see the options.
I’ll use Amazons Route 53 for this guide. We will create a test DNS entry in Route53’s DNS service for access.nguvu.org which will be updated with my WAN address. Depending on which Dynamic DNS service you chose, your authorisation settings may be slightly different.
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.
From the command line, perform a DNS lookup to verify the correct address is correctly being returned (I’ve obfuscated the Address response below)
$ nslookup access.nguvu.org
Server: 8.8.8.8
Address: 8.8.8.8#53
Non-authoritative answer:
Name: access.nguvu.org
Address: 1.2.3.4
To secure access to our SOHO network, we need to create a certificate authority to validate devices attempting to gain access.
Navigate to System > Cert Manager > CAs
Create / Edit CA
Internal Certificate Authority
Once created, verify your certificate authority looks like this when done
Navigate to System > Cert Manager > Certificates
Select Create an internal certificate
Add a new certificate
Internal Certificate
Certificate Attributes
Save
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 this isnt required to get our remote access working, its trivial to create so we may as well.
Navigate to System > Certificates > Certificate Revocation
Internal Certificate Revocation List
Now we’ll create the OpenVPN server which remote devices will connect to. We will change from the default port of 1194 to 443 as this port is often closed on remote networks.
Navigate to VPN > OpenVPN > Server
Click +Add
General Information
Cryptographic settings
Tunnel Settings
Client Settings
Advanced Client Settings
Advanced Configuration
mute-replay-warnings
maybe needed if you see a lot of replay warnings in your logsWe can now create an interface based on the OpenVPN server we just created.
Navigate to Interfaces > Assign
Select ‘ovpns4 (Roadwarrior VPN)’
Click Add
Click on the OPTx interface next to Roadwarrior VPN Network port
once you’ve saved and applied the changes, your interface should look like this
Navigate to System > Routing
Click ‘copy gateway’ icon next to RW_VPN_VPNV4 gateway
This section uses a few aliases which I used in my pfSense baseline configuration, please 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 > Rules and select 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
Select ↑Add
Your WAN interface should look this this when done.
Navigate to Services > DNS Resolver
Under Network interfaces dropdown, add RW_VPN to the selection to enable DNS resolution for remote devices.
Save & Apply
NAT is needed to convert your inbound devices private local IP address (192.168.200.0/24) to the global registered address space. We’ll set this up for our multiple VPN_WAN gateways, if you are only using a single VPN gateway, you’ll only need one of these three rules.
Navigate to Firewall > NAT and select the Outbound tab
Click ↴Add
Click ↴Add
Click ↴Add
I use the LOCAL_SUBNETS alias to define traffic which is internal and external. We need to add our new RW_VPN address range to this address to ensure we match traffic correctly 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.
We will now 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 or client and provides the ability to expire a single certificate to revoke access at any time.
Navigate to System > Cert Manager > Certificates
Click Add/Sign
Internal Certificate
Certificate Attributes
Your certificates summary should look this this when done.
We will use the Client Export Wizard to export client certificates. Navigate to System > Packages > Available packages and 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.
The following 4 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
pfSense-pkg-openvpn-client-export: 1.4.13_1 [pfSense]
openvpn-client-export: 2.4.3_4 [pfSense]
zip: 3.0_1 [pfSense]
p7zip: 16.02 [pfSense]
Number of packages to be installed: 4
The process will require 18 MiB more space.
11 MiB to be downloaded.
[1/4] Fetching pfSense-pkg-openvpn-client-export-1.4.13_1.txz: ... done
[2/4] Fetching openvpn-client-export-2.4.3_4.txz: .......... done
[3/4] Fetching zip-3.0_1.txz: .......... done
[4/4] Fetching p7zip-16.02.txz: .......... done
Checking integrity... done (0 conflicting)
[1/4] Installing openvpn-client-export-2.4.3_4...
[1/4] Extracting openvpn-client-export-2.4.3_4: .......... done
[2/4] Installing zip-3.0_1...
[2/4] Extracting zip-3.0_1: .......... done
[3/4] Installing p7zip-16.02...
[3/4] Extracting p7zip-16.02: .......... done
[4/4] Installing pfSense-pkg-openvpn-client-export-1.4.13_1...
Extracting pfSense-pkg-openvpn-client-export-1.4.13_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 the wizard has finished installing, navigate to VPN > OpenVPN and select Client Export and set up the options as follows:
OpenVPN Server
Client Connection Behavior
Certificate eport options
Proxy Options
Advanced
Save as default
There will now be several options displayed alongside each certificate for exporting in various formats. We will use 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
2017-09-09 18:56:51 ----- OpenVPN Start -----
OpenVPN core 3.1.2 ios arm64 64-bit built on Dec 5 2016 12:50:25
2017-09-09 18:56:51 Frame=512/2048/512 mssfix-ctrl=1250
2017-09-09 18:56:51 UNUSED OPTIONS
0 [persist-tun]
1 [persist-key]
4 [tls-client]
7 [lport] [0]
8 [verify-x509-name] [Roadwarrior_cert] [name]
2017-09-09 18:56:51 EVENT: RESOLVE
2017-09-09 18:56:51 Contacting [xxxx:xxxx::xx:x:x:xxxx:xxx]:443 via UDP
2017-09-09 18:56:51 EVENT: WAIT
2017-09-09 18:56:51 SetTunnelSocket returned 1
2017-09-09 18:56:51 Connecting to [access.nguvu.org]:443 (2607:7700::1a:0:1:4c5b:9d7) via UDPv6
2017-09-09 18:56:52 EVENT: CONNECTING
2017-09-09 18:56:52 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
2017-09-09 18:56:52 Creds: UsernameEmpty/PasswordEmpty
2017-09-09 18:56:52 Peer Info:
IV_GUI_VER=net.openvpn.connect.ios 1.1.1-212
IV_VER=3.1.2
IV_PLAT=ios
IV_NCP=2
IV_TCPNL=1
IV_PROTO=2
IV_LZO=1
IV_AUTO_SESS=1
2017-09-09 18:56:52 VERIFY OK: depth=1
cert. version : 3
serial number : 00
issuer name : C=US, ST=My State, L=My City, O=My org, emailAddress=info@nguvu.org, CN=internal-ca
subject name : C=US, ST=My State, L=My City, O=My org, emailAddress=info@nguvu.org, 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
2017-09-09 18:56:52 VERIFY OK: depth=0
cert. version : 3
serial number : 02
issuer name : C=US, ST=My State, L=My City, O=My org, emailAddress=info@nguvu.org, CN=internal-ca
subject name : C=US, ST=My State, L=My City, O=My org, emailAddress=info@nguvu.org, 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, ???
2017-09-09 18:56:52 SSL Handshake: TLSv1.2/TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384
2017-09-09 18:56:52 Session is ACTIVE
2017-09-09 18:56:52 EVENT: GET_CONFIG
2017-09-09 18:56:52 Sending PUSH_REQUEST to server...
2017-09-09 18:56:52 OPTIONS:
0 [dhcp-option] [DOMAIN] [local.lan]
1 [dhcp-option] [DNS] [192.168.200.1]
2 [dhcp-option] [NTP] [192.168.200.1]
3 [redirect-gateway] [def1]
4 [comp-lzo] [adaptive]
5 [route-gateway] [192.168.200.1]
6 [topology] [subnet]
7 [ping] [10]
8 [ping-restart] [60]
9 [ifconfig] [192.168.200.2] [255.255.255.0]
10 [peer-id] [0]
11 [cipher] [AES-256-GCM]
2017-09-09 18:56:52 PROTOCOL OPTIONS:
cipher: AES-256-GCM
digest: SHA1
compress: LZO
peer ID: 0
2017-09-09 18:56:52 EVENT: ASSIGN_IP
2017-09-09 18:56:52 Unknown pushed DHCP option: [dhcp-option] [NTP] [192.168.200.1]
2017-09-09 18:56:52 TunPersist: saving tun context:
Session Name: access.nguvu.org
Layer: OSI_LAYER_3
Remote Address: xxxx:xxxx::xx:x:x:xxxx:xxx [IPv6]
Tunnel Addresses:
192.168.200.2/24 -> 192.168.200.1
Reroute Gateway: IPv4=1 IPv6=0 flags=[ ENABLE REROUTE_GW DEF1 IPv4 ]
Block IPv6: no
Add Routes:
Exclude Routes:
DNS Servers:
192.168.200.1
Search Domains:
local.lan
2017-09-09 18:56:52 Connected via tun
2017-09-09 18:56:52 LZO-ASYM init swap=0 asym=0
2017-09-09 18:56:52 EVENT: CONNECTED @access.nguvu.org:443 (xxxx:xxxx::xx:x:x:xxxx:xxx) via /UDPv6 on tun/192.168.200.2/ gw=[192.168.200.1/]
2017-09-09 18:56:52 SetStatus Connected
2017-09-09 18:56:53 NET Internet:ReachableViaWWAN/WR t------
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.
15 January 2018
Fixed error in certificate export instruction
Fixed typos
2 November 2017
Fixed roadwarrior certificate server type error
Fixed RW_VPN NAT section