VPNSmith
self-host-vpnINFO

WireGuard Split DNS: Send Only Your Internal Domains Through the Tunnel

WireGuard's DNS option is all or nothing: set it and every lookup goes to the tunnel resolver. Sending only your internal zone there, and leaving the rest on your normal resolver, needs a piece WireGuard does not have. Here are the three ways to add it.

By Eric Gerard · Founder · VPNSmith - Self-host VPN & GDPR VPS specialist4 min readPhoto via Pexels

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.

The usual setup: a WireGuard tunnel to a home network or a VPS, with internal hostnames like nas.home.lan that should resolve through it. Everything else, ordinary web browsing, should keep using the resolver you already had.

Put DNS = 10.10.0.1 in the config and you get half of it. Internal names resolve, and every other lookup on the machine now goes through the tunnel too, including the ones you did not want to send anywhere.

Why WireGuard cannot do this itself

DNS is not a WireGuard protocol field. wg-quick reads it and hands it to whatever manages resolvers on that system: resolvconf, systemd-resolved, or a direct rewrite of /etc/resolv.conf.

That handoff is interface wide. There is no place in the WireGuard configuration to say these domains here, everything else there, because WireGuard moves packets and does not parse DNS at all.

Split DNS therefore always comes from the resolver layer. Which of the three methods below applies depends only on what your machine already runs.

Method 1: systemd-resolved, the one line answer

On a Linux machine using systemd-resolved, and most current desktop distributions do, wg-quick understands a second field:

[Interface]
DNS = 10.10.0.1
Domains = ~home.lan

The tilde is the whole trick. ~home.lan marks it as a routing only domain: queries for that suffix go to the tunnel resolver, and nothing else does.

Check the result while the tunnel is up:

resolvectl status wg0
resolvectl query nas.home.lan

The second command reports which resolver answered, which is the fastest way to confirm it worked rather than assume it.

The common failure is that systemd-resolved is installed but not actually managing /etc/resolv.conf. If that file is a plain file rather than a symlink into /run/systemd/resolve/, the Domains line is accepted and ignored. ls -l /etc/resolv.conf settles it in one command.

A metal signpost by a mountain road with five wooden arrow signs pointing in different directions, two orange and one green with white lettering, against dark forested hillsides under an overcast sky
A metal signpost by a mountain road with five wooden arrow signs pointing in different directions, two orange and one green with white lettering, against dark forested hillsides under an overcast sky

Method 2: dnsmasq, when there is no systemd-resolved

dnsmasq runs locally as your resolver and forwards per domain:

server=/home.lan/10.10.0.1
server=/10.in-addr.arpa/10.10.0.1

The first line sends home.lan and everything under it to the tunnel resolver. The second does the same for reverse lookups of your 10.x range, which is the line people forget and then wonder why ping shows addresses instead of names.

Point the system at 127.0.0.1 and leave it there. Because dnsmasq is always the resolver, tunnel up or down, nothing has to be reconfigured when the interface changes state.

Method 3: Windows and macOS

Windows does not read a Domains field, but the official WireGuard client accepts a search domain list in the DNS line itself:

DNS = 10.10.0.1, home.lan

Entries that look like domains rather than addresses become the search list, and the client applies the resolver to those names via NRPT rules.

macOS with wg-quick writes a resolver file under /etc/resolver/, which is the native way to scope a resolver to one domain. The WireGuard app from the App Store handles the common case by itself. If you need finer control, a file at /etc/resolver/home.lan containing nameserver 10.10.0.1 does it, and survives independently of the tunnel.

The check that catches most failures

Before blaming DNS configuration, confirm the query can physically reach the resolver:

dig @10.10.0.1 nas.home.lan

If that times out with the tunnel up, this is not a split DNS problem. Either the resolver address is missing from AllowedIPs on the peer, so the query never enters the tunnel, or the resolver refuses queries from your tunnel subnet. AllowedIPs doing double duty as route table and access list is covered in our AllowedIPs guide.

One caveat worth stating plainly: split DNS means some of your lookups keep going to your ordinary resolver, in the clear, visible to whoever operates it. That is usually what you wanted. If it is not, the answer is encrypted DNS on the non tunnel path rather than routing everything through the VPN, and our DNS leak prevention guide covers the difference.

For deciding what traffic, rather than what names, goes through the tunnel, see split tunneling.

★ Nuremberg GDPR datacenter · ✓ Dedicated IPv4 included · 200+ Mbps guaranteed

Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region

Frequently asked questions

Can WireGuard do split DNS on its own?
No. The DNS line in a WireGuard config sets the system resolver for the whole interface while the tunnel is up. It has no notion of sending some domains to one resolver and the rest to another, so split DNS always comes from something else on the machine.
What is the difference between split tunneling and split DNS?
Split tunneling decides which traffic goes through the tunnel, using AllowedIPs. Split DNS decides which name lookups go to the tunnel's resolver. They are independent, and you can have either without the other.
How do I do split DNS on Linux with WireGuard?
If the machine runs systemd-resolved, add a Domains line to the WireGuard config alongside DNS. wg-quick passes it to resolvectl, which routes only those domains to the tunnel resolver. Without systemd-resolved, use dnsmasq with a server entry scoped to the domain.
Why do my internal hostnames not resolve over WireGuard?
Usually the DNS server's address is not inside AllowedIPs, so queries never enter the tunnel. Check that the resolver address, or a range containing it, is listed on the peer, and that the resolver accepts queries from the tunnel subnet.