Mullvad VPN on OPNsense using Wireguard
A guide to set up Mullvad VPN service on OPNsense using Wireguard.
Getting Started
Create a public key in OPNsense for the new Wireguard instance. Go to Settings > Wireguard > Instances. Click the plus button. Add a name for the Instance, then click the "gear" icon "generate key pair". Note down the "Public Key" generated for the next step. Click save.
Use the Mullvad API to add your public key and request IPv4 and IPv6 tunnel addresses. For this step, SSH into OPNsense then select "8" for shell.
# This API returns IP addresses which enable routing all DNS queries to Mullad DNS servers. This "Hijacks" DNS queries to prevent leaks.
curl -sSL https://api.mullvad.net/wg/ -d account=YOURACCOUNTNUMBER --data-urlencode pubkey=YOURPUBLICKEY
# This API returns IP addresses which do not "Hijack" DNS. I prefer this option as to have the choice to use Mullvad for DNS.
curl -sSL https://api.mullvad.net/app/v1/wireguard-keys -H "Content-Type: application/json" -H "Authorization: Token YOURACCOUNTNUMBER" -d '{"pubkey":"YOURPUBLICKEY"}'
# Example data returned by Mullvad. Note, your data will be different.
{"id":"uKpxOtipAUHHUM1UmtFkJt1eSk%2Bv0cvHVmtpOqJtsRg%3D","pubkey":"uKpxOtipAUHHUM1UmtFkJt1eSk+v0cvHVmtpOqJtsRg=","ipv4_address":"10.129.207.102/32","ipv6_address":"fc00:bbbb:bbbb:bb01:d:0:1:cf66/128"}
Add returned data from Mullvad to the newly created Wireguard instance in OPNsense.
Go to Settings > Wireguard > Instances. Click the pencil icon to edit your Wireguard instance.
Copy and paste your IPv4 address "10.129.207.102/32" to the Tunnel Address section.
Copy and paste your IPv6 address "fc00:bbbb:bbbb:bb01:d:0:1:cf66/128" to any text editor and change the /128 to /127 so it looks like this:
"fc00:bbbb:bbbb:bb01:d:0:1:cf66/127"
Then, copy and paste your IPv6 address "fc00:bbbb:bbbb:bb01:d:0:1:cf66/127" to the Tunnel Address section.
Assign a listen port - Anything around 51820. I set 51865.
Before completing this step, check the box "Disable routes". Click Save.
Adding a Peer - Mullvad server.
Pick a server from https://mullvad.net/en/servers. I'm partial to DataPacket servers, they tend to have good peering and less CAPTCHA prompts. For this example, I'll use one in Ashburn, VA.
Go to Settings > wireguard > peers > "+"
Under Edit peer:
Add a name for your peer.
Add the public key of the given Mullvad server.
Under "Allowed IPs" for routing IPv4 add: "0.0.0.0/0". For IPv6 add "::/0".
Add the endpoint address of the given Mullvad server.
Add the Wireguard port of the Mullvad server: "51820"
Under instances, select your previously created instance.
Set keepalive interval to: "25".
Save.
Assign an interface in OPNsense
Navigate to Interfaces > Assignments > Assign new interface
Select your newly created wireguard device, click "Add". Then under "Interface" Click "save".
Navigate to the newly created interface under Interfaces > mv-4. Note your interface may be named differently.
Enable interface: check
MSS: "1420". Why? Clamping MSS will reduce packet fragmentation, this increases performance greatly.
Save.
Adding IPv4 and IPv6 gateways.
For IPv4 - The IPv4 gateway is easy. The longstanding method is to subtract 1 number from your IPv4 address supplied by Mullvad. So, "10.129.207.102" will have a gateway of "10.129.207.101".
Under Settings > Gateways > Single > "+"
Name: set any name
Interface: Mullvad interface
Address Family: ipv4
IP Address: "10.129.207.101"
Check "Far Gateway"
Uncheck "Upstream Gateway, Disable Gateway Monitoring, Disable Host Route"
Set monitor IP to a reliable IPv6 host. I'll use cloudflare: "1.1.1.2"
Save.
For IPv6 - Initially, find the 2nd address from your /127 set in the prior Wireguard instance configuration. I use http://www.gestioip.net/cgi-bin/subnet_calculator.cgi
We can see the address for our gateway will be: "fc00:bbbb:bbbb:bb01:000d:0000:0001:cf67"
Under Settings > Gateways > Single > "+"
Name: set any name
Interface: Mullvad interface
Address Family: ipv6
IP Address: "fc00:bbbb:bbbb:bb01:000d:0000:0001:cf67"
Uncheck "Upstream Gateway, Disable Gateway Monitoring, Disable Host Route"
Set monitor IP to a reliable IPv6 host. I'll use cloudflare: "2606:4700:4700::1112
"
Save.
The IPv4 and IPv6 gateways should be ready to go. Under Settings > Gateways > Single. Click "Apply changes".
At this point, both of these gateways should show as online.
Create Outbound NAT rules
Navigate to Firewall > NAT > Outbound
Set NAT mode to "Hybrid"
Create manual IPv4 outbound NAT rule:
Interface: wireguard interface
TCP/IP Version: IPv4
Protocol: any
Source address: Your LAN network
Source port, Destination address, Destination port: any
Translation / target: wireguard interface
Save.
Create manual IPv6 outbound NAT rule:
Interface: wireguard interface
TCP/IP Version: IPv6
Protocol: any
Source address: Your LAN network
Source port, Destination address, Destination port: any
Translation / target: wireguard interface
Save.
Apply Changes.
Add Firewall rules for IPv4 and IPv6 Gateways
Under Firewall > Rules > Your LAN
Modify the "any to any" ipv4 and ipv6 rules to your new wireguard gateways.
Set these two rules to "last match" > Uncheck "Quick / Apply the action immediately on match."
Your rules should look somewhat like this. Note the white lightning bolt.:
The name WireGuard is a registered trademark of Jason A. Donenfeld.