So in my last post, I picked up a Qotom Mini-PC to run OPNsense on. After a few months, the device has been running well & I'm very happy with it.
One of the new things I got to try out with OPNsense was Wireguard VPN. I had previously been using something else for VPN connectivity back to my home network - but I heard good things about Wireguard & wanted to give it a try.
So far my experience has been good! I've been pleasantly suprised with how easy it is to configure & get running. In addition, the performance & overall experience has been very positive. The VPN connects quicker than anything I've used in the past, and just simply works without issue.
All that being said - I wanted to put together a quick guide on how to configure Wireguard on OPNsense. Specifically, this configuraion will be for remote-access VPN - where clients will connect to a VPN headend. We'll walk through the OPNsense configuration & a few clients as well. So let's dig in!
Topology
For the purpose of this blog post, we'll be using the lab topology below:
I will be using the reserved IP range 203.0.113.0/24 for the WAN-side addressing. I'll have one Windows & one Android client that we'll walk through & connect to the VPN.
Installing the Wireguard Plugin
To get started, first thing we will want to do is install the Wireguard plugin for OPNsense. By default, OPNsense will have standard IPSec & OpenVPN already available - but other VPN options can be enabled easily.
So in OPNsense, we'll navigate down to System > Firmware > Plugins, then search for wireguard and click the plus icon.
This should pull down the package & install pretty quickly. No reboot required here!
Once installed, you may have to refresh the page or navigate to a new page so that the menu bar has a chance to reload. Then we'll have a new option under VPN:
Wireguard Tunnel Configuration
Next we'll begin configuring Wireguard on the OPNsense side.
There is a little bit of a chicken & egg scenario here since everything is based on cryptographic keys. We'll need to generate keys on the firewall, which we need to enter on the client - but we also need the client keys to enter on the firewall. A bit of bouncing between the two - but for now we'll try to complete as much as we can on the firewall side.
We'll enable Wireguard by dropping down to VPN > WireGuard then clicking Enable and Apply
Next we'll set up the Wireguard tunnel interface on OPNsense. This will be a virtual tunnel interface that will be created as interface wg<instance number>
.
To do this, we'll navigate to the Local tab, and click the plus icon to add a new tunnel.
In the above screenshot, I've filled in just a few details.
For Name, I've entered our virtual interface name wg1
. Since OPNsense shows the Instance as 1
- it will create a wg
interface with that instance number.
We'll leave Public Key & Private Key blank for now. OPNsense will auto-generate these keys once we save this config.
For Listen Port, I've set this to 51820 which is the default for Wireguard. It's not stated here, but this is a UDP tunnel.
For Tunnel Address - this is where we add the IP address of the virtual tunnel interface. This will be the gateway for our remote clients. In my lab I'll be using 10.50.50.1/24 here.
We have no peers configured yet - so we can't select any here. We'll leave this blank for now, but come back later.
We will leave Disable Routes unchecked. By default, OPNsense will add static/connected routes for any client via the tunnel interface. You might not want this behavior if you wanted to do custom routing - for example, in a site-to-site VPN connection - but we'll leave this enabled.
Once we're done, we'll click Save.
Like I mentioned before, OPNsense will now auto-generate our crypto keys for the tunnels. So if we edit our tunnel, we'll now see those fields populated:
We'll want to copy the Public Key & save it for later. This will need to be imported onto our clients, so that they can communicate securely with our firewall.
Wireguard Interface Assignment
Now that we have our headend tunnel interface defined, we can map our wg1
interface to an OPNsense interface. The OPNsense documentation suggests this is optional, but I would recommend it since it will allow us to create firewall rules to permit/deny access to clients.
We'll navigate to Interfaces > Assignments, and we should see a New interface available: our wg1
tunnel.
We can assign this a name, then click the plus icon & Save.
Next we'll enable the interface by navigating to Interfaces > WG1. Here we'll only need to click Enable & save the change - nothing else is necessary.
Of course, we'll be prompted to apply the changes - which we will do:
By default, all traffic through our WG1
firewall interface will be blocked - so please make sure to configure a firewall rule to permit traffic from the Wireguard clients.
Firewall Rules: Allow Inbound Wireguard Traffic
Next we need to permit the Wireguard traffic into our firewall. By default the WAN interface will block all traffic that isn't explicitly allowed - including our Wireguard traffic.
For this, we'll navigate to Firewall > Rules > WAN. Then click the plus icon to add a new rule.
The screenshot above shows what our firewall rule will look like.
Here's the summary:
- Action: Pass
- Interface: WAN
- Direction: In
- TCP/IP Version: IPv4
- You can enable IPv6 as well, if you have IPv6 connectivity (this is a lab box, which does not)
- Protocol: UDP
- Source: Any
- This will allow anyone on the internet to reach our VPN. We could restrict source IP addresses, if our clients had permanent, static IPs.
- Destination: WAN Address
- The firewall itself is the destination for this traffic
- Destination Port Range: (other) / 51820
I also enabled logging & added a quick description. After we have all this configured, we can click Save - then Apply Changes.
Client Setup - Windows
So first we'll start with an easy configuration on a Windows client. Wireguard client software can be found on the Wireguard site here.
For the sake of the walkthrough, we will manually configure each client. However, this can be a difficult task if there is a large number of clients. Wireguard does support importing configurations, and there are a number of free tools available to help automate generating config files for clients - including some which will generate QR codes for easy import on mobile clients.
So on my lab Windows machine, we'll open up the Wireguard client & click Add Empty Tunnel:
Then we'll be given a blank config file, with only the devices public & private key pair generated for us.
We're going to fill in details similar to the below screenshot:
The configuration under [Interface] is the local, client-side configuration. I've added the client's tunnel address - which will be 10.50.50.15/32. I've also configured DNS servers which the client can reach via the VPN.
Then we'll add the [Peer] section, which contains info about our VPN headend. Here's where we'll need the public key from our OPNsense firewall. We'll also specify the Endpoint address, which is the IP or hostname of our VPN headend & the port (which by default is 51820).
We've also configured AllowedIPs as 0.0.0.0/0
. This will force all client traffic over the VPN tunnel - including general internet traffic. However, we could limit this to specific subnets. For example, let's say your network only used 172.16.90.0/24 & 10.1.1.0/16 subnets & we only wanted the user to be able to access those. We would configure the following: AllowedIPs = 172.16.90.0/24, 10.1.1.0/16
. In this case, only traffic for those subnets would be routed over the VPN - any other traffic would use the devices default internet connection.
Now, we'll save this - and again need to copy the device's Public Key, which we'll need to enter on the OPNsense firewall.
Client Setup - Adding Clients to OPNsense
In order for the Windows machine to connect to OPNsense, we'll also need to configure a client profile on the firewall.
In OPNsense, we'll navigate back to VPN > WireGuard, then click on the Endpoints tab.
Here we'll configure a name for our client & paste in the client's Public Key.
We'll also set AllowedIPs to the client's IP address, which we have configured as 10.50.50.15/32
. This controls what IP addresses are reachable via this endpoint.
We do have some additional fields available, which we will leave blank. For example - Endpoint Address & Endpoint Port would be used to define a public IP that we expect our client to connect from. Since a remote-access client could connect from any IP, we leave those fields blank to allow this.
Once we're done, we'll click Save then Apply.
Next we'll jump back to the Local tab, and edit our headend tunnel configuration.
We should now see our windows client in the Peers dropdown. We'll select that client, so that Wireguard will permit that client to connect via this tunnel interface.
Then, as always, click Save & Apply
Last but not least - we should restart our Wireguard server on OPNsense. This can be done by either disabling & re-enabling Wireguard - or by navigating back to the OPNsense dashboard & clicking the restart icon next to the wireguard-go service.
Testing The Connection
Okay - now that we have all that completed, it's finally time to test connectivity from our client.
On my Windows client, I'll just click the Activate button for the tunnel:
And we'll see that the Status shows Active, and we'll start to see updates to the Last Handshake & Transfer fields - indicating we are connected & sending data.
To further validate, we can check the Log tab:
The key things to look for here, are the following messages:
- Receiving handshake response which indicates our firewall responded to our request to connect
- Keypair 1 created which indicates that our connection is healthy to our peer
- Receiving keepalive packet from peer - we should see these periodically to maintain our connection. If keepalives stop flowing, then we may have a break in connectivity between client & peer.
We should also be able to reach out wg1
tunnel address from the Windows client:
On the OPNsense side of things, we can check what client is connected via the List Configuration tab, under VPN > Wireguard:
On this screen, we can see we have 1 peer connected - which matches the IP & public key of our Windows client. We'll see similar output like the Windows client, where we can see the latest handshake & data transfer.
Additionally, for easier access we can add the Wireguard widget to the OPNsense dashboard.
If we navigate to our dashboard, then click Add widget - we can add the Wireguard widget.
Here's what that looks like:
Additional Client Setup - Android
Let's also take a quick look at a mobile client. I'll get through this pretty quickly, since the configuration will be very similar to our other client - just a different UI.
On my Android device - if I open up the Wireguard app, I have a few options for creating or importing a tunnel:
In this case, we'll again walk through creating a tunnel manually. Again, it's worth mentioning that there are 3rd party apps available to auto-generate config imports or QR codes to make this easier.
First we'll have a handful of fields to fill in about the Android-side configuration. This includes a name for the tunnel, an address, and DNS servers.
We can click on the refresh icon in the Private Key field to auto-generate our key pairs:
One of the interesting parts of the mobile app is the ability to permit/exclude individual apps from traversing the VPN tunnel.
Here's a quick screenshot, where we can pick either to allow only certain apps to use the VPN - or permit all except a few we choose to exclude:
In my case, I'll keep this set to allow all applications.
Next we'll work on the peer config:
After that, all we need to do is save our VPN configuration - then we can toggle the tunnel on or off:
And similar to the Windows client, we can click on the tunnel itself to see current status / data transfer:
So it looks like we should be connected & can try accessing VPN resources!
We can also use the same methods as earlier to check connectivity from the OPNsense side.
Okay - that's all I wanted to share today. I've been quite pleased with how easy to use WireGuard has been - and how well it performs! I hope this blog post was helpful if you're interested in trying it out.
Thanks!!