Warning: If you're using WireGuard to split tunnel traffic on Windows, WireGuard is leaking what sites you visit. Here's how to fix it.
What Is a DNS Leak and Why Is It Bad?
When you type in a URL, a DNS query is made to resolve that URL's domain to an IP address. DNS queries, by default, are unencrypted meaning that anyone watching can see what sites you're visiting. Simply put, a DNS leak means that you're broadcasting what sites you're visiting. This is probably not your intention if you use a VPN like WireGuard to encrypt your traffic.
Why are WireGuard DNS Leaks Specific To Windows Clients?
"Normal" Windows DNS Resolution Behavior
Let's say you're on your laptop connected to wifi. In a typical network connection without WireGuard enabled, you only have one network connection. When you connect to wifi, a DHCP server on the network assigns you an IP address and gives you a DNS server to use. When you enter a URL, the domain name resolution process described above occurs using that given DNS server. Very straightforward.
Windows Multihomed DNS Resolution Behavior
So, if your wifi network connection assigns you a DNS server, what happens if you have multiple network connections? How does Windows know which DNS server to use? And therein lies the problem...
When you're connected to WireGuard, you have, by necessity, multiple network connections. You have one network connection to the local network (wifi, LAN, etc.) AND a separate WireGuard network connection (which has its own network adapter).
In these scenarios, Windows ends up just blasting DNS queries to all of the DNS servers. (There's a bit more subtlety to it than this, but the end result is the same).
Am I Affected By WireGuard DNS Leaks?
First of all, 1) are you using Windows? and 2) are you using split tunneling? You are affected if the answer is "Yes" to both. If you aren't using split tunneling, you are NOT affected.
How Can I Tell If I Am Using Split Tunneling?
Split tunneling means you're only running SOME traffic (not all) through WireGuard. This is the case if you have specific AllowedIPs specified in your WireGuard client configuration. If you have AllowedIP set to /0 (as in AllowedIP=0.0.0.0/0), then you've enabled WireGuard's "kill-switch" and are unaffected.
How to Fix WireGuard DNS Leaks in Windows
We fix WireGuard DNS leaks by creating firewall rules to allow only the connection to the DNS server specified in our WireGuard config and block the connection to any other DNS server. Thankfully, DNS queries have a specific fingerprint in that they listen for UDP traffic on port 53; therefore, this is relatively easy.
Stop WireGuard DNS Leaks in Windows Using Bitdefender Firewall
If you're using Bitdefender, the firewall configuration is the most straightforward. Open Bitdefender Total Security and navigate to "Protection". Find the "Firewall" section and click "Settings". Once in the Firewall settings, click "Rules" and "Add rule".
Toggle on "Apply this rule to all applications". Set Permission to "Allow", Protocol to "17. UDP" and Direction "Outbound". Click on "Show Advanced Settings", toggle on "Custom Local Address" and, in the IP field, enter your WireGuard client IP address (NOT your WireGuard server IP address). Toggle on "Custom Remote Address" and specify the IP address of the DNS server you have set up in your WireGuard client configuration. Under the Custom Remote Address "Ports", enter "53". After all this is done, it should look something like this:
Next, we'll need to create a block rule to block all other DNS queries. Again, we'll "Add rule" and "Apply this rule to all applications". Permission this time will be set to "Deny"; Direction is "Outbound". Then "Show Advanced Settings", and toggle "Custom Remote Address" on. Leave the IP address blank and for Ports, specify "53" so you end up with this:
Overall, your Bitdefender firewall rules should appear like so (and in this specific order):
Prevent WireGuard DNS Leaks Using Windows Defender Firewall
Now, if you're like me, coming from Linux and being familiar with iptables, Windows firewalls are a bit "weird". You lack A LOT of the granularity and control with Windows Defender firewall rules that you get with iptables just because of how Windows applies its firewall rules. (Windows doesn't apply firewall rules in a top-down order like iptables does, it also lacks a "NOT" boolean logic operator, block rules take priority so if you block all DNS queries and then try to allow DNS queries to a single specified DNS server it won't work, etc.). Overall, Windows firewall rules are not my idea of a good time, but for the vast majority of Windows users, this is what you're using, so I've come up with some "tricks" to help you.
In Windows, search for "Windows Defender Firewall with Advanced Security". This will open up your traditional Windows Defender Firewall rules. Click on "Outbound Rules" in the left-hand menu. In the right menu, under "Actions" and under "Outbound Rules", click "New Rule". Under "Rule Type" select "Port". Click "Next" and set the protocol to "UDP". Specify a "Specific remote port" of "53" and click "Next" again. For the "Action" tell Windows Defender to "Block the connection". Under "Profile" leave everything checked and give the rule a descriptive name like "CUSTOM- BLOCK wifi DNS".
Find your new rule in the "Outbound Rules" list. Right-click on it and select "Properties" > "Advanced". Click "Customize" under "Interface types" and tell Windows Defender Firewall to only apply this block rule to "Wireless" interface types.
What we've done here (because Windows gives block rules priority regardless of how specific the rule) sidesteps the issue by having the block rule apply to any DNS queries on the wifi connection while leaving the DNS queries over the WireGuard tunnel (which isn't considered a wifi interface) free to pass.
Note that if you're not using wifi and are instead using a wired connection, this is still possible, albeit cumbersome. Please leave a comment below if you need help doing so.
Alternative Methods to Stop WireGuard DNS Leaks
- Don't use split tunneling unless absolutely necessary. Instead, use WireGuard as a traditional VPN and route all your traffic through the WireGuard tunnel. You can read my blog posts on how to do so here: