How to configure VPN on OPNSense with WireGuard VPN protocol
By: Miha Kralj
Tags: Firewall, Wireguard, Opnsense, Networking, VPN

I am using WireGuard protocol to establish a VPN into my household for a while now — but setting it up was a tinkering ordeal of trial and error. Why WireGuard, you ask? Because reasons. I will not wax poetically why WireGuard is superior to IPSec or OpenVPN — go elsewhere to find that out. This here is just a simple installation guide that — I hope — will reduce some of the frustration and shorten the troubleshooting time of making WireGuard work on OPNSense firewall.

1. Installing the WireGuard plugin on OPNSense

WireGuard on OPNSense is an installable plugin that you will find under System ➡️ Firmware ➡️ Plugins , named os-wireguard (or os-wireguard-devel if you are brave). You can install it by clicking the little ➕ sign next to its name.

2. Adding the local endpoint

After installation of the plugin, a new WireGuard configuration panel should appear under VPN ➡️ WireGuard (If it doesn’t, do a quick F5 refresh of the page). WG configuration has five panels: General , Local , Endpoints , L ist Configuration , and Handshakes . The first three are actual configuration panels, the last two are just status and control screens.

General panel

Keep the WireGuard disabled for now. Don’t be tempted. There is too much to configure before you can click that enabling checkbox. Just… Don’t. 😊

Local panel

Create a new local endpoint here by clicking ➕ on the right side of the screen and filling the form:

+ — — — — — — — -+ — — — — — — — +

| SETTING | CONFIGURATION |

| Name | WGServer | Choose any name

| Public Key | Leave blank | Will be auto-generated

| Private Key | Leave blank | Will be auto-generated

| Listen Port | 51820 | Default port for WireGuard

| DNS Server | <OPNSense_IP> | IP of your fastest/closest DNS

| Tunnel Address | 10.10.10.1/24 | IP of OPNSense on this tunnel

| Peers | Leave blank |

| Disable Routes | Leave blank |

+ — — — — — — — -+ — — — — — — — +

After you hit Save, edit the same form by clicking the ✏️ on the right, and you will now see both private and public keys of your WG server populated in the fields.

Important: copy both Public and Private Key and paste them into a new text file named wireguard.keys . Add some identifiers in front of each key, so we remember which is which. We will use these public/private key pairs to configure our client.conf file for WireGuard peers using our VPN server.

3. Generating public/private key pairs

Here is a trick that will make the configuration of WireGuard VPN clients so much easier: we will pre-generate private and public keys for our remote clients, so they don’t have to. That way, there will be less hassle with a key exchange between peers.

So, let us generate another Local endpoint (by clicking ➕ in the first WireGuard panel):

+ — — — — — — — -+ — — — — — — — +

| SETTING | CONFIGURATION |

| Enable | unchecked |

| Name | Dummy | We will delete it anyway

| Public Key | Leave blank | Will be auto-generated

| Private Key | Leave blank | Will be auto-generated

| Listen Port | Leave blank |

| DNS Server | Leave blank |

| Tunnel Address | 1.2.3.4/32 | dummy address (cannot be blank)

| Peers | Leave blank |

| Disable Routes | Leave blank |

+ — — — — — — — -+ — — — — — — — +

Click Save, then re-open the form. We just created ourselves a SECOND public/private key pair, but we will not use it for our local node; we will use them to configure our remote peer nodes. Copy and label each private/public key into the wireguard.keys file.

Close the form and delete this dummy Local WG entry from the list of Local endpoints — you should now have only one entry, generated at step 2.

While we are at it, let’s go and generate yet ANOTHER key pair as described above! But this time, when you re-open the saved dummy entry, grab only one key (public or private, doesn’t matter), and add it to the wireguard.keys file and label it “Secret”. We will use this as a pre-shared key for strengthening security.

Grab the Secret key, close the form and delete this dummy entry. You should still have just one Local entry, but you should have two pairs of keys plus a Secret in your wireguard.keys file.

4. Adding a WireGuard remote endpoint

Now we are ready to add a remote peer by selecting the Endpoints panel and clicking ➕ to add a new Endpoint:

+ — — — — — — — — + — — — — — — — +

| SETTING | CONFIGURATION |

| Enabled | checked |

| Name | myMac | Name of remote VPN peer

| Public Key | <Public2> | paste from wireguard.keys

| Shared Secret | <Secret> | paste from wireguard.keys

| Allowed IPs | 10.10.10.0/24 | IP range of allowed peer IPs

| Endpoint Address| Leave blank |

| Endpoint Port | Leave blank |

| Keepalive | Leave blank |

+ — — — — — — — — + — — — — — — — +

Click save, head back to the Local panel, and edit your WireGuard server entry there again. (You did delete all dummy entries that you used to generate key pairs, right? There is only one entry on the Local panel page, right?)

At the bottom of the form, there is a field Peers . Add your just-created remote endpoint to the list of allowed peers and click Save.

Head to the General tab and — finally — enable WireGuard. It won’t work yet, but we are done with configuration here, and we don’t need to come back to the WireGuard configuration panels.

Before we continue, let us check that WireGuard service is up and alive. Go to System ➡️ Diagnostics ➡️ Services and scroll to the bottom of the services list. The service wireguard-go should be up and running, not stopped. We need it running before we proceed to the next step.

5. Adding a WireGuard interface

Time to add WireGuard as an interface on OPNSense router and allow bits to flow! Head to Interfaces ➡️ Assignments and find the (unassigned) wg0 network port under New Interface . Give it a cool description (such as VPN0 ) and Press a big fat ➕ next to it.

Click on the new WireGuard interface name ( VPN0 ) and make sure it is enabled.

6. Firewall and the WireGuard

Now that we have WireGuard interface created, we want our firewall to accept the incoming traffic on WireGuard port.

Head to Firewall ➡️ NAT ➡️ Port Forward and add a new entry:

+ — — — — — — — — — +

| CONFIGURATION |

| Disabled | unchecked

| Interface | WAN

| TCP/IP version | IPv4

| Protocol | UDP

| Destination | WAN address

| Dest port range | from: other-51820 to: other-51820

| Redirect target IP| Single host - 10.10.10.1

+ — — — — — — — — — +

All other settings keep as they are. Click Save at the bottom of the form.

The outbound NAT also requires some tweaking. Head to Firewall ➡️ NAT ➡️ Outbound and set outbound NAT mode to Hybrid . Also, generate a new manual rule by clicking Add at the top right of the screen:

+ — — — — — — — — — +

| CONFIGURATION |

| Disabled | unchecked

| Do not NAT | unchecked

| Interface | WAN

| TCP/IP version | IPv4

| Protocol | UDP

| Source address | WireGuard net

+ — — — — — — — — — +

All other settings keep as they are. Click Save at the bottom of the form.

Now let us add a Firewall rule to let the traffic flow from WireGuard interface into OPNSense and beyond. Head to Firewall ➡️ Rules ➡️ Wireguard . Create a new allow-all firewall rule by clicking Add at the top right of the screen:

+ — — — — — — — — — +

| CONFIGURATION |

| Action | Pass

| Disabled | unchecked

| Quick | checked

| interface | WireGuard

| Direction | in

| TCP/IP Version | IPv4

| Protocol | any

| Source | WireGuard net

+ — — — — — — — — —

All other settings keep as they are. Click Save at the bottom of the form.

7. Making Unbound listen to WireGuard interface