OPNsense Forum

English Forums => Tutorials and FAQs => Topic started by: Greelan on January 31, 2021, 12:32:41 am

Title: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on January 31, 2021, 12:32:41 am
UPDATE: This tutorial has now been included in the official OPNsense documentation (https://docs.opnsense.org/manual/how-tos/wireguard-selective-routing.html). Please submit any updates or improvements there (via GitHub).

UPDATE #2 28 March 2021: This tutorial has been updated to remove reference to including the VPN provider’s DNS servers in the Local configuration, as this can break DNS resolution on OPNsense itself. Also, if your network generally uses local DNS servers, you will likely experience DNS leaks unless you take further steps. Suggested solutions are proposed to be added to the official OPNsense documentation.


This tutorial is designed to assist with setting up WireGuard on OPNsense to connect only limited (not all) local hosts to an external VPN provider.

These circumstances may apply where only certain local hosts are intended to use the VPN tunnel. Or it could apply where multiple connections to the VPN provider are desired, with each connection intended to be used by different specific local hosts.

This tutorial draws heavily on the great work of @Jonny, in particular as shown here: https://m.imgur.com/gallery/JBf2RF6

This tutorial focuses on the configuration of OPNsense. You will also have to configure the peer at your VPN provider - consult your VPN provider’s documentation as to how to do that.

Your OPNsense local public key will need to be registered with your VPN provider, and you will need to get your VPN provider’s endpoint public key and the VPN tunnel IP provided for your local peer by your VPN provider. In some cases, you will not be able to get the endpoint public key and VPN tunnel IP until you register your local public key. In that case, create the OPNsense local configuration first, using a dummy tunnel IP and no peer selected, so that the public key is generated, and then update the configuration later once the other information is known.

This tutorial discusses IPv4 configuration only. It can be readily adapted for IPv6 as well.

Configure the endpoint

Go to VPN -> WireGuard -> Endpoints
Click + to add a new Endpoint
Configure the Endpoint as follows (if an option is not mentioned below, leave it as the default):

   Enabled: Checked
   Name: Call it whatever you want (eg VPNProviderName_Location)
   Public Key: Insert the public key from your VPN provider
   Allowed IPs: 0.0.0.0/0
   Endpoint Address: Insert the public IP address (desirably) or domain name of your VPN provider, as provided by it
   Endpoint Port: Insert the port of your VPN provider, as provided by it
   Keepalive: 25

Save the Endpoint configuration, and then click Save again

Configure the local peer

Go to VPN -> WireGuard -> Local
Click + to add a new Local configuration
Turn on “advanced mode"
Configure the Local configuration as follows (if an option is not mentioned below, leave it as the default):

   Enabled: Checked
   Name: Call it whatever you want (eg VPNProviderName)
   Public Key: This will initially be blank; it will be populated once the configuration is saved
   Private Key: This will initially be blank; it will be populated once the configuration is saved
   Listen Port: 51820 or a higher numbered unique port
   DNS Server: Leave this blank
   Tunnel Address: Insert the VPN tunnel IP provided by your VPN provider, in CIDR format, eg 10.24.24.10/32
   Peers: In the dropdown, select the Endpoint you configured above
   Disable Routes: Checked
   Gateway: Specify an IP that is 1 number below your VPN tunnel IP, eg 10.24.24.9. Note that the IP you choose is essentially arbitrary; pretty much any unique IP will do. The suggestion here is for convenience and to avoid conflicts

Save the local peer configuration, and then click Save again

Turn on WireGuard

Turn on WireGuard under VPN -> WireGuard -> General if it is not already on

Assign an interface to WireGuard and enable it

Go to Interfaces -> Assignments
In the dropdown next to “New interface:”, select the WireGuard device (wg0 if this is your first one)
Add a description (eg WAN_VPNProviderName)
Click + to add it, then click Save

Then select your new interface under the Interfaces menu
Configure it as follows (if an option is not mentioned below, leave it as the default):

   Enable: Checked
   Lock: Checked if you wish to
   Description: Same as under Assignments, if this box is not already populated
   IPv4 Configuration Type: None
   IPv6 Configuration Type: None

Save the interface configuration and then click Apply changes

Restart WireGuard

Now restart WireGuard - you can do this from the Dashboard (if you have the services widget) or by turning it off and on under VPN -> WireGuard -> General

Create a gateway

Go to System -> Gateways -> Single
Click Add
Configure the gateway as follows (if an option is not mentioned below, leave it as the default):

   Name: Call it whatever you want, easiest to name it the same as the interface
   Description: Add one if you wish to   
   Interface: Select your newly created interface in the dropdown
   Address Family: Select IPv4 in the dropdown
   IP address: Insert the gateway IP that you configured under the WireGuard local peer configuration
   Far Gateway: Checked
   Monitor IP: Insert an external IP to monitor the gateway, such as 1.1.1.1 or 8.8.8.8

Save the gateway configuration and then click Apply changes

Create an Alias for the relevant local hosts that will access the tunnel

Go to Firewall -> Aliases
Click + to add a new Alias
Configure the Alias as follows (if an option is not mentioned below, leave it as the default):

   Enabled: Checked
   Name: Call it whatever your want, eg WG_VPN_Hosts
   Type: Select either Host(s) or Network(s) in the dropdown, depending on whether you want specific host IPs to use the tunnel, or an entire local network (such as a VLAN)
   Content: Enter the host IPs, or the network in CIDR format
   Description: Add one if you wish to

Save the Alias, and then click Apply

Create a firewall rule

This will involve two steps - first creating a second Alias for all local (private) networks, and then creating the firewall rule itself. The ultimate effect of these two steps is that only traffic from the relevant hosts that is destined for non-local destinations will be sent down the tunnel. This will ensure that the relevant hosts can still access local resources

First go to Firewall -> Aliases
Click + to add a new Alias
Configure the Alias as follows (if an option is not mentioned below, leave it as the default):

   Enabled: Checked
   Name: RFC1918_Networks
   Type: Select Network(s) in the dropdown
   Content: 192.168.0.0/16 10.0.0.0/8 172.16.0.0/12
   Description: All local (RFC1918) networks

Save the Alias, and then click Apply

Then go to Firewall -> Rules -> [Name of the interface for the network in which the hosts/network resides, eg LAN for LAN hosts]
Click Add to add a new rule
Configure the rule as follows (if an option is not mentioned below, leave it as the default):

   Action: Pass
   Quick: Checked
   Interface: Whatever interface you are configuring the rule on
   Direction: in
   TCP/IP Version: IPv4
   Protocol: any
   Source / Invert: Unchecked
   Source: Select the relevant hosts Alias you created above in the dropdown (eg WG_VPN_Hosts)
   Destination / Invert: Checked
   Destination: Select the RFC1918_Networks Alias you created above in the dropdown
   Destination port range: any
   Description: Add one if you wish to   
   Gateway: Select the gateway you created above (eg WAN_VPNProviderName)

Save the rule, and then click Apply Changes

Then make sure that the new rule is above any other rule on the interface that would otherwise interfere with its operation. For example, you want your new rule to be above the “Default allow LAN to any rule”

Create an outbound NAT rule

Go to Firewall -> NAT -> Outbound
Select "Hybrid outbound NAT rule generation” if it is not already selected, and click Save and then Apply changes
Click Add to add a new rule
Configure the rule as follows (if an option is not mentioned below, leave it as the default):

   Interface: Select the interface for your WireGuard VPN (eg WAN_VPNProviderName)
   TCP/IP Version: IPv4
   Protocol: any
   Source invert: Unchecked
   Source address: Select the Alias for the hosts/networks that are intended to use the tunnel (eg WG_VPN_Hosts)
   Source port: any
   Destination invert: Unchecked
   Destination address: any
   Destination port: any
   Translation / target: Interface address
   Description: Add one if you wish to

Save then rule, and then click Apply changes

You should now be done!

Note that @Jonny’s tutorial (linked above) also include instructions for the optional step of adding a kill switch - so that if the VPN tunnel is down, the relevant hosts will be blocked from using your normal WAN
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: FingerlessGloves on February 20, 2021, 01:04:33 am
Great guide best one I've seen yet for WireGuard VPN Providers! I have one recommendation on the firewall rule.

Create a Second ALIAS called RFC1918, and put RFC1918 networks (192.168.0.0/16.10.0.0.0/8,172.16.0.0/12) in it. Then use it in the Firewall rule Destination

Create a firewall rule

   Destination / Invert: Checked
   Destination: RFC1918
   Destination port range: any

This will make it so only internet traffic will go over the VPN, making any other local traffic not be interfered with by the VPN gateway, this can then be blocked or allowed by any rules after it.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on February 20, 2021, 01:41:32 am
Thanks. At the bottom of the firewall rule section, I did already include a note in italics to that effect :)
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: FingerlessGloves on February 20, 2021, 01:44:39 am
Thanks. At the bottom of the firewall rule section, I did already include a note in italics to that effect :)

