Split Tunneling in WireGuard on Windows

asheroto
5 min readAug 3, 2021
Tunnel

Note: Although the instructions below work for most setups, it’s not a method that should be relied on if you have high security concerns, mainly because of the DNS issue I discuss at the bottom of this article (or any other leaks). I’ve found that one of the best ways to accomplish split-tunneling in WireGuard is to actually use Proxifier. With it, you can force traffic out specific Interfaces or specific proxies (like SOCKS5). Proxifier has a built-in virtual driver that actually forces traffic out the interface/proxy of your choice. I mention it later on in this article. I don’t work for Proxifier, just a fan of it.

Recently I stumbled upon a situation in which I needed to use split tunneling in WireGuard. I had an application that I wanted to route through WireGuard, but everything else I wanted to route through my regular default gateway.

By default, WireGuard will create a new default route setting it as high priority (low metric). This forces all of your traffic out the WireGuard tunnel. You can delete the default route, but then you’d have to add a route each time the tunnel is connected.

That seemed like a hassle, so after some digging, I found a better solution.

Here’s the how I accomplished split tunneling with WireGuard:

  • Disable automatic default route creation
  • Configure allowed IPs
  • Enable the use of scripts
  • Add post-up/pre-down commands

Disable automatic default route creation:

In the [Interface] section of your tunnel config, add

Table = off

This tells WireGuard not to create a default route automatically.

Configure allowed IPs:

You’ll probably want to set this to all IPs. AllowedIPs tells WireGuard what IP addresses to route through the tunnel. So if your application connects to various IPs, or you aren’t sure, perform this step. (After this we will fix the default routes so packets don’t actually go out through the tunnel.)

In the [Peer] section of your tunnel config, set this

AllowedIPs = 0.0.0.0/0

Enable the use of scripts:

Scripts are not enabled in WireGuard on Windows by default. We need to enable scripts so we can properly set up the correct route. To do this, you’ll need to enable the DangerousScriptExecution registry key.

Open the registry editor and navigate to

HKEY_LOCAL_MACHINE\SOFTWARE\WireGuard

Create the WireGuard key if it doesn’t exist. Create a new DWORD value named

DangerousScriptExecution

And set its value to

1

It should look like this

Registry Editor

Add post-up/pre-down commands:

In the [Interface] section of your tunnel config, add these lines

PostUp = powershell -command "$wgInterface = Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%; route add 0.0.0.0 mask 0.0.0.0 0.0.0.0 if $wgInterface.ifIndex metric 9999; Set-NetIPInterface -InterfaceIndex $wgInterface.ifIndex -InterfaceMetric 9999;"
PreDown = powershell -command "$wgInterface = Get-NetAdapter -Name %WIREGUARD_TUNNEL_NAME%; route delete 0.0.0.0 mask 0.0.0.0 0.0.0.0 if $wgInterface.ifIndex metric 9999; Set-NetIPInterface -InterfaceIndex $wgInterface.ifIndex -InterfaceMetric 9999;"

This will tell WireGuard to add a new default route after the tunnel is up (PostUp) with a metric of 9999 (low priority), as well as setting the metric of the interface itself to 9999 (low priority). That means although Windows will technically route traffic through the tunnel, it will [probably] never happen because all other routes precede it in priority. As a comparison, most route metrics are less than 500 (lower is higher priority).

You’ll have to tell whatever program you’re using to use the WireGuard interface or the interface’s IP address. Proxifier can also do this (as seen below).

Confirming things

If you’d like to see your routes, open PowerShell and type

route print

Once the tunnel disconnects, it will delete that route (PreDown).

To confirm your metrics are working correctly, open PowerShell and type

netsh interface ip show address

Your VPN interface should show a Gateway Metric of 9999 and an Interface Metric of 9999.

If you want to confirm which traffic is passing over your VPN vs your regular connection, the easiest way I’ve found is to use NetworkTrafficView from NirSoft which shows each connection. (Note the “Process Filename” column)

NetworkTrafficView

DNS….it’s always DNS!

DNS is something to be concerned about when it comes to privacy.

The 9999 metric trick above works mainly because traffic will always traverse a non-VPN adapter first before traversing the VPN.

With DNS it’s different…

The way Windows handles DNS is complex and can result in a DNS leak. This is because even if your primary and secondary DNS servers on your physical adapter are working, your VPN’s DNS will still receive queries which will also be traversing the DNS servers itself.

This article from YogaDNS describes this perfectly. YogaDNS forces DNS traffic over a specific interface. I’ve never used YogaDNS, but I have used its sister-product Proxifier and I love it (see below).

TL;DR…

If you run into connectivity issues with certain apps, remove this line from your WireGuard config.

If you’re concerned about privacy… use YogaDNS to force specific apps to use specific DNS servers on specific interfaces. They have a free version.

DNS = x.x.x.x

Forcing Traffic through a Specific Network Interface:

The only downside to split-tunneling through a traditional method, like the above, is that the program you want to use on that specific network interface must support the ability to let you choose which network interface to use.

If the application you want to route through the tunnel doesn’t support binding to a specific interface or IP address, consider using ForceBindIP (free) or Proxifier (free trial, but worth it).

I don’t work for Proxifier nor do I know them, but I can say if you want ultimate control over which app to use which connection, use Proxifier.

Proxifier

Proxifier is absolutely terrific. Not only can you specify specific applications to route through specific interfaces, but it also supports SOCKS5 and other proxies. You can even specify certain hostnames or ports to re-route traffic for.

…. plus you don’t even have to worry about split-tunneling!

Consider becoming a Medium member if you appreciate reading stories like this and want to help me as a writer. It costs $5 per month and gives you unlimited access to Medium content. I’ll get a little commission if you sign up via my link.

--

--

asheroto

🌎 Full Stack Developer 🔗 Systems Administrator 😎Innovation through Automation ✔ Privacy Advocate ♥ Startup Facilitator