pfSense is a powerful open-source-based router/firewall that’s focused on security and usability.
With pfSense, you have three options when it comes to setting up a VPN: IPSec, OpenVPN, and WireGuard. You can use either protocol to setup, a site-to-site connection, linking two separate networks over the VPN tunnel, an “always-on” connection to a VPN server (typically a commercial VPN provider), or a road warrior setup for remote access. It’s the latter that interests us in this post.
In this guide we’re going to explain how to set up a road warrior setup pfSense using WireGuard.
Note: Netgate, the company behind pfSense’s development, maintains two forks of the project:
pfSense CE, which stands for Community Edition, is the fully open-source version of pfSense. pfSense Plus is open-source-based but with extra features added using proprietary code. While both are free for individual users, we’ll be using pfSense CE in this guide – which also assumes you have a working pfSense configuration with a WAN and a LAN interface setup.
Installing the WireGuard package
The first thing we’re going to do is install the WireGuard package. WireGuard isn’t included in pfSense CE out of the box. But we can install it from the official pfSense package repository.
- From the top menus, select General > Package Manager. The Installed Packages tab of the Package Manager is displayed.
- Go to the Available Packages tab. The list of available packages is displayed.
- Scroll down towards the bottom of the page until you see WireGuard.
- Click the Install button to the right of WireGuard. This displays up the Package Installer window.
- Click Confirm to begin the installation.
- Once the package is installed, you should see the word Success displayed at the bottom of the Package Installer window. You’ve successfully installed WireGuard.
Configuring the WireGuard package
Now that WireGuard is installed on our system, we can begin the configuration.
Before we begin, note that WireGuard does not use the typical server/client nomenclature. Instead, every participant in the network is a node that can talk to the other nodes based on its access control list (acl). Despite those semantics, we’re going to treat the “pfSense node” as our server – which makes sense, particularly in a road warrior setup.
Setting up the pfSense node/server
- From the top menus, select VPN > WireGuard. The main WireGuard settings page is displayed.
- By default, we are on the Tunnels page. Click Add Tunnel. The Tunnel Configuration page is displayed.
- Under Tunnel Configuration, tick the Enable Tunnel box.
- Enter a description in the Description field.
- Enter a port in the Listen Port field. The default is 51820.
- Click the Generate button to generate a key pair for our pfSense WireGuard node/server. The resulting keys are displayed in the Interface Keys fields.
- In the Interface Configuration section, enter an interface address in the Interface Addresses field. Make sure to use a subnet that’s not already in use on your system and give it a /24 subnet mask. You can also optionally enter a description.
- Click Save Tunnel. You’re taken back to the main WireGuard settings page.
Enabling the WireGuard service
- We can see that our tunnel is greyed out in the list and we have a message stating that “The WireGuard service is not running.” Select the Settings tab. The Settings page is displayed.
- Under General Settings, tick the Enable WireGuard box.
- Under User Interface Settings, untick the Hide Secrets and Hide Peers boxes.
- Click Save at the bottom of the page. You’re taken back to the main WireGuard settings page.
- We can see that our tunnel is no longer greyed out now that the service is running.
Adding a peer
- Each peer needs to have its own public/private key pair. We generated a key pair for the “server” node when we created it. But because there’s no key generation button in the peer settings, we’re going to perform a small hack to generate our peer’s key pair. From the Tunnels tab, click Add Tunnel. The Tunnel Configuration page is displayed.
- Click the Generate button to generate a key pair. Copy both the public and private keys displayed in the Interface Keys fields. We will use those keys to configure our peer.
- Click the Tunnels tab to exit. You’re taken back to the main WireGuard settings page.
- Select the Peers tab. The Peers page is displayed.
- Click Add Peer. The Peer Configuration page is displayed.
- Under Peer Configuration, tick the Enable Peer box.
- From the Tunnel drop-down menu, select the WireGUard interface we created earlier. It should be tun_wg0.
- Enter a description in the Description field.
- Untick the Dynamic box next to Dynamic Endpoint.
- In the Endpoint and Port fields, enter the IP address of the interface we created earlier and the listening port number we chose. In my case this is 192.168.10.1 and 51820.
- In the Public Key field, enter the public key from the peer keypair we generated earlier.
- Click the Generate button next to Pre-shared Key. This adds an extra layer of security by requiring matching pre-shared keys as well as the peer’s private/public keys we’ll be setting up in a later step. The generated pre-shared key is displayed in the Pre-shared Key field. Copy it – we will need it later.
- Under Address Configuration, enter the IP address you want to assign to this peer. Make sure it’s in the same subnet as the WireGuard interface we created (18.104.22.168/24 in my case) and give it a /32 subnet mask. I will use 192.168.10.10/32. You can optionally enter a description in the Description field.
- Click Save Peer at the bottom of the page. You’re taken back to the main WireGuard settings page.
- Click Apply Changes.
Checking the status of our WireGuard tunnel
- Select the Status tab. The WireGuard Status page is displayed.
- We can see that our tunnel is up and running and that our peer exists but is not yet connected. Our next step will be to make sure our WireGuard nodes can use our system’s DNS server.
Checking DNS access
By default when you configure a WireGuard tunnel, pfSense automatically adds an ACL entry for the WireGuard subnet in pfSense’s DNS Resolver (Unbound). This allows the WireGuard interface to use the DNS Resolver for DNS resolution. There’s nothing to configure here. We just want to make sure everything is set up correctly.
- From the top menus, select Services > DNS Resolver. The main DNS Resolver settings page is displayed
- Select the Access Lists tab. The Access Lists configuration page is displayed.
- We can see that we have a WireGuard ACL entry that was automatically added. Click the pencil icon to the right of the page.
- We can see that our WireGuard subnet (192.168.10.0/24) is allowed access to the DNS Resolver.
Enabling port forwarding and firewall rules
Our next step is to configure pfSense to allow the peer to connect and for its traffic to be allowed through the firewall. To do this, we’re going to add some port forwarding rules.
- From the top menus, select Firewall > NAT. The main NAT configuration page is displayed and we’re on the Port Forwarding tab by default.
- Click the Add button (with the arrow pointing upwards). The port forwarding rule page is displayed.
- From the Interface drop-down menu, select WAN.
- From the Address Family drop-down menu, select IPv4.
- From the Protocol drop-down menu, select UDP.
- From the Destination drop-down menu, select WAN address.
- From the Destination port range drop-down menus, select Other and enter 51820 in both port fields.
- From the Redirect target IP drop-down menu, select Single host and enter the WireGuard node/server’s interface address (192.168.10.1).
- From the Redirect target port drop-down menu, select Other and enter 51820 in the port field.
- Enter a description in the Description field.
- Make sure that the Filter rule association drop-down menu is set to Add associated filter rule. This will create a corresponding rule on our WAN interface automatically.
- Click Save at the bottom of the page. You’re taken back to the main NAT configuration page.
- Click Apply Changes.
- Our port forward rule has been applied. Let’s now make sure our WAN rule has been automatically added.
- From the top menus, select Firewall > Rules. The main Firewall rules page is displayed and we’re on the WAN page by default.
- We can see that our WAN rule has indeed been added. Select the WireGuard tab.
- The WireGuard tab is automatically generated as soon as you create a WireGuard interface and the rules in this tab apply to all WireGuard interfaces you add to your system. It is distinct from the standalone interface tab you would have if you had assigned the WireGuard interface on the system, like the LAN tab/interface. If we wanted to use the WireGuard interface as a gateway, this would have been useful. But because we’re going to be using the pfSense WAN interface as our gateway, there’s no need to assign the interface, we can use the “general” WireGuard tab to allow traffic on our WireGuard interface. Click Add (with the arrow pointing upwards). The FIrewall Rule configuration page is displayed.
- Make sure the Action drop-down menu is set to Pass.
- Make sure the Interface drop-down menu is set to WireGuard.
- Make sure the Address Family drop-down is set to IPv4.
- From the Protocol drop-down menu, select Any.
- From the Source drop-down menu, select Network and enter your WireGuard subnet and a /24 subnet mask. In my case, this is 192.168.10.0/24.
- From the Destination drop-down menu, select Any.
- Click Save at the bottom of the page.
- You’re taken back to the main Firewall Rule configuration page. Click Apply Changes.
- Our firewall rule has been applied and our remote peer should be allowed to connect and its traffic should be allowed through the firewall. Our next step will be to configure our remote peer (client). We’ll be doing this using the official WireGuard app for iPhone.
Setting up our remote peer (client)
- Download and install the WireGuard app for your device. I’ll be using an iPhone for this tutorial.
- From the app’s main screen, click Add Tunnel. A pop-up menu appears.
- Select Create from scratch.
- Under Interface, enter a name for your connection in the Name field.
- Copy and paste the peer’s private key in the Private Key field. The public key will be populated automatically.
- Enter the peer’s IP address in the Address field. This is 192.168.10.10/32 in my case.
- Enter the port number in the Port field. In my case, this is 51820.
- Enter your pfSense box’s IP address in the DNS field. This is 192.168.1.1 in my case.
- Under Peer, enter the “server” node’s public key in the Public key field. You can copy it from the Tunnels tab.
- Enter the peer’s pre-shared key in the Preshared key field.
- Enter 0.0.0.0/0 in the Allowed IPs field. This will pass all traffic through the WireGuard tunnel.
- In the Persistent Keepalive field, enter 25.
- Click Save at the top.
- All that’s left is to enable our connection and see if it works.
Checking the status of our connection
Now that our remote node is connected, let’s just check on the status in pfSense to make sure everything is working properly.
- From the top menus, select VPN > WireGuard. You’re taken to the WireGuard main settings page.
- Select the Status tab.
- We can see that our tunnel is up and our remote peer is connected.
- To make sure the WireGuard tunnel is using your pfSense WAN as its gateway, you can check your IP online. The IP address displayed should be your WAN IP address.
Congratulations, you’ve successfully configured a road warrior VPN using WireGuard in pfSense. You can now access your home network and any of its resources (servers, databases, other computers) from anywhere. You can also browse the internet through your home connection from anywhere.