nguvu

pfSense remote access via OpenVPN

Revised 20 February 2021.

Contents

Introduction

Small home or office (SOHO) setups often involve services that a user wants to access when away from the home or office, security cameras, media collections and system monitoring tools for example. One solution to access these remotely is to open a number of firewall ports. An alternative and more secure method used is to open a single port and enable access through an OpenVPN connection. This guide will build upon the pfSense baseline guide and illustrate how to configure pfSense and an iOS device to enable secure remote access.

Dynamic DNS

Most non-business internet connections provide service through a dynamic IP address as opposed to a static one. To enable remote devices to locate and access our network we can use a dynamic DNS service that can keep a DNS record updated with our networks current local WAN address. PFsense has such a service that supports a wide variety of DNS services. This guide will use Amazon’s Route 53 but the same principles apply to the other services although the authorisation settings may vary slightly.

Dynamic DNS Configuration

Navigate to Services > Dynamic DNS and Click Add

Click Save and then Force Update

Route53 Dynamic DNS Setup
Route53 Dynamic DNS Setup

If everything is correct, your Dynamic DNS record will be updated to your WAN address. We will use this record in our VPN tunnel connection settings later.

Route53 Dynamic DNS Configured
Route53 Dynamic DNS Configured

Dynamic DNS Verification

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: xxx.xxx.xxx.xxx

Secure OpenVPN

To provide secure access through OpenVPN we need to provision a Certificate Authority (CA) and generate a suitable certificate. The CA issues and validates the certificates that will secure the VPN.

Cipher selection

I decided to leave my recommendation as is for a 4096 bit RSA based system rather than a more modern elliptical curve based method for a couple of reasons.

I’ve added some links in the reference section below for further reading. I welcome feedback and suggestions as this is an area I’m actively researching.

Configure Certificate Authority (CA)

Navigate to System > Cert Manager > CAs

Create / Edit CA

Internal Certificate Authority

Save

Create internal certificate authority
Create internal certificate authority

Verify your certificate authority looks like this when done

Internal certificate authority
Internal certificate authority

Generate certificate

Navigate to System > Cert Manager > Certificates

Internal Certificate

Certificate Attributes

Save

Create roadwarrior certificate
Create roadwarrior certificate

Verify your certificate looks like this when done

Created roadwarrior certificate
Created roadwarrior certificate

Configure Certificate Revocation List

The Certificate Revocation List (CRL) will allow certificates to be expired.

Navigate to System > Certificates > Certificate Revocation

Internal Certificate Revocation List

Click Save

Configure OpenVPN server

This section will configure a secure OpenVPN server running on port 443 rather than the default OpenVPN port of 1194. This reduces the likelihood of a remote network preventing access to your local infrastructure because port 1194 is not permitted or open.

Navigate to VPN > OpenVPN > Server

Click +Add

General Information

Cryptographic settings

Tunnel Settings

Client Settings

Ping Settings

Advanced Client Settings

Advanced Configuration

Create VPN Server
Create VPN Server

Assign OpenVPN interface

Create an interface for the OpenVPN server to support the configuration of firewall rules and enable other services such as NTP & DNS.

Navigate to Interfaces > Assign

Select ‘ovpns4 (Roadwarrior VPN)’
Click Add

Add VPN server interface
Add VPN server interface

Click on the OPTx interface next to Roadwarrior VPN Network port

After saving and applying the configuration, the interface should look similar to this

VPN server interface
VPN server interface

Configure OpenVPN gateway

Navigate to System > Routing

Click ‘copy gateway’ icon next to RW_VPN_VPNV4 gateway

Configure VPN server gateway
Configure VPN server gateway

Configure firewall rules

This section makes uses of several aliases that were configured as part of my pfSense baseline guide.
This section will setup firewall rules for the OpenVPN interface to provide the following access:-

Navigate to Firewall > Rules and select RW_VPN

Allow Pings for network diagnostics

Allow traffic to local subnets (LOCAL_SUBNETS) on permitted ports (Allowed_OUT_ports_LAN).

Pass approved internet bound traffic out the VPN gateway

Default Block & log IPv4

Block default IPv6

The RW_VPN interface should look this this complete.

Configure VPN firewall rules
Configure VPN firewall rules

Open VPN WAN port

To enable devices to connect to the OpenVPN server the firewall needs port 443 opening.

Navigate to Firewall > WAN

Select ↑Add

WAN firewall rules
WAN firewall rules

Your WAN interface should look this this when done.

Configure WAN firewall rules
Configure WAN firewall rules

Configure DNS resolution

Navigate to Services > DNS Resolver

Under Network interfaces dropdown, verify and add the RW_VPN is selected

