I just finished setting up a Site-to-Site VPN between 2 OPNsense VMs with WireGuard only passing traffic going to a certain IP range, so I thought I'd share the setup.
I'm no expert, so please do correct me if I'm wrong.
I got most of my knowledge from the OPNsense official site: https://wiki.opnsense.org/manual/how-tos/wireguard-s2s.html
And also from mimugmail's site: https://www.routerperformance.net/opnsense-wireguard-as-a-central-gateway-for-vpn-clients/
Background:I have two sites which both had OPNsense installed in a VM.
I wanted to setup a VPN that would redirect IPv4 traffic from Site B to go out from Site A, but only traffic going to a server that had IP restrictions.
I first had this set up with openVPN, but hearing that WireGuard is much speedier than openVPN, I decided to give this a try.
Site B = Client, Source
Site A = Server, Gateway*The Guide is a little detailed, so sorry if it gets too long
--The following will need to be done for both sites unless otherwise specified--Upgrade OPNsense:First things first, remember to upgrade your OPNsense to the latest version if you already have not done so. It would be difficult to troubleshoot if you are on an older version.
Also, it may be wise to disable all VPN settings between the two sites if you have this set already so that the traffic doesn't get wacky. If you cannot access the other site if the VPN is down, you should open up the HTTPS port or SSH port for GUI/console access "for only your global IP or FQDN" so only people in your site can get in. (Preferably with FQDN/DDNS if you don't have static IP since it may reset anytime) Hope you don't have black-hat hackers in your home network. 8)
Or you can also use a different remote tool to connect to a PC behind the other site's OPNsense.
Change to Development Release:The next step is to change the Release Type from "Production" to "Development" since WireGuard is still experimental.
If you can find the "os-wireguard-devel" under System>Firmware>Plugins, then there's no need to change. It might be that the plugin was transferred over to "Production" when you're reading this.
But at the time of writing (OPNsense 19.1.1 - os-wireguard-devel 0.9), you'll need to change the Release Type under System>Firmware>Settings from "Production" to "Development" and hit "Save".
Run the Upgrade as you normally would do, which should not take more than a minute since OPNsense should be already up to date and only the difference will need to be upgraded.
You shouldn't need to perform a reboot, but that may change later on so if in doubt go ahead and reboot.
Install WireGuard Plugin:After the upgrade is done, go to the "Plugins" tab and find the "os-wireguard-devel" plugin, which should be close to the bottom of the list.
Press the "+" button on the right to install the WireGuard plugin, which should also be done in less than a minute.
Configure Local:After the plugin is installed, you'll need to go to another page or refresh the page in order for the WireGuard menu to show up.
Once the "WireGuard" menu shows up under "VPN", go there and click on the "Local" tab. This was previously named "Servers" tab, so if you find other guides that reference the "Servers" tab it would be the "Local" tab.
Click on the "Add" button on the bottom right, which will get you a "Local Configuration" popup.
What you would need to enter for Site A (Server, Gateway) and Site B (Client, Source) differs.
For Site A (Server, Gateway):
- Enabled: Leave this checked.
- Name: Any name is fine. (ie. Site A)
- Public Key: Leave this blank, it would populate automatically after saving.
- Private Key: Leave this blank, it would populate automatically after saving.
- Listen Port: Leave this as "51820."
- DNS Server: You can leave this blank. (Probably useful for Road Warrior setup)
- Tunnel Address: This would be a made-up-IP-address that is going to be used for the VPN connection only. Any private IP address is fine, but it should be outside other networks that are already existing on both Site A and Site B. (List of Private IP addresses on Wikipedia: https://en.wikipedia.org/wiki/Private_network)
To make things simple, the last digit should be 1 with a subnet of 24. (ie. I used 10.10.10.1/24 since it does not conflict with 192.168.1.0/24 or 10.10.0.0/24 which is my local network) - Peers: You can leave this blank for now.
- Disable Routes: Leave this unchecked. If this setting is checked the system would not automatically add routes for the IP address related to the VPN network, but since we would like all traffics that are coming in to the server routed correctly, we would leave this unchecked.
For Site B (Client, Source): (Same as above except for Name, Tunnel Address and Disable Routes option)
- Enabled: Leave this checked.
- Name: Any name is fine. (ie. Site B)
- Public Key: Leave this blank, it would populate automatically after saving.
- Private Key: Leave this blank, it would populate automatically after saving.
- Listen Port: Leave this as "51820."
- DNS Server: You can leave this blank.
- Tunnel Address: This should be in the same subnet as the Server's Tunnel Address, but not the same IP address.
To make things simple, make the last digit for the second site 2. (ie. 10.10.10.2/24) - Peers: You can leave this blank for now.
- Disable Routes: Unlike the server side, place a check on this since we do not want to route all the local traffic via WireGuard VPN.
After saving the entries, re-open the Local Configuration by clicking on the "Edit" pencil mark on the right of the newly created entry.
It should now show the "Public Key" and the "Private Key", so copy the contents of the "Public Key" for both Site A and Site B. You don't need the "Private Key".
Configure EndpointsNow we can add the endpoints, so go to the "Endpoints" tab.
The values needed here also differs between Site A (Server, Gateway) and Site B (Client, Source).
For Site A (Server, Gateway):
- Enabled: Leave this checked.
- Name: Any name is fine, but for easier understanding enter the name of the Client. (ie. Site B)
- Public Key: Paste the Public Key of the other site, so Site B. (Not Site A)
- Shared Secret: You can leave this blank. (It would add an extra layer of security if you specify a shared secret, but it needs to be in a specific format unlike openVPN)
- Tunnel Address: Enter the Tunnel Address of Site B. The actual configuration file has this named as "Allowed IPs," which means that the traffic coming from the (local) IP specified here would be allowed to pass through. So in this case it would be 10.10.10.2/24 which is the Tunnel Address of Site B.
- Endpoint Address: You can leave this blank. If you have a static IP on Site B and would like to add security, you can specify the Global IP of Site B here.
- Endpoint Port: You can leave this blank. Same as above I believe. (Although I do not know how to set the outgoing port number of WireGuard if I do want to set this up)
- Keepalive: You can leave this blank. (I'm not sure how this would be used)
For Site B (Client, Source):
- Enabled: Leave this checked.
- Name: Any name is fine, but for easier understanding enter the name of the Server. (ie. Site A)
- Public Key: Paste the Public Key of the other site, so Site A. (Not Site B)
- Shared Secret: You can leave this blank, if you entered a shared key for Site A then paste the same contents here.
- Tunnel Address: Enter the local IPs in Site B that are allowed to use the VPN connection. The actual configuration file has this named as "Allowed IPs", which means that the traffic coming from the (local) IP specified here would be allowed to pass through. Since we would like all IPs to be capable of going through the VPN we would set this as 0.0.0.0/0 which would mean all IPs. Or you can specify your local IPs only if you want to be very detailed.
- Endpoint Address: Enter the Global IP of Site A. (Not the local or tunnel IP)
- Endpoint Port: Enter the Port specified in the Local configuration of Site A, which is "51820" if set as default.
- Keepalive: You can leave this blank. However if you've entered a value in the Endpoint entry in the other site, you should enter the same value here.
When done, click on the "Save" button on the bottom of the "Endpoints" tab to update the system with the new endpoint entries.
Now go back to the "Local" tab and click the "Edit" button on the right.
In the "Peers" section, click on the dropdown menu and select the endpoint that we created, and hit "Save."
When done, click on the "Save" button on the bottom of the "Local" tab to update the system with the new local entries.
The WireGuard setting is now complete, so you can go to the "General" tab and check the "Enable WireGuard" option, and then hit "Save."
This will start the WireGuard service.
WireGuard Firewall Rules:We will still need to perform some other setting changes for the VPN to work.
First, we would like to allow all the WireGuard traffic to pass through on both sites, so we'll first add a new rule under Firewall>Rules>WireGuard.
However in my case the "WireGuard" menu was missing from Firewall>Rules. Clicking on a different page didn't help either.
So I went into Firewall>Rules>LAN and clicked on the "Edit" pencil button on the right of the default LAN rule (IPv4/IPv6 doesn't matter which), and then hit "Save" without changing anything.
Then it should show the "WireGuard" menu under Firewall>Rules. I think saving anything in OPNsense triggers this, but just be sure to hit the "Apply" button if this comes up after saving the setting. (Not that leaving this would do something, it's just that the button sticks there until you hit "Apply")
After going into Firewall>Rules>WireGuard, click on the "Add" button on the top right.
You can go ahead and hit the "Save" button without changing anything, and it will create a rule to pass all IPv4 traffic in WireGuard.
If you would like to allow only certain ports to go through the VPN, then I believe you can specify the allowed ports here.
Be sure to hit "Apply" after saving the entry, which will reflect the changes to the system.
The above were all the things that would be needed for both sites.
Now we'll start finishing the Server Site A.
Site A WAN Firewall Rules:We'll need to do two things in Site A: adding a firewall rule for WireGuard on WAN and configuring outbound NAT.
Go to Firewall>Rules>WAN on Site A, and click on "Add" button on the top right.
Change the following fields:
- Protocol: UDP
- Destination: WAN address
- Destination port range: from (other) 51820 to (other) 51820
- Description: Allow WireGuard Access
You can also specify the Source IP address if Site B has Static IP and you'd like the extra security, which I believe would be better than specifying the "Tunnel Address" in the "Endpoints" setting of Site A, since it blocks it before reaching the WireGuard service, but it's up to you.
After entering the above, hit "Save" and then hit "Apply" to reflect the change after coming back to the WAN Rules list.
Site A Outbound NAT Rules:Now go to Firewall>NAT>Outbound.
If the "Mode" setting is set to "Automatic outbound NAT rule generation" which is the default, then click on "Hybrid outbound NAT rule generation" and hit "Save" then "Apply."
If the "Mode" setting is set to "Disable outbound NAT rule generation," then click on "Manual outbound NAT rule generation" and hit "Save" then "Apply."
If you already have the "Mode" set as "Hybrid" or "Manual," then you can leave this as-is.
After the mode is set, click on "Add" button on the top.
Change the "Source address" to "WireGuard net," and click on "Static-port" to place a check there and then hit "Save" and "Apply."
This should be it for the server side (Site A).
Site B WireGuard Interface:Now in Site B, we'll first need to create a virtual interface for WireGuard.
Go to Interfaces>Assignments. which should have your local interfaces listed for Site B.
Next to "New interface," select "wg0" which will be the WireGuard connection name, and click on the "+" button on the right to add the interface.
This would add the interface as "OPT1" or something similar, so click on the new entry that has "wg0" as the Network Port, which will take you to the configuration page of that interface.
Click on "Enable interface" which should display the additional configuration options below.
You don't need to change anything here, but for easier reference you may want to change the name from "OPT1" to say "VPN." The name can be anything you'd like.
Hit "Save" and then "Apply" to reflect the change.
Site B WireGuard Gateway:Now that the interface is set, go to System>Gateways>Single, and click on the "Add" button on the top right.
Enter the following:
- Name: Can be anything, but for easier reference you should include the name of the interface. (ie. VPN_V4)
- Description: Can be anything. (ie. Interface VPN IPv4 Gateway)
- Interface: Select the WireGuard interface. (ie. VPN)
- IP address: Leave as blank or you can also enter "dynamic" without quotes, either way it will end up with "dynamic" after saving.
- Disable Gateway Monitoring: You should leave this checked, since for me unchecking this caused the gateway and VPN to go down.
Hit "Save" and then "Apply" when you're done. We now have a WireGuard gateway set.
Site B Routes:Lastly, we need to specify the routes for traffic going through WireGuard.
Go to System>Routes>Configuration, and then click on "+" button which is on the bottom right.
In the "Edit route" popup,
enter the following:
- Network Address: The subnet for the Tunnel Address of Site A and B. (ie. 10.10.10.0/24)
- Gateway: Specify the WireGuard gateway (ie. VPN)
- Description: This would be for WireGuard virtual network, so enter "WireGuard Subnet"
Hit "Save." This will enable the local network in Site B to ping the virtual adapter in Site A, which is handy for testing and checking VPN connection.
You can then add another route for the server that has the IP restrictions. Just specify the "Gateway" as the WireGuard gateway and enter the Network Address of that server.
You can also add the subnet of the local network in Site A if you want to access this from Site B.
After adding the routes, hit "Apply" to reflect the changes and you should be all set.
You can check if the VPN connection is working by going to Interfaces>Diagnostics>Ping to ping Site A's tunnel address. (ie. 10.10.10.1)
Some troubleshooting tips:First, you can check if the VPN is connected by going to VPN>WireGuard and looking at the "List Configuration" tab. It takes a couple of seconds to show up.
- If you see the "interface" section but no "peer" section, it means that you forgot to specify the "Peer" in the local configuration.
- If you see both the "interface" and "peer" section, but no "last handshake" or "transfer" line, you should check if port 51820 is open on the server side. It may be that while there are no configuration mistakes in the firewall, the modem is blocking the port before it reaches the firewall. You should also check if you entered the Global IP of Site A correctly.
If you can't ping the tunnel address of Site A from Site B, a good thing to do will be to see where the ping is headed to.
Open a new tab in your browser. Have 1 tab open Interfaces>Diagnostics>Ping, and the other tab Firewall>Log Files>Live View, both for Site B.
In "Live View" tab, enter the IP address that you are pinging in the "filter" field. (ie. 10.10.10.1)
This should now show only the logs including Site A's tunnel address, so now in the "Ping" tab enter Site A's tunnel address and start the ping.
If you go back to the "Live View" tab, you should now see which interface the ping is headed towards.
- If the list is still blank, first check if you're in the correct site. Check the ping tab too.
- If the list shows the pings, but displays the interface as WAN, most likely the routes have not been set correctly.
- If the list shows the pings with the WireGuard interface, but shows as blocked by firewall, then check if you have set "and applied" your firewall rules for WireGuard.
- If the list shows the pings with the WireGuard interface with a green background, then it means that the pings have correctly went out from Site B.
For the last scenario, you'll need to then check the logs from Site A. Open a new "Live View" tab for Site A and initiate the pings again from Site B.
- If the list is still blank, check if you're opening the correct site. (If you have more than two sites)
- If the list shows the pings, but shows as blocked by firewall, then check if you have set "and applied" your firewall rules for WireGuard.
- If the list shows the pings with a green background, then it means that the pings have correctly reached Site A.
If everything looks good on both sides but you still can't get a ping response, this would mean that the pings correctly went through WireGuard VPN, but wasn't able to go back to Site B.
In this case it might be that there is a NAT problem somewhere, so you may need to set the Outbound NAT similarly for Site B also.
The only difference between Site A and Site B for Outbound NAT configuration will be to change the "Interface" for outbound NAT rule to the WireGuard Interface (ie. VPN) and not WAN. The other procedure should be the same.
Results:For my setup, the ping responses went down from 180 ms on openVPN to 160 ms on WireGuard, which I think is quite good. (The two firewalls are about 6,300 miles away, hence the response times)
I had trouble setting this up since there weren't much examples around, but I believe once I get more acquainted with WireGuard I think this would be much easier than setting up openVPN.
Hope this example helps someone. And again please do let me know if I'm doing something wrong or if something needs to be corrected.
Best wishes,
Sure! You can even copy/paste/modify this on your site if that would be better.
Glad to know that you liked this. :)
@walshen big thank you for this.
i managed to get this set up however everything is connect but the ping is not leaving Site A to B and the otherway arround.
on the liveview on both sides its shows green with default green rules let out anything from firewall host itself
i cannot seem to find what i have done wrong ? services has been rebooted, firewalls booted twice but nothing happens
those are the results of the ping from the interface.
# /sbin/ping -c '10' '100.64.0.14'
PING 100.64.0.14 (100.64.0.14): 56 data bytes
36 bytes from 100.64.0.10: Time to live exceeded
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 0054 46d3 0 0000 01 01 aa3e 100.64.0.10 100.64.0.14
36 bytes from 100.64.0.10: Time to live exceeded
Vr HL TOS Len ID Flg off TTL Pro cks Src Dst
4 5 00 0054 05da 0 0000 01 01 eb37 100.64.0.10 100.64.0.14
Thank you for the great tutorial.
TTL exceeded would mean a routing loop, can you check routes on both sides?
I am having issues with adding site B gateway. When I leave blank or put "dynamic" in the IP address it fails to add a gateway by that I mean it's just not on the list of gateways.
(https://cloud.thacher.pw/index.php/s/szHb4fHwLwjrLc7/preview) So I upgraded to 19.7.3 went to interfaces to see if I could add the WG interface now. I was greeted with the two that I tried to make before the upgrade. I can delete the WG_VPN one, but I can't delete or enable the WG interface.
Thanks for the walkthrough and of course the great work on the wireguard plugin guys! It works great.
There are two things I haven't managed to solve yet though:
- administration of the remote firewall through the vpn
- setting up unbound to use the remote site's dns server as a forward-zone.
Both come down to the fact that the auto created Wireguard interface does not show up in the interfaces list in most of the firewall's GUI. Do you guys know a way to overcome this? Maybe by editing the config files from CLI?
Thanks a bunch and keep up the great work! :)
Just assign the interface like stated in most of the docs, then it gets listed :)
yes, please call it different than wireguard. no ip, enable lock, then restart your wireguard config and you are good.
Thank you. Did that and will test it from home (the remote site) :) in the evening.
What happens when you connect to the LAN IP of the Firewall via the tunnel?
It times out. (Same behaviour as when i try to access it from an interface not added to the access list.)
There you go.
edit: [images removed]
These screenshots are from the OPN as your central server or your client?
These are the config screenshots from one of the two sites. They have symmetrical configurations, so there is no server/client relationship, it's more like two identical peers connecting/sharing the networks behind them.
The only difference is that this (shown site) has the tunnel IP of 10.1.1.1 and the network behind is 10.10.0.0/16, while the other site's tunnel address is 10.1.1.2 and is on the network 10.20.0.0/16. (There is an extra entry - 10.1.1.10 for mobile access, but that does not work yet for some reason... probably to do with android. So is irrelevant for now.)
Greetings....
It is fantastic you went to the trouble to detail this. The instructions on the opnsense doc site are very inadequate. Hopefully they will allow somebody to flesh it out more completely soon.
I was going to ask if you would consider updating the docs, since it is no longer dev, but part of the latest update. :)
I must be doing something wrong, because I'm not seeing an Wireguard wg0 to add. Still fooling around to figure out why not.
later: I figured it out. Wireguard services were not starting. The only way to get the service to fire up, was to disable the endpoint. I suspect it might be the chicken or the egg thing. No rules were set up in the firewall, so I'm thinking the endpoint would abend the service. But once the service is running, then I can assign wg0. Maybe someone else will be helped by this.
EDIT: Later... we have gotten the tunnel established.... But we must be missing routing or rules because we can't go any farther. This is harder to setup than openvpn and it shouldn't be. There are several sites all giving different instructions.. so who to follow. gah!