I did read that bit but this negates the need, but only a suggestion.

Ideally you should use the same idea for the invert destination of RFC1918 for your normal WAN rule too. So it saves you having to create block rules for internal networks, just allow internet only by default then put the cross network allow rules in :-). Easiest way to lock down the rules.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on February 20, 2021, 01:54:54 am
That’s fair. It is probably the main use case, so I will update the firewall rule section to exclude local IPs by default

I will leave out the WAN side of things as that’s really out of scope for this tutorial
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: FingerlessGloves on February 20, 2021, 01:57:16 am
That’s fair. It is probably the main use case, so I will update the firewall rule section to exclude local IPs by default

I will leave out the WAN side of things as that’s really out of scope for this tutorial

Yeah that makes sense 🙂
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on February 20, 2021, 02:29:45 am
So I have now updated the firewall section. I have left the outbound NAT section as is - although on its face it has a broader operation than the firewall rule, I figured that if the firewall rule is not sending local traffic through the WG gateway then the outbound NAT rule for the WG interface won't impact it. Let me know if you disagree. Thanks again for the input
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: FingerlessGloves on February 20, 2021, 02:31:03 am
So I have now updated the firewall section. I have left the outbound NAT section as is - although on its face it has a broader operation than the firewall rule, I figured that if the firewall rule is not sending local traffic through the WG gateway then the outbound NAT rule for the WG interface won't impact it. Let me know if you disagree. Thanks again for the input