Save & Apply

Configure Network Address Translation (NAT)

NAT is needed to convert private local IP addresses (192.168.200.0/24) to the global address space for broadcast on the internet. This section will illustrate how to configure this for our VPN_WAN gateway (or gateways if you have already followed my multiple-VPN failover guide).

Navigate to Firewall > NAT and select the Outbound tab

Create ‘RW_VPN to VPN_WAN` NAT

Click ↴Add

Create ‘RW_VPN to VPN2_WAN` NAT

Click ↴Add

Create ‘RW_VPN to VPN_WAN` NAT

Click ↴Add

Update aliases

The LOCAL_SUBNETS alias is used to identify internal and external networks. Verify the RW_VPN address range (192.168.200.0/24) is included in the alias so policy routing continues to function correctly. If you followed a later revision of my baseline guide, you may instead have a 192.168.0.0/16 entry, if so this already includes the `192.168.200.0/24 subnet.

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.

Updated alias
Update alias

Generate VPN user certificate

This section will illustrate how to create a client certificate suitable for an specific user or device to connect remotely. Although its possible to configure OpenVPN to accept the same certificate from multiple clients, its a less secure solution and avoided here.

Navigate to System > Cert Manager > Certificates

Click Add/Sign

Internal Certificate

Certificate Attributes

When complete the certificate summary should look similar to this.

iPhone certificate
iPhone certificate

Install OpenVPN Client Export wizard

The Client Export Wizard simplifies the export of client certificates in a format compatible with a number of devices and software packages.

Navigate to System > Packages > Available packages and click Install next to the OpenVPN-client-export to install the utility.

A window will display installation progress…

>>> 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:
        openvpn-client-export: 2.5.0 [pfSense]
        p7zip: 16.02_3 [pfSense]
        pfSense-pkg-openvpn-client-export: 1.5_5 [pfSense]
        zip: 3.0_1 [pfSense]

Number of packages to be installed: 4

The process will require 23 MiB more space.
16 MiB to be downloaded.
[1/4] Fetching pfSense-pkg-openvpn-client-export-1.5_5.txz: ... done
[2/4] Fetching openvpn-client-export-2.5.0.txz: .......... done
[3/4] Fetching zip-3.0_1.txz: .......... done
[4/4] Fetching p7zip-16.02_3.txz: .......... done
Checking integrity... done (0 conflicting)
[1/4] Installing openvpn-client-export-2.5.0...
[1/4] Extracting openvpn-client-export-2.5.0: .......... done
[2/4] Installing zip-3.0_1...
[2/4] Extracting zip-3.0_1: .......... done
[3/4] Installing p7zip-16.02_3...
[3/4] Extracting p7zip-16.02_3: .......... done
[4/4] Installing pfSense-pkg-openvpn-client-export-1.5_5...
[4/4] Extracting pfSense-pkg-openvpn-client-export-1.5_5: .......... 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

Export user certificate

Navigate to VPN > OpenVPN and select Client Export tab. Configure as follows:-

OpenVPN Server

Client Connection Behaviour

Certificate export options

Proxy Options

Advanced

Click Save as default

Certificates can be exported by selecting one of the options to the right of each certificate.

Click on OpenVPN connect (Android or iOS) and a .ovpn configuration file will be downloaded to your desktop.

Install client software

The official OpenVPN connect client (iOS & Android) applications provide easy to use and secure OpenVPN functionality and can utilise the the exported .ovpn configuration file.
There are many ways to transfer the configuration file to your device. Please be mindful of the security risks transferring this file via a third party service such as email or dropbox. This file contains all the details needed to access your network remotely so its worth taking precautions to prevent it being compromised. Consider using self hosted file storage systems such as Seafile or direct connection utilities such as Instashare.

Having transferred the configuration file to the mobile device, there wll be a prompt to add the connection profile.

Import VPN profile
Import VPN profile

Once imported its possible to finally connect.

Instashare import
Instashare import

Assuming everything has gone well, your mobile device should connect to your OpenVPN server.

OpenVPN Connected
OpenVPN Connected

If the connection isn’t successful, inspect the logs available within the application.

OpenVPN logs
OpenVPN logs

Here’s a log example for reference

2021-02-16 15:23:35 ----- OpenVPN Start -----
OpenVPN core 3.git::58b92569 ios arm64 64-bit
2021-02-16 15:23:35 OpenVPN core 3.git::58b92569 ios arm64 64-bit
2021-02-16 15:23:35 Frame=512/2048/512 mssfix-ctrl=1250
2021-02-16 15:23:35 UNUSED OPTIONS
0 [persist-tun] 
1 [persist-key] 
2 [data-ciphers] [AES-256-GCM:AES-256-CBC] 
3 [data-ciphers-fallback] [AES-256-CBC] 
5 [tls-client] 
8 [block-outside-dns] 
9 [lport] [0] 
10 [verify-x509-name] [internal-ca] [name] 

