[Guide] Setup a wireguard tunnel to VPN provider (multiple VPN tunnel setup)
-
I've been running pfSense with OpenVPN tunnels to VPN providers for years. Now it was time for me to switch to Wireguard. I ran into some really annoying and frustrating situations, especially with the mixed setup of multiple OpenVPN and Wireguard tunnels
Therefore I created this step-by-step guide with my major lessons learnt at the end. Maybe it's useful for some of you.
This guide was created using pfSense 2.7.2-RELEASE and pfSense PLUS 24.11-RELEASE.
My VPN provider is Torguard, but config generators are available with most VPN providers.Preparation
- Remove unused gateways, static routes and gateway groups
- Remove unused interface assignments
- Remove unused firewall rules and unused NAT-rules (especially Outbound rules).
- Make sure that Outbound NAT Mode is set to Manual Outbound NAT rule generation. This is essential in order to ensure that the traffic is ALWAYS routed via the intended routes. If you are not familiar with settings outbound NAT in pfSense, I advice to get familiar before continuing in this guide!
Wireguard Setup
1.) Install the Wireguard package:
Head to System>Package Manager>Available Packages and search for wireguard, click Install to install the wireguard package
2.) Add a tunnel
- Navigate to VPN > WireGuard > Tunnels and click + Add Tunnel
- Check Enable Tunnel
- Enter a Description, like Wireguard_VPN
- Leave Listen Port empty (default)
- Click on Generate
- Click on Save Tunnel and Apply Changes
3.) Generate Wireguard Config
Go to website of the VPN Provider and follow the instructions for generating the wireguard config.
The following steps are for TorGuard, your's might be different:
-
Select VPN tunnel type: Wireguard
-
Select VPN Server Hostname/IP/location: e.g. USA - New York
-
Enter VPN username
-
Copy ONLY the public key generated in Step 2 and leave “Local Private-Key” empty
-
Click Generate Config to get the tunnel config and peer config
-
Navigate to VPN > WireGuard > Peer
-
Click Add Peer
-
For Tunnel select the name of the tunnel created in Step 2
-
Add description like Wireguard Peer #1
-
Uncheck Dynamic Endpoint
-
Enter the information of the generated peer config from Step 3
** For Endpoint enter the Endpoint IP
** Keep Alive: 25
** Public Key: from generated Config output in Step 3,
** Allowed IPs: 0.0.0.0/0 -
Click on Save Peer and Apply Changes
-
Navigate to VPN > WireGuard > Settings
-
Check Enable Wireguard
-
Click Save
4. Verify tunnel
Go to VPN > WireGuard > Status
!! At this point the handshake of the tunnel must be successful. Otherwise the config is not correct !!
5. Interface Assignment
Go to Interfaces > Interface Assignments and click the + Add button beside Available networks ports: tun_wg0. The interface becomes OPT1 (if you have already other interfaces defined, the naming might be slightly different)
-
Click the Save button.
-
Click the OPTx interface name
-
Check Enable interface
-
Change description from OPTx to INT_WIREGUARD
-
IPv4 Configuration Type: static IPv4
-
IPv6 Configuration Type: None (in my case. If you have a IPv6 config, select IPv6)
-
Static IPv4 Configuration:
-- IPv4 Address: enter the IP address from the tunnel config that was generated in Step 3: 10.13.36.105 with the subnetmask 32
-- click on + Add a new gateway
-- In the window: Check Default gateway , Change the Gateway name to TG_WG_GW, Gateway IPv4: this is the SAME ip address entered in the previous window: 10.13.36.105 -
Click on Add
-
Set MSS to 1420
This is a point where I am not really sure about. There are many values mentioned as recommendations. Personally I left the MSS field empty and everything works fine so far. Christian McDonald, the maintainer of the wireguard package for pfSense puts 1420 in one of his videos (pfSense WireGuard Guide Series 001 - Mullvad Failover, time stamp 17:05) -
Click Save and then Apply Changes
6. NAT
- Navigate to Firewall > NAT > Outbound and ensure that Manual Outbound NAT is selected
- Click Add (top) to add a rule for your local network subnet (Source) at the top. In case you have more subnets (sources), you can add a rule for each source or you just create a subnet that big so that all your sources are included.
- Change Interface to INT_WIREGUARD .
- Change Translation > Address to INT_WIREGUARD
- Edit description to mention the VPN, like LAN to Wireguard VPN
- Click the Save button and click the Apply Changes button.
- Disable all other rules containing with WAN in the Interface column. Only keep the rule with source 127.0.0.1. This will ensure that traffic does not leak if the VPN tunnel accidentally goes down.
- In many cases the auto-generated NAT rules (for example, the ones containing port “500 ISAKMP”) can be disabled. Try cleaning up those rules BEFORE you start with this guide
- Click the Apply Changes button.
7. RULES
The goal is now to ensure that the traffic only uses the VPN tunnel and does not leak via the any other interface. Here you have 2 options:
- Option 1: Use the Default Gateway (for example, System > Routing > Default gateway IPv4).
I chose this option as I have multiple interfaces and don’t want to create a rule for each and every one. By setting the default gateway and not working with gateway groups, it is ensured that the traffic only goes through the VPN tunnel (= default gateway). This step is implemented in Step 10 - Option 2: Define rules for every interface (for example, Firewall > Rules > LAN)
** Navigate to Firewall > Rules > LAN, click the Add (top) button and set the following:
** Action: Pass
** Interface: LAN
** Address Family: IPv4
** Protocol: Any
** Source: LAN subnets
** Click Advanced Options > Display Advanced and scroll down to Gateway and set it to the VPN gateway TG_WG_GW
** Click the Save button and click the Apply Changes button.
8. Kill Switch (optional)
The kill switch ensures that no traffic is allowed through any other gateway then the Wireguard tunnel. It is essential that the ‘Block’ rule is below the ‘Allow' rule.
In my case, I did not configure this, as I need certain traffic not going through the Wireguard tunnel.
Navigate to Firewall > Rules > Floating, click on the Add (bottom) button and create the rule to reject all traffic on WAN interface:
- Action: Reject
- Quick: Checked
- Interface: WAN
- Direction: Any
- Address Family: IPv4
- Protocol: Any
- Description: [FL] Reject all WAN traffic
- (I use the [FL] prefix as this indicates a ‘floating rule’ which makes troubleshooting easier)
- Save
- Click on the Add (top) button again and create another rule to allow the traffic from WAN interface to VPN server:
- Action: Pass
- Quick: Checked
- Interface: WAN
- Direction: Any
- Address Family: IPv4
- Protocol: Any
- Destination > Single host or alias > <IP of Wireguard server> (Step 3)
- Description: Allow traffic to VPN server
- Save
- Ensure that ‘Reject’ rule resides below the ‘Allow’ one, otherwise drag it down manually
- Click Save and Apply Changes
9. Static Routing
Navigate to System > Routing > Static Routes
Click the Add button and configure the routes as follows:
Destination network: The IP address of the Wireguard server <IP of VPN server> (Step 3)
Gateway: WAN Gateway
Description: WAN to Wireguard VPN
Click Save
10. Default Gateway
Navigate to System > Routing > Gateways tab and set Default gateway IPv4 to TG_WG_GW
Click Save and Apply changes.If you intend to setup multiple VPN tunnels (for example to different VPN locations), static routing needs to be defined for EVERY VPN tunnel!
!! At this point your Wireguard connection should be working !!
DNS (optional)
11. DNS Server
I recommend to adjust the DNS settings as well. Most VPN provider also provide different DNS server options (no blocking, family filter, etc.)
- Navigate to System > General Setup > DNS and set the DNS Servers > Address to one of the DNS server options provided by your VPN provider
- Set the Gateway to the Wireguard gateway TG_WG_GW
- Uncheck DNS Server Override
- Select Use remote DNS server, ignore local DNS
- Click the Save button.
12. DNS Resolver
- Navigate to Services > DNS Resolver and check Enable
- Have Enable DNSSEC checked.
- Check Enable Forwarding Mode
- Click the Save and Apply Changes
Verification
_
The next step is the most important one! You need to verify that everything is working as expected.13. Check you public IP address:
This can be done in command-line or via a website, for exmaple: IP Chicken
Expected result: <IP of VPN server>from Step 3user@pfsense:~$ curl -4 ifconfig.co 67.213.221.7 user@pfsense:~$
14. Verify correct routing via default gateway
- Open a command-line and start a constant ping and let it run (for example, Google DNS): ping -t 9.9.9.9
- While the ping continues, go to System > Routing and change the Default gateway IPv4 from TG_WG_GW to the WAN interface
- Expected result: the ping has to run into a time-out because all the traffic is only allowed through the Wireguard gateway. If your ping continues, check your firewall rules and NAT Outbound rules
- Switch back from WAN interface to TG_WG_GW
- Expected result: the ping should be resumed
15. Reboot
- Save your pfSense config via Diagnostics > Backup & Restore
- Reboot pfSense to ensure that the config is REALLY working. I had many situations in the past where only a reboot revealed that something was not correctly configured/working.
For example, the wireguard interface did not come up correctly after a reboot (see ‘Troubleshooting’ below)
Troubleshooting / Lessons learnt
As stated in the introduction, I am using a setup with multiple VPN tunnels in a mixed-mode of OpenVPN and Wireguard.
Here I encountered some issues which I'd like to mention here.A. MSS value
The MSS value is still a mystery to me. If your Wireguard tunnel was successfully verified (Step 4), but you cannot ping or DNS is not working, it might be a try to change the MSS value (1380, 1412, 1420 are common values).
B. OpenVPN tunnels:
- Check Don't pull routes and Don't add/remove routes for EVERY OpenVPN tunnel in VPN > OpenVPN > Clients
- Otherwise switching the default gateway is inconsistent and packets are send via other OpenVPN tunnels even if a different default gateway is selected in System > Routing > Gateways. This is especially relevant for Step 14
C. Multiple VPN Gateways
In case you want to setup multiple VPN tunnels, keep in mind:
- For every tunnel a static route (Step 9) is required !
- For every tunnel a NAT Outbound rule (Step 6) is required !
D. Monitoring of Gateways
For monitoring the VPN gateways, I use IPs of public available DNS servers. Of course, I just could use the IP of the VPN endpoint/GW, but by using DNS servers I can ensure that traffic is going beyond the VPN gateway.
Usuals suspects of DNS servers are: 8.8.8.8, 8.8.4.4, 9.9.9.9, 1.1.1.1 (Google, Quad9, Cloudfare).
In order to have a consistent gateway monitoring:- Check Do not add static routes for gateway monitor IP addresses in System > Advanced > Miscellaneous
- Otherwise monitoring VPN Gateways gets very fuzzy und not deterministic, i.e. the gateway selection becomes very vague and inconsistent.
- Gateway monitoring in general can be tricky with the service dpinger
Sometimes dpinger needs to be restarted in order to provide the correct gateway status - especially after rebooting pfSense
Solution:
** Install cron and watchdog
** Add the service wireguard to watchdog
** Add to cron @reboot with the command sleep 45 && /usr/local/sbin/pfSsh.php playback svc restart dpinger
References:
IVPN - pfSense WireGuard Setup Guide/
OpenVPN + WireGuard breaking DNS resolver. [SOLVED]
Is it possible to resolve DNS via WireGuard interfaces?
How to Setup the Latest pfSense Wireguard Client -