Looks good 😊
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: TheChickenMan on March 01, 2021, 09:17:15 pm
I'm not sure how much of what I was having trouble with was due to actual "wireguard issues" vs the manual gateway configuration process but either way this was finally the tutorial that I needed to really understand what was going on.


This should really be cleaned up and added as one of the official VPN walkthroughs in the manual.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 03, 2021, 04:31:36 am
This should really be cleaned up and added as one of the official VPN walkthroughs in the manual.
Not sure what "clean ups" you had in mind, but a PR has now been submitted for this tutorial to be added as a how-to in the OPNsense documentation: https://github.com/opnsense/docs/pull/317
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: TheChickenMan on March 06, 2021, 11:07:53 pm
This should really be cleaned up and added as one of the official VPN walkthroughs in the manual.
Not sure what "clean ups" you had in mind, but a PR has now been submitted for this tutorial to be added as a how-to in the OPNsense documentation: https://github.com/opnsense/docs/pull/317 (https://github.com/opnsense/docs/pull/317)


Oh sorry I just meant added to the official documentation page and not that there was anything wrong with the content. I appreciated the info very much and helped to get my Wireguard working.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: djronh1 on March 13, 2021, 05:13:50 pm
Any idea how to do this same thing, but only route via VPN based on specific
 destinations?

For example I want PC1, PC2, PC3 to use VPN only when trying to access YouTube.com, but all other traffic from these systems (that is NOT going to YouTube.com) would go out the regular WAN interface.

I created a hosts alias for both group of PCs (PC1, PC2, & PC3), and another host alias for destinations that should be routed via VPN (e.g. UseVPN alias has YouTube.com, Amazon.com, google.com).