2021-02-16 15:23:35 EVENT: RESOLVE
2021-02-16 15:23:35 Contacting [xxx.xxx.xxx.xxx]:443/UDP via UDP
2021-02-16 15:23:35 EVENT: WAIT
2021-02-16 15:23:35 Connecting to [access.nguvu.org]:443 (xxx.xxx.xxx.xxx) via UDPv4
2021-02-16 15:23:35 EVENT: CONNECTING
2021-02-16 15:23:35 Tunnel Options:V4,dev-type tun,link-mtu 1585,tun-mtu 1500,proto UDPv4,cipher BF-CBC,auth SHA512,keysize 128,key-method 2,tls-client
2021-02-16 15:23:35 Creds: UsernameEmpty/PasswordEmpty
2021-02-16 15:23:35 Peer Info:
IV_VER=3.git::58b92569
IV_PLAT=ios
IV_NCP=2
IV_TCPNL=1
IV_PROTO=2
IV_IPv6=0
IV_AUTO_SESS=1
IV_GUI_VER=net.openvpn.connect.ios_3.2.3-3760
IV_SSO=openurl
IV_BS64DL=1

2021-02-16 15:23:35 VERIFY OK: depth=1, /CN=internal-ca
2021-02-16 15:23:35 VERIFY OK: depth=0, /CN=internal-ca
2021-02-16 15:23:35 SSL Handshake: CN=internal-ca, TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384
2021-02-16 15:23:35 Session is ACTIVE
2021-02-16 15:23:35 EVENT: GET_CONFIG
2021-02-16 15:23:35 Sending PUSH_REQUEST to server...
2021-02-16 15:23:35 OPTIONS:
0 [dhcp-option] [DOMAIN] [local.lan] 
1 [dhcp-option] [DNS] [192.168.200.1] 
2 [block-outside-dns] 
3 [register-dns] 
4 [dhcp-option] [NTP] [192.168.200.1] 
5 [redirect-gateway] [def1] 
6 [route-gateway] [192.168.200.1] 
7 [topology] [subnet] 
8 [ping] [5] 
9 [ping-restart] [30] 
10 [ifconfig] [192.168.200.2] [255.255.255.0] 
11 [peer-id] [0] 
12 [cipher] [AES-256-GCM] 
13 [block-ipv6] 

2021-02-16 15:23:35 PROTOCOL OPTIONS:
  cipher: AES-256-GCM
  digest: NONE
  compress: NONE
  peer ID: 0

2021-02-16 15:23:35 EVENT: ASSIGN_IP
2021-02-16 15:23:35 NIP: preparing TUN network settings
2021-02-16 15:23:35 NIP: init TUN network settings with endpoint: xxx.xxx.xxx.xxx
2021-02-16 15:23:35 NIP: adding IPv4 address to network settings 192.168.200.2/255.255.255.0
2021-02-16 15:23:35 NIP: adding (included) IPv4 route 192.168.200.0/24
2021-02-16 15:23:35 NIP: redirecting all IPv4 traffic to TUN interface
2021-02-16 15:23:35 NIP: adding match domain local.lan
2021-02-16 15:23:35 NIP: adding DNS 192.168.200.1
2021-02-16 15:23:35 NIP: blocking all IPv6 traffic
2021-02-16 15:23:35 Connected via NetworkExtensionTUN
2021-02-16 15:23:35 EVENT: CONNECTED access.nguvu.org:443 (xxx.xxx.xxx.xxx) via /UDPv4 on NetworkExtensionTUN/192.168.200.2/ gw=[/]

Verification of functionality and performance

Navigate to Status > OpenVPN

Verify the OpenVPN tunnel is connected as expected

OpenVPN connections
OpenVPN connections

Revoking certificates

To expire a certificate, Navigate to System > Cert Manager > Cert Revocation

Select the certificate to expire, enter a reason and select ‘Add’

OpenVPN certificate revocation
OpenVPN certificate revocation

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.

References

torproject: NIST approved crypto in Tor
Wikipedia:Dual_EC_DRBG
New York Times: N.S.A. Able to Foil Basic Safeguards of Privacy on Web
CryptoExchange: Should we trust the NIST-recommended ECC parameters
Safecurves

Changelog

20 February 2021
Updates for pfSense 2.5
Updates for OpenVPN 2.5
Added reasoning around RSA preferences over ECC ciphers

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