WireGuard is a modern designed VPN that uses the latest cryptography for stronger security, is very lightweight, and is relatively easy to set up (mostly). I say ‘mostly’ because I found setting up WireGuard in OPNsense to be more difficult than I anticipated. The basic setup of the WireGuard VPN itself was not overly difficult, but I did struggle with getting everything working together in the same way that I had my OpenVPN configured.
WireGuard is similar to a SSH server in that devices which have shared their cryptographic keys with each other are able to connect via an encrypted tunnel. The devices that communicate with one another are referred to as “peer” devices. When the peer device is an OPNsense router with WireGuard enabled, for instance, it can be configured to allow further access to various devices/services on your network.
I will refer to the WireGuard installation on OPNsense as the WireGuard server rather than a “peer” to make it more clear which device I am configuring unless I am describing the user interface because that is the terminology used by WireGuard.
Please keep in mind that I am describing how to connect securely to your home network remotely via WireGuard in OPNsense and not how to connect OPNsense to an external WireGuard provider. I imagine many of the same concepts apply but your mileage may vary.
Install the WireGuard VPN Plugin
The first thing that you will need to do is to install the WireGuard plugin in OPNsense because it is not a VPN provider that is natively installed in OPNsense. Go to the “System > Firmware > Plugins” page. Scroll down to the “os-wireguard” plugin and click the install button.
Configure the WireGuard VPN Server
After installing the plugin, let us start configuring the WireGuard VPN Server. Go to the “VPN > WireGuard” page and click the “Local” tab:
Click the “+” button to add a new WireGuard server.
Click the “Enabled” checkbox. Give the server a “Name” of your choice. Leave the “Public Key” and “Private Key” blank as they will be automatically generated when you click “Save”.
The default “Listen Port” is 51820. I like to change it to a non-default port when exposing the port to the world so I am using 51821 in my example to keep it similar to the default port. Using a non-default port generally helps reduce connection attempts and port scanning since many automated scripts/bots scan for the default ports. Changing the default port offers little security benefit.
If you have Unbound DNS set at the default of being applied to all interfaces or you have your WireGuard interface selected as using Unbound DNS, then you can leave the “DNS Server” blank. It will use the WireGuard tunnel address as the DNS server (which in our example will be 10.0.0.1).
If you are using alternate DNS server(s) such as Pi-hole, you will need to specify those DNS servers rather than leaving the box blank. You will meed to create an additional firewall rule to allow access to the alternate DNS server(s) since it will exist on other networks (unless you have an “allow all” rule for your WireGuard clients, which is not the best idea if you have security in mind).
For the “Tunnel Address”, enter a network address such as 10.0.0.1/24. All of the peers/clients connecting to the server should have an IP address that falls in that range. Keep that in mind when you are configuring the user. Important: You should choose an address range that falls outside the range of your other networks. VPNs typically use their own virtual network so it needs to have a different address range. Do not worry – you can still allow access to other parts of your network as though the remote clients are connected locally (see the “(Optional) Add Firewall Rules to Access Internal Networks/Devices” section below).
Leave the “Peers” as “Nothing selected” for now. You will need to come back to this once the user(s)/peer(s) have been configured. Configuring the peers on the server and client to exchange public keys is not the most user friendly process. The WireGuard iOS app supports QR codes so if that gets implemented in the WireGuard plugin in OPNsense, configuring mobile devices would be a lot easier.
Click the “Save” button.
Copy and Send the Server’s Public Key
After saving the WireGuard server configuration, click the edit button (the pencil icon). You will notice that the public and private keys have been automatically generated. In order to set up “peers” (clients/users) that will connect to your OPNsense WireGuard VPN, you will need to send the public key to all of your WireGuard client devices. Emailing the public key may be the easiest way or if you are using a secure file sync application, you could transfer the key via a text file. I transferred my public key via email which is using a TLS/SSL connection.
Important: Only send yourself the public key. You need to keep the private key a secret!
Since the key is a public key, you do not have to worry about keeping the public key as much as a secret as the private key. It is not a bad idea if you still want to keep it secured. Note that someone also needs your private key in order to fully decrypt your communications/data. All bets are off if you lose control of the private key.
Configure the WireGuard Client (iOS Example)
Now that you have the server’s public key available to the client device, you can now set up the client. You will not be able to connect to the WireGuard server until the client endpoint is added, but there is enough information at this time to set up the client. Once the client is set up, you can proceed to add the client information to the server. This helps reduce jumping back and forth between the two devices.
There are a number of devices/operating systems which have WireGuard support, but I am going to use iOS as the example client – mostly because that is what I am using to access my home network remotely. You can find Android and other examples on various blogs, forums, etc. I am using the official WireGuard app on the app store.
When you open the WireGuard app, you will need to click “Create from scratch” since currently the OPNsense WireGuard plugin does not provide a QR code to scan.
Once you click the button you will see the “Edit configuration” screen.
For the “Name” enter a description for the VPN connection. If you have more than one connection, a useful description becomes more important. Click “Generate keypair” to generate a public and private key. For the “Addresses”, enter the static IP address for the user. I am using 10.0.0.2/32. The “/32” is CIDR notation which in this case means you are specifying a single IPv4 address. Use the same “Listen port” that the WireGuard server is using. I am using port 51821.
If you are tunneling all traffic from the client through the WireGuard VPN, you must specify the DNS servers even though it says it is “strongly recommended”. This caused some issues for me until I realized I needed to enter the information (which is stated in the “Step 3 - Setup WireGuard Client” section of the OPNsense documentation).
Click on “Add peer” to open up a new section of configuration on the screen:
The peer device is the OPNsense router with WireGuard installed. You will need to leave the WireGuard app (but do not force close the app and lose your settings!) and open your email client (or file sync app) in order to obtain the public key you sent yourself. Copy and paste the public key into the “Public key” box. If you plan to use a passphrase in addition to the keys, you can enter it in the “Preshared key” box. Be sure to use the same preshared key when you set up the client endpoint in OPNsense.
For the “Endpoint”, you should ideally use a domain name for external access to your home network rather than an IP address. This can be a dynamic DNS domain name like dyn.com or your own custom domain name which have APIs available to allow clients on your network to update the IP address when it changes (see my Dynamic DNS how-to).
The “Allowed IPs” box allows you to enter IPs that should pass through the VPN. If you specify 0.0.0.0/0, that means all network traffic including DNS lookups which is why you have to specify the DNS server in the “DNS servers” box above. Routing all network traffic through the VPN is useful if you want to use public WiFi hotspots, but it is also good if you do not wish to leak DNS lookups from your device. If you are using IPv6, you can specify ::/0 to indicate tunnel all IPv6 traffic in the same way as IPv4.
Do not click “Save” until you complete the next step. It will save you a few clicks.
Copy the WireGuard Client’s Public Key (iOS Example)
Before saving the client configuration, click on the long string of characters beside the “Public key” label. A “copy” dialog box will be displayed. Click “copy”. You will need to enter that key in OPNsense for the client endpoint configuration.
Click “Save” to finish setting up the iOS client.
Important: Before you forget, paste the public key from your WireGuard client in an email or text file in your file sync application. Send the key to your PC or other device which has access to the OPNsense web interface.
Configure the WireGuard Client Endpoint
With the user/client device configured, next up is the client endpoint configuration. Go back to the “VPN > WireGuard” page and click on the “Endpoints” tab.
Click the “Enabled” checkbox and a “Name” for the user. Leave the “Public Key” blank for now. It will be obtained later when you are setting up the client for the user.
A “Shared Secret” may be used if you want another layer of protection in case you happen to lose your private key(s) (but if you lose your shared secret, you are in the same situation as losing your private keys with no preshared key). You need to ensure you use the same preshared key as you entered in your client device.
For the “Allowed IPs” box, enter the user/client’s IP address. This address is a static address associated with the user’s public key.
You may leave the “Endpoint Address” empty unless perhaps you have a more complicated network structure.
The “Endpoint Port” needs to be set the same as the server’s “Listen Port”. You may be able to leave this blank if you are using the default WireGuard port, but since I am using an alternate port in the example it needs to be entered.
Click the “Save” button.
Enable the WireGuard VPN Server
At this point, the WireGuard VPN server can be enabled since the server and one client endpoint has been configured. To enable to the WireGuard server, go to the “General” tab and click “Enable”.
Click the “Save” button.
Add the WireGuard Interface
I found this next step of creating a WireGuard interface necessary via trial and error. A blog post included this step in their instructions. I discovered that the creation of a WireGuard interface is necessary to allow external clients to use the Internet connection of your home network.
If you only need to access your home network but not your home network’s Internet connection, you may be able to skip this step.
To add the WireGuard interface, go to “Interfaces > Assignments”.
Select the “wg0” interface and click the “+” button to add the interface to the list of interfaces. Click the “Save” button to persist the change. It will show up as something like “[OPT1]” or some other number if you already have an “[OPT1]” interface. Now click on the “[OPT1]” interface (or whatever the new interface is called).
Click the “Enable” checkbox and “Prevent interface removal” checkbox. In my example, I renamed the “OPT1” interface to “WG” in the “Description” box so it is easier to remember when looking at the interface and firewall configuration pages. Make sure you do not call it “WireGuard” since a firewall group by the same name is automatically generated when enabling WireGuard. You do not need to enter any other settings.
Add the WAN Firewall Rule
To allow external access to the WireGuard VPN, a WAN rule needs to be created. Go to the “Firewall > Rules > WAN” page.
Choose “Pass” for the “Action” and “UDP” as the “Protocol”. The “Source” should be set to “any” to allow any remote host to connect. You can restrict this if you know you are always connecting from a certain network with static IP address(es) or address range(s). The “Destination” needs to be the “WAN address”, which is your external IP address. For the “Destination port range”, select “(other)” and enter the port number you used when you created the WireGuard VPN service. In my example, I am using port 51821 but if you are using the default port, it should be set to 51820. You may add a useful “Description” such as “Allow remote access to the WireGuard VPN”.
Add the Outbound NAT Rule
In order to for WireGuard clients/users to use the Internet connection of the remote network, an outbound NAT rule has to be created. Most home users will likely want this functionality because they can browse the Internet more securely than using public WiFi. You can take advantage of the privacy and security you have in place on your home network while you are away from home. Like with the creation of the WireGuard interface, this step is likely optional if you do not wish to access your home network’s Internet connection while you are connected to the WireGuard VPN.
If you are using the default “Automatic outbound NAT rule generation” option, you will need to set it to “Hybrid outbound NAT rule generation” or “Manual outbound NAT rule generation”. The hybrid option is likely best for most home users unless you want to take the time to configure all of the necessary outbound NAT rules for other services.
Once you enable the hybrid or manual mode, you will see an “Add” button on the top right corner of the page.
Note: You should see the “WG” WireGuard interface listed in the “Automatic rules” section at the bottom of the page. If you do not see it listed, you may need to reboot your router. It is possible it will show up later when you are applying other various changes to the configuration so a reboot may not always be necessary.
Click the “Add” button to create a new outbound NAT rule.
Ensure that the “Interface” is set to “WAN”. Choose “any” for the “Protocol”. The “Source address” should be your “WireGuard net” which includes all users/clients connected to your WireGuard VPN server. The “Source port” should be set to “any”. The “Destination address” and “Destination port” should both be set to “any” to allow outgoing connections to any address. The “Translation/target” dropdown should be set to “Interface address” to indicate the WAN’s interface – so route any WireGuard network traffic through the WAN interface to your desired destination.
Connect to the WireGuard VPN
The moment of truth… you are finally ready to connect to your WireGuard VPN! Go to your client device and click connect. In OPNsense, go to the “List Configuration” tab on the “VPN > WireGuard” page, and you should be able to see information about the connected user. You will see which peer (by its public key), the IP address of the connected user, how long ago the last connection occurred, and the amount of data transferred.
(Optional) Add Firewall Rules to Access Internal Networks/Devices
At this point, the WireGuard VPN should be configured to allow external connections from client devices such as your phone. The client(s) should be able to have access to your home network’s Internet connection. That may be all you desire if you just want to have a more secure connection to the Internet while you are away from home. However, if you wish to access any devices within your home network, you will need to create additional firewall rules to allow such access. The process of creating such rules is exactly the same as creating rules to allow access between other VLANs in your home network.
If you want to keep the rules simple, you could create an “allow all” rule that will allow the WireGuard users full access to your network, but I imagine you would want to only allow access to specific devices/services on your network. If you already have an IoT or guest network with restrictive firewall rules, for instance, and you may want to simply mimic the same rules for your WireGuard clients. It is easy to clone your rules from other interfaces, but if you clone the rules, you will need to remember to change the source interface for each rule being cloned.
Personally, I like having nearly identical rules applied to my WireGuard interface as the IoT network which my phone is connected to while I am at home. So when I am away from home, I have pretty much the same access to all my services/devices as I do when I am at home. It helps to make the experience of roaming to other networks more seamless.
Since the internal network firewall rules could vary greatly depending on your specific needs, I will leave the creation of such rules to the reader. If you would like some guidance on creating OPNsense firewall rules, I have written about it on another how-to. I have also created a “cheat sheet” list providing several common firewall rule examples.
Important: All of your firewall rules should be applied to the firewall group called “WireGuard” rather than the WireGuard interface that you added unless you are running more than one instance of WireGuard in OPNsense. Also more importantly, you will need at least one rule to provide access to your internal network(s) and/or to the Internet since by default if no rules exists, all traffic is blocked. This could be a gotcha for those new to configuring firewalls. You may have WireGuard configured perfectly but not have access to anything if you forget to add at least one rule to allow WireGuard traffic to other parts of your network or the Internet.
Although my initial attempts to configure WireGuard was a struggle, once I learned how it functions, it is actually easier to configure than a VPN such as OpenVPN. Part of my struggle was the fact I was using Pi-hole in my network and was using DNSCrypt-Proxy which made the DNS configuration more complex. Since the original version of this how-to, I have switched from Pi-hole to Sensei and now use DNS over TLS using the built-in functionality in Unbound DNS rather than DNSCrypt-Proxy. That has helped to simplify my network configuration, and I have fewer places to check when something I want to access gets blocked. I decided after reading user feedback to simplify, restructure, and clarify this how-to so that it is hopefully more accurate and easier to implement a basic WireGuard VPN server in OPNsense. I hope that I have achieved that goal to help minimize headaches with setting up WireGuard in OPNsense!