I setup rule same as listed in main post, but instead of !RFC, I have UseVPN as destination... but this is not working. All traffic continues to go out WAN interface. But works fine when I revert back to !RFC
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: FingerlessGloves on March 13, 2021, 06:00:50 pm
I created a hosts alias for both group of PCs (PC1, PC2, & PC3), and another host alias for destinations that should be routed via VPN (e.g. UseVPN alias has YouTube.com, Amazon.com, google.com).

I setup rule same as listed in main post, but instead of !RFC, I have UseVPN as destination... but this is not working. All traffic continues to go out WAN interface. But works fine when I revert back to !RFC

because your only looking at the hosts in the main URL of the webpage, when you load youtube.com you make many other requests to domains other than youtube.com

If you press F12 on a blank tab, click the network tab on the newly popped up window. Then browse to youtube, you will see other domains other than youtube.com being loaded. For example "i.ytimg.com".
Trying to VPN certain websites via their base url domain, isn't always possible, when they use a CDN or a CDN of their own, because usually many other domains get used.

One way around it is to VPN the IP blocks that YouTube uses, but even this isn't always a fool proof way.
So you could get an IP for youtube.com which for me is "216.58.210.206", then lookup what ASN the IP is apart of which is AS15169, then get all the IPs owned by this ASN number. Which is a lot of ranges, because its Google's ASN, so any traffic going to Google, in these ranges would get VPN'd.

https://traceroute-online.com/ip-asn-lookup/

What your trying to do if not easy...
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: djronh1 on March 13, 2021, 06:05:46 pm
I'm only using YouTube.com as an example .... the destinations I'm trying to force thru VPN are simple websites that resolve to a single IP.

I was able to setup rules easily on my old Asus router (via AsusWrt-Merlin firmware).

So I'm hoping that achieving same thing with OPNSesne should be doable.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: FingerlessGloves on March 13, 2021, 06:20:19 pm
I'm only using YouTube.com as an example .... the destinations I'm trying to force thru VPN are simple websites that resolve to a single IP.

I was able to setup rules easily on my old Asus router (via AsusWrt-Merlin firmware).

So I'm hoping that achieving same thing with OPNSesne should be doable.

Oh then if they're simple websites, this is very doable.

Have you made sure your SitesToVPn rule is above your rule that allows traffic to the internet?
Also you need to make sure the Outbound NAT rule is there.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: djronh1 on March 13, 2021, 06:25:20 pm

Oh then if they're simple websites, this is very doable.

Have you made sure your SitesToVPn rule is above your rule that allows traffic to the internet?
Also you need to make sure the Outbound NAT rule is there.

Yes, I've made sure SitesToVpn rule is the first (top) rule for my LAN interface.
And I also had created my Outbound NAT rule per OP instructions.

Everything works fine when I use !RFC, but when I swap that out with alias of websites I'm trying to use (and undo the Inverse match), then traffic does not use VPN.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: FingerlessGloves on March 13, 2021, 10:47:07 pm
Ah ok :-)

Go to "Firewall: Diagnostics: pfTables" and select your alias from the drop down, is it populated with the IPs you expect?
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: djronh1 on March 13, 2021, 10:57:32 pm
Yes, pTables does have IP resolved for FQDN I had set
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: FingerlessGloves on March 13, 2021, 11:04:17 pm
Yes, pTables does have IP resolved for FQDN I had set

Screenshot us your rule then, cause it sounds like it should be working.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: djronh1 on March 14, 2021, 03:51:43 pm
Here is screenshot
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: djronh1 on March 18, 2021, 09:50:31 pm
BUMP
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 19, 2021, 12:24:12 am
I think you have people stumped as to why it is not working. Maybe open a new thread rather than continuing in this tutorial thread - you might get a wider audience
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: CactusFractal on March 24, 2021, 05:31:42 am
Hi Greelan and Fingerlessgloves,

Thank you both so much for working on this Wireguard selective routing guide, and very glad it got added to official OPNSense documentation.

I have been banging my head trying to figure out why I am leaking my ISP DNS after implementing your guide exactly as suggested twice from a bone-stock OPNSense configuration.

