Affiliate disclosure — This post contains Contabo affiliate links. If you grab a VPS through them, we earn a commission at no extra cost to you. We only document what we actually run in production on our own VPS.
This is the WireGuard hidden defect nobody warns about: you set up your tunnel, all your IP traffic goes through Contabo, you feel safe — except your DNS queries still go to your ISP, your hotel router, or your Wi-Fi corp network's resolver. A DNS leak destroys the privacy guarantee of any VPN: even if your data is encrypted, your ISP knows you're visiting github.com, your-bank.com, or anything else, because it resolves the names for you.
The problem is structural to WireGuard. Unlike OpenVPN, the protocol takes zero stance on DNS — it's a pure IP tunnel. The DNS = ... directive in your .conf is just a hint to wg-quick and varies by OS. This guide unpacks why, how to detect it, and the working fixes per platform — based on a year of debugging real leaks on our own Contabo + WireGuard setups.
How a DNS leak really happens
Three distinct mechanisms produce a DNS leak on a WireGuard client:
1. The OS keeps its original resolvers active. On Linux without resolvectl, /etc/resolv.conf is rewritten by NetworkManager, dhclient or systemd-resolved at every event (DHCP renew, wakeup, network change). The DNS you pushed via wg-quick gets overwritten. The application makes a query → the system queries the original DNS → that DNS sees your queries outside the tunnel.
2. DNS over HTTPS / DNS over TLS browsers bypass the OS. Firefox and Chrome ship DoH enabled by default in many regions. When the browser opens a DoH connection to mozilla.cloudflare-dns.com, that connection does transit through the WireGuard tunnel (so far so good), but the browser bypasses the local resolver completely. If a DoH provider keeps logs, your queries are visible there, in a different way.
3. Apps using hardcoded resolvers. Some apps (Spotify, certain Microsoft apps, some games) hardcode 8.8.8.8 or their proprietary servers. They make a UDP/53 query directly to 8.8.8.8 — and if your firewall doesn't block that outside the tunnel, the query goes outside.
The conclusion is brutal: a DNS leak isn't a WireGuard bug, it's a structural state of OSes. You have to actively lock things down to prevent it.
Reliable detection — the right tools
Forget cosmetic leak tests for a minute. Here are the three tests we run every time we suspect a leak:
Test 1: dnsleaktest.com (extended) + ipleak.net
Both sites do the same thing: load a page that does DNS queries to unique randomly-generated subdomains, then look on the server side which resolvers requested those subdomains. If you see resolvers in your home country (your ISP, your corp Wi-Fi), it's a leak. If you only see resolvers from your VPS region (Cloudflare DE, Hetzner DE), you're clean.
dnsleaktest.com/extended-test | ipleak.net
Test 2: Server-side tcpdump (the most reliable)
This is the actually-airtight test. On your VPS hosting WireGuard:
tcpdump -i wg0 -n udp port 53
Leave it running. On your client (laptop, phone) connected to the tunnel, type curl https://example.com. You must see a DNS query in the tcpdump on wg0. If you see nothing, your client resolved DNS without going through the tunnel = leak.
Alternative on the client side itself, even cleaner:
sudo tcpdump -i any -n udp port 53 and not net 10.66.0.0/16
Where 10.66.0.0/16 is your WireGuard tunnel subnet. If anything appears here, it's a leak — DNS traffic flowing outside the tunnel.
Test 3: resolvectl status (Linux only)
resolvectl status
For each interface, you see the DNS servers in use. The wg0 interface should list your tunnel DNS, and ideally the eth0 interface should have no DNS servers (or be ignored). If eth0 keeps your ISP's resolvers active, applications will use them when DNS resolution fails on wg0 (fallback behavior).
Working fixes per platform
Linux desktop — the most robust solution
Recommendation: systemd-resolved + per-interface DNS + nftables lockdown.
In your WireGuard .conf, the [Interface] block:
[Interface]
PrivateKey = ...
Address = 10.66.0.2/24
DNS = 10.66.0.1
PostUp = resolvectl dns %i 10.66.0.1; resolvectl domain %i '~.'
PreDown = resolvectl revert %i
The ~. domain tells systemd-resolved "all DNS queries go through this interface". The PreDown reverts on disconnect.
Then nftables firewall lockdown — block any DNS traffic NOT going to your VPS:
nft add table inet vpn_lock
nft add chain inet vpn_lock output { type filter hook output priority 0 \; }
nft add rule inet vpn_lock output udp dport 53 ip daddr != 10.66.0.1 drop
nft add rule inet vpn_lock output tcp dport 53 ip daddr != 10.66.0.1 drop
Persist this in /etc/nftables.conf for reboot survival. This rule kills any UDP/TCP 53 packet not destined for your VPS resolver. Brutal but effective — any leak is physically blocked.
Windows 10/11
The native WireGuard client honors DNS = ... correctly via the Wintun driver. The issue: split DNS isn't great by default, and DoH in Edge/Chrome can bypass.
Steps:
- In your .conf,
DNS = 10.66.0.1(your VPS resolver). - Disable browser DoH: in Chrome
chrome://settings/security→ uncheck "Use secure DNS"; in Edge same setting. - Hardening firewall: Windows Defender Firewall with Advanced Security → outbound rule blocking UDP/53 except to your VPS IP. The PowerShell command:
New-NetFirewallRule -DisplayName "Block DNS Leak" `
-Direction Outbound -Protocol UDP -LocalPort 53 `
-RemoteAddress "!10.66.0.1" -Action Block
The leading ! syntax means "anything but". Adjust 10.66.0.1 to your VPS resolver IP.
macOS Sonoma/Sequoia
The macOS WireGuard client (App Store) honors DNS correctly. But the mDNSResponder cache and proximity to .local can introduce surprises.
Steps:
- WireGuard config:
DNS = 10.66.0.1. - After connecting, flush DNS cache:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder. - Disable browser DoH (same as Windows).
- Verify with
scutil --dnsthat only your tunnel DNS appears in the "resolver #1" block.
iOS — the WireGuard client is honest
The official iOS WireGuard client honors DNS = ... cleanly. You usually have nothing more to do. Watch out though:
- Safari can use iCloud Private Relay if active, which adds an extra layer (Cloudflare/Akamai) — non-leak, but it changes the routing.
- Apps using non-standard ports (some VoIP) may bypass — rare but exists.
Real-life test: enable the tunnel, go to dnsleaktest.com on Safari, you should see only resolvers from your VPS region.
Android — the gnarliest case
The official Android WireGuard client handles DNS partially. The classic issue: Android getprop net.dns1 keeps the original DNS active, and some Android apps query that prop directly, bypassing the tunnel.
Mitigations in order of preference:
- NetGuard or AFWall+ in conjunction with WireGuard: NetGuard creates a local VPN that locks all DNS traffic onto your tunnel. Free, open-source on F-Droid.
- Private DNS Android (settings → Network → Private DNS) with a DoT server you trust:
dns.adguard.comor your own server with Unbound + DoT support. DoT works even without VPN, so it's a base layer of protection. - AdGuard Home or NextDNS as Private DNS provider: same setup, but you fully control the resolver.
Honest verdict: Android WireGuard + Private DNS to your own VPS is the most robust setup we've tested. Zero leaks across 6 months of intensive smartphone use.
Solid VPS-side setup — Unbound on Contabo
The other half of the equation is what answers DNS on your VPS. By default, if your WireGuard client points to 10.66.0.1, that's your VPS — and the VPS itself needs a real resolver. Two viable options:
Option A: Unbound (purist, fully recursive)
Unbound queries the DNS roots directly. Zero third-party log. The cleanest privacy setup. Install on a Contabo VPS S (Debian 12):
apt install unbound unbound-anchor
Minimal config in /etc/unbound/unbound.conf.d/vpn.conf:
server:
interface: 10.66.0.1
access-control: 10.66.0.0/24 allow
hide-identity: yes
hide-version: yes
qname-minimisation: yes
use-caps-for-id: yes
prefetch: yes
cache-min-ttl: 300
cache-max-ttl: 86400
num-threads: 2
msg-cache-size: 50m
rrset-cache-size: 100m
Restart: systemctl restart unbound. Test from a client: dig @10.66.0.1 example.com — you should get an answer with ANSWER SECTION.
Option B: AdGuard Home (filtering + UI)
If you want DNS-level ad/tracker blocking, AdGuard Home is the easy choice. Web UI, filter lists (EasyList, EasyPrivacy, OISD, …), per-client stats. Install:
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v
Web setup on port 3000 → set listening on 10.66.0.1:53. Upstream: leave the default DoT/DoH stack (or chain it to Unbound on 127.0.0.1 for full purist mode).
We run AdGuard Home → Unbound on our own Contabo. Best of both worlds: filtering + zero log.
Setting up either option takes 15 minutes on a freshly provisioned Contabo VPS S at €4.99/month (full setup: Contabo step-by-step tutorial). The total cost remains €60/year for a VPS that handles WireGuard + your DNS resolver in one shot.
VPS-side DNS leak hardening
Three additional tweaks on the WireGuard hub side that make DNS leaks much harder:
1. Force tunnel DNS via iptables/nftables. On the VPS, intercept any UDP/53 traffic originating from the WireGuard subnet and redirect it to your local resolver:
nft add rule ip nat prerouting iif wg0 udp dport 53 dnat to 10.66.0.1
Even if a client tries to query 8.8.8.8 directly, the VPS intercepts and answers via Unbound. Brutal but bulletproof.
2. Block IPv6 leak server-side. If your VPS doesn't disable IPv6 on the wg0 interface, some clients will leak DNS over IPv6 outside the tunnel. Either disable IPv6 entirely on the VPS (net.ipv6.conf.all.disable_ipv6=1 in /etc/sysctl.conf), or push a ::/0 IPv6 route through wg0 in the client AllowedIPs.
3. Outbound monitoring of unusual DNS. Set up a daily cron on the VPS that audits Unbound logs for queries from external IPs (not 10.66.0.0/24). If queries arrive from outside, your tunnel is leaky or open. See our WireGuard VPS monitoring with Prometheus + Grafana for a dashboard-ready setup.
Common false positives — don't panic
Two situations look like leaks but aren't:
1. iCloud Private Relay (macOS/iOS). If you have Private Relay active, DNS queries are dual-relayed through Apple + Cloudflare/Akamai. dnsleaktest.com sometimes shows "Cloudflare US" instead of your tunnel DNS — that's expected behavior, not a leak. Disable Private Relay if you want to see only your tunnel DNS.
2. Browser DoH (Firefox, Chrome). With DoH active, your browser bypasses the OS resolver and queries a DoH server (cloudflare-dns.com by default in Firefox). It's technically not a leak — the connection goes through the WireGuard tunnel — but it does mean a third party (Cloudflare) sees your queries. Disable browser DoH if you want all queries to go through your VPS resolver.
Final verdict — the 5-minute leak-proof checklist
In order of priority, what to put in place to eliminate DNS leaks on a self-host WireGuard:
DNS = 10.66.0.1in your .conf +PostUp = resolvectl dns %i 10.66.0.1; resolvectl domain %i '~.'on Linux.- nftables/iptables firewall that blocks UDP/TCP 53 outside the tunnel on the client.
- VPS-side resolver: Unbound or AdGuard Home on
10.66.0.1. - VPS-side DNAT for UDP/53 from wg0 to 10.66.0.1.
- Disable browser DoH (or accept that Cloudflare sees your queries).
- Verify with
tcpdump -i any -n udp port 53on the client — zero traffic outside wg0 is the goal.
A clean WireGuard setup on Contabo with this stack: zero leaks across 12 months of intensive use. No magic — the protocol is sound, the OSes are gnarly, and lockdown is structural, not optional.
Going further
- Self-host VPN on Contabo: full WireGuard guide 2026
- Tailscale vs WireGuard self-host: which one in 2026
- Headscale self-host: the sovereign Tailscale control plane
- WireGuard kill-switch on Linux: iptables + systemd
- VPS VPN monitoring with Prometheus + Grafana
Sources and references:
- WireGuard whitepaper — Jason A. Donenfeld
- Unbound — recursive DNS resolver
- AdGuard Home — open-source DNS-level blocker
- systemd-resolved manual
- dnsleaktest.com extended
Published 2026-06-05. Tests and fixes validated on Debian 12, Ubuntu 24.04, Windows 11 23H2, macOS Sonoma 14.5, iOS 17.5, Android 14 — with a Contabo VPS S Nuremberg running WireGuard 1.0.20210914 + AdGuard Home + Unbound. Behavior may differ on other distros or OS versions — always verify your own setup with tcpdump before considering it leak-proof.
Reminder: WireGuard and the self-hosting of DNS resolvers are perfectly legal in the EU, US, Canada and most democratic countries. VPNSmith publishes this content for educational purposes.
★ Datacenter Nuremberg GDPR · ✓ IPv4 dédiée incluse · 200+ Mbps garantis
Get Contabo30 jours satisfait ou remboursé→