VPN with WireGuard on OPNSense

Image for post
Image for post

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.

Image for post
Image for post

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, List Configuration, and Handshakes. The first three are actual configuration panels, the last two are just status and control screens.

Image for post
Image for post

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. 😊

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

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.

Image for post
Image for post

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.

Image for post
Image for post

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):

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.

Image for post
Image for post

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.

Image for post
Image for post

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:

Image for post
Image for post

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.

Image for post
Image for post

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.

Image for post
Image for post

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

Image for post
Image for post

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:

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

Image for post
Image for post

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:

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

Image for post
Image for post

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:

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

Image for post
Image for post

7. Making Unbound listen to WireGuard interface

If you want to use the local Unbound DNS server on OPNSense to resolve requests from WireGuard clients, we need to enable that interface on Unbound configuration page. Go to Services ➡️ Unbound DNS ➡️ General and edit the field Network Interfaces. You need to add your WireGuard VPN0 as a listening interface:

Image for post
Image for post

8. Creating a configuration file for WireGuard client

Now that we have the server-side configured, what do we need on the client-side? WireGuard client configuration is a simple text file, and all we need to do is stitch together all bits of config information.

In your favorite text editor, create a new wg-client.conf file and populate it as follows:

Image for post
Image for post

9. Configuring WireGuard client on Mac/Windows/Android

This step is trivial, now that we have generated wg-client.conf :

- Deliver wg-client.conf to your target device
- install WireGuard client
- Import the wg-client.conf into WireGuard client
- Activate the WireGuard VPN tunnel
- enjoy the flow of bits towards your OPNSense

Once the WireGuard VPN tunnel is working, my recommendation is to erase the wireguard.keys file permanently. It holds all the keys to your WireGuard. Literally.

A cloud computing nerd, an expert in IT paleontology, purveyor of all geeky things. A very “ethical” advisor who is the first in line for any free food or swag.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store