How can we route DNS traffic through the VPN without leaking DNS when using your guide?  I took the following steps based on a redditor's suggestions, but nothing has worked so far:

Quote
OK, reverted to bone stock OPNsense, disabled IPV6, few minor tweaks, then spun up the guide.

Tried setting unbound to use WG interface only, it didn't work. It still used ISP DNS (even ignored DNS settings from System -> Settings -> General).

Then I tried setting it to forwarding mode and specifying VPN-provided DNS in System -> Settings -> General, this didn't work. Static clients got no DNS at all.

I then theorized that the firewall alias (and thus rule) in step 8 contained networks which include the DNS servers my VPN provider has specified for use, so maybe the firewall was forcing that traffic to NOT use the WG gateway I created. So I removed those networks from the firewall. Still didn't work, but I'm tired and maybe I needed to flush DNS or something, I don't know.

This has me stumped. Surely other people are using this official Wireguard selective routing guide and not leaking DNS?

Lastly, when I traceroute from a static client, it actually routes through the Wireguard VPN DNS, and VPN tunnel. But when I fire up Firefox, dnsleaktest.com clearly shows my ISP DNS and IP, which I literally put nowhere in any setting.

Thanks for any help you can provide, I'd like to make the guide and documentation improved for the benefit of others if we can figure this out.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 24, 2021, 07:22:45 am
What’s handing out the DNS configuration in your network, and what is that configuration? What are the DNS settings on the computer on which you are browsing with Firefox? If you route everything over the tunnel (ie don’t exclude local IPs), what result do you get?
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: CactusFractal on March 24, 2021, 07:43:15 am
Thanks for the reply, Greelan!

I have opnSense as close to default config as possible, with DNSMASQ disabled, and Unbound Enabled. 

The computer I'm browsing with receives a static IP and is in the VPN alias configured in your guide.  The device is set for standard DHCP, not static, no overrides.  Further, I have both "Allow DNS server list to be overridden by DHCP/PPP on WAN" and "Allow default gateway switching" unchecked (disabled).  There is only one DNS set in System - Settings - General and that is 1.1.1.1 (Cloudflare).

When I configure the router from stock defaults using my provider's VPN guide, I get ALL traffic routed over the VPN tunnel, no leaks at all.

Here is my latest post on the reddit thread, let me know what you think:

Quote
That's just it - Firefox on a desktop client given a static IP as defined in the step 7 alias shows the VPN IP, but shows my ISP DNS server as reported by DNSleaktest.com.

I did also set Unbound to only send traffic out via the WG interface. It did not work, it still used my ISP DNS servers. It would not even use 1.1.1.1 which was the only DNS I set in General Settings.

I have both the boxes you mention unchecked under Settings: General.

I am wondering if this situation is because of the differences between Wireguard and OpenVPN, and perhaps the guide author did not fully test for DNS leaks. As I understand it, DNS traffic can use both TCP and UDP protocols, which is fine for OpenVPN. But Wireguard does not use TCP, only UDP. (https://www.wireguard.com/known-limitations/) Could this be causing the router to fall back to ISP DNS when nothing else works? I'm running short on new theories. As it stands, I do not believe this guide works as intended, unless I'm still not configuring something correctly.

I hope I made some simple error, and we can get to the bottom of this.

Edit: I realize your second question referred to removing the RFC1918 alias as Destination in the LAN firewall rule.  When I do that, the static client gets no DNS at all.

Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 24, 2021, 08:29:34 am
You are right, I didn’t do a comprehensive test of DNS leakage, although this would likely be a broader issue for non-selective routing setups too? What I wonder is how your ISP DNS is being introduced into your network in the first place, which may reflect an entirely separate issue. 
Title: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 24, 2021, 12:51:18 pm
When you removed the RFC1918 alias from the firewall rule, did you also uncheck the invert checkbox for the destination?
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: CactusFractal on March 24, 2021, 02:52:31 pm
Yes, I did remove the invert checkbox, it got no DNS at all after that.  I am using a VPN provider that I believe does DNS "hijacking" when connecting over WG, I suppose in an effort to prevent DNS leaks.  Maybe this is an issue, I'm not sure.  But I just can't fathom why even if that's the case, I would be leaking DNS to my ISP when checking at dnsleaktest.com.

Just to confirm - what do you see when you test your connection at dnsleaktest.com?  Is it working properly without leaks for you?

Thank you so much.

Edit: So I took the following steps to force ALL DNS through the WG tunnel, and it worked without leaking DNS on a client in the WG VPN Alias:

Quote
In unbound, try setting the outgoing interface to the WG interface AND set unbound to forward mode and set the DNS servers in systems: settings to 1.1.1.1. I think that may fix the issue for you. I'm not sure why it does not work in recursive mode.

I recall reading that Mullvad does DNS hijacking on WG servers. Unlike their OpenVPN servers, where you can connect to a specific port to avoid DNS hacking, they do not have the option for WG servers (perhaps to be added in the future).

Quote
OK, when I did all those three things simultaneously (unbound to forwarding mode, use only WG interface, set system settings general DNS), I actually got the Cloudflare servers returned on the DNSleaktest.com test.

Then, I set the DNS server in System -> Settings -> General to my VPN provider's DNS, and also set it to "Use Gateway: WG_VPN" and HOLY CRAP, it appears to be working without leaking DNS.

This is fantastic, I can't believe it seems to be working. Need to run some more tests to verify non-VPN client connectivity, but WOW!

OK so the net result (as we intended) is that ALL DNS traffic is forced over the VPN, even from clients not in the WG VPN alias. Clients not in the VPN alias appear to be routing non-DNS traffic over the ISP, also as intended. WOW. YOU ARE A LEGEND.

I'm not sure yet whether this setup will result in unintended breakage of services, so maybe there is a way to force clients not in the VPN alias to use different DNS servers by setting them to use DNSMASQ or something? That seems difficult given the particulars of this setup and workaround, but I don't know. It's probably fine.

The whole point in doing this exercise is that I need some clients on my network to egress over the VPN and cannot install VPN software directly on them hence this firewall solution, but I also need to forward some inbound ports to an internal IP to stand up Nextcloud behind a LEMP stack (reverse proxy). I'm hoping I can achieve this with this setup. WHEW!

EDIT: In further testing after deploying settings above, another client that I set a static mapping for and added to the VPN Hosts alias fails to resolve DNS at all.  I'm unsure as to why, but my theory is either that the limitations of Wireguard prevent DNS over TCP from working properly in this scenario, or my VPN provider's interception of DNS is causing issues.  Frustrating.


Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 24, 2021, 08:58:05 pm
I will need to do some more testing when I get a chance.

As a matter of interest, did you set any DNS entries in the Local config for your VPN on OPNsense?
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: CactusFractal on March 24, 2021, 10:22:31 pm
Yes, I set the DNS entry to the one provided by my VPN provider.

For now, I have reverted to a base config without policy routing, which routes ALL traffic from my router through my VPN using Wireguard.  It's working great, near my rated line speed even with the WG-Go userspace implementation, so I'm super frustrated I have not yet been able to get policy routing working.  I am loving OPNSense's speed and interface so far.

My working theories are still some combination of:
1) An issue with the Wireguard protocol or WG-Go being unable to route TCP DNS traffic by design
2) The particular DNS addresses my VPN provider issues being in the RFC1918 space
3) The fact that I believe my VPN provider intercepts DNS traffic (in the name of preventing leaks, but it may break this implementation)

I look forward to your further testing, and thanks.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 25, 2021, 01:37:36 pm
Yes, a quick test has DNS leaking. I will have to spend some time trying to figure out how to address it. I have OPNsense handing out over DHCP the local IPs of my pihole / unbound box for DNS, and I suspect the relevant client just continues to use those
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: CactusFractal on March 25, 2021, 08:17:27 pm
I considered spinning up a PiHole with Unbound to hand off DNS as well, let me know how it goes with your continued testing.

Do you happen to know if your VPN provider intercepts / redirects DNS traffic?  If not, it would seem that the issue could be related to my #1 or #2 theory above.
Title: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 26, 2021, 04:00:53 am
No it doesn’t

And your theory 1 doesn’t hold if everything is going through the tunnel (including DNS) when you are running full routing. If TCP didn’t work down the tunnel then you couldn’t browse websites over the VPN, as http/https is (mostly) TCP :)

Theory 2 I also don’t think is related. What I do think is resulting in this behaviour is when a local DNS server is used in the network setup generally. If a public DNS server was simply configured on the hosts, then I think that would go down the tunnel just fine

Something is not right with the routing it seems
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on March 27, 2021, 06:42:40 am
OK, the issue is indeed if the network is set up generally with a local DNS server - such as OPNsense itself or another local host. In my case I have a Raspberry Pi box running Pi-hole and unbound that is my DNS server for the whole network.

So the hosts that are meant to use the tunnel have the local IPs of the RPi box as their DNS servers. If the local networks (RFC1918 networks) are excluded from the firewall rules set up for WG as per the guide, then obviously all DNS requests will go in the normal way to the DNS server local IPs, and then from there out of the network through the normal WAN gateway (assuming the DNS server local IPs are not in the "VPN hosts" alias that is meant to use the WG tunnel). Result: DNS leaks.

As I see it, potential solutions are:

1. Include the DNS server local IPs in the "VPN hosts" alias. This will mean that all DNS traffic for the network will go over the tunnel, not just the DNS traffic for the hosts that are in the "VPN hosts" alias.

2. (If possible) intercept DNS traffic coming from the "VPN hosts" and port forward that traffic to a DNS server supplied by the VPN provider,* or to a public DNS server. Note that I say "if possible" because if the local DNS server that is configured generally for the network is not OPNsense itself and is on the same subnet as the "VPN hosts", then DNS requests won't be routed through OPNsense (they will be layer 2) and so a port forward on OPNsense won't work.

3. In the DHCP static mappings for the "VPN hosts", specify either the DNS servers supplied by the VPN provider,* or public DNS servers. This will override the network-wide DNS settings for those hosts.

4. Configure public DNS servers for the whole local network, rather than local DNS servers.

5. Manually override the DNS settings on the "VPN hosts" so that the DNS servers provided by DHCP are ignored, and either the DNS servers supplied by the VPN provider,* or public DNS servers, are used instead.

* Note: If the DNS servers supplied by the VPN provider are local IPs (ie within the RFC1918 subnets), then the firewall rules will have to be configured so that the WG gateway (rather than the normal WAN gateway) is used for the relevant IPs - in effect, the IPs will need to be excluded from the exception for RFC1918 networks.

Obviously what solution works best will depend on each user's network configuration and desired outcomes.

I will in due course add a warning about potential DNS leaks to the OPNsense documentation and outline the potential solutions. Happy to hear anyone else's thoughts on potential solutions as well.
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: styr0 on June 15, 2022, 03:53:46 am

Greelan, thank you for this. Works like a charm. :) :)
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: pb81 on August 30, 2022, 11:13:52 am
Great guide best one I've seen yet for WireGuard VPN Providers! I have one recommendation on the firewall rule.

Create a Second ALIAS called RFC1918, and put RFC1918 networks (192.168.0.0/16.10.0.0.0/8,172.16.0.0/12) in it. Then use it in the Firewall rule Destination

Create a firewall rule

   Destination / Invert: Checked
   Destination: RFC1918
   Destination port range: any

This will make it so only internet traffic will go over the VPN, making any other local traffic not be interfered with by the VPN gateway, this can then be blocked or allowed by any rules after it.

And exactly how do i add this second rule? My WireGuard provider uses the 10.x.x.x range.
Can somebody add this step to the guide please =)
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: Greelan on August 30, 2022, 11:26:07 am
It already is. See steps 7 and 8 in the how-to: https://docs.opnsense.org/manual/how-tos/wireguard-selective-routing.html
Title: Re: TUTORIAL: Set up WireGuard for limited local hosts to use external VPN provider
Post by: pb81 on August 30, 2022, 11:36:30 am
Ahh ok =)