2-5: DNS
At some point, you’re going to get pretty tired of using IP addresses all over the place to refer to your Wireguard Peers. Or, you’ll want to use your existing private network’s internal domain while roaming. Both of these are possible!
Wireguard offers multiple ways to route DNS over the tunnel. We’ll start with the lame easy way.
The DNS Directive
Turns out, there’s a DNS directive available in the [Interface] configuration! Setting that address will send all DNS requests to that destination while the tunnel is up.
DNS = 172.16.100.10
You can also add multiple addresses, just like other DNS configurations.
DNS = 172.16.100.10, 172.16.100.11
You can even add a search domain.
DNS = 172.16.100.10, mydomain.local
As long as the IP address provided is reachable by your Peer, DNS will be routed through the tunnel. This prevents DNS Leaks while on a “private” network.
Systemd-Resolved
On Linux systems using systemd-resolved for their DNS management, there is also the option of specifically routing DNS requests for known domains on a specific network interface. If you want all DNS traffic routed through the Wireguard tunnel, this is unnecessary; you can use the DNS directive described above. But in some cases, you do want only certain domains to be handled by the DNS server on the tunnel. For example, suppose you want to route an intern lab’s domain name via the tunnel, but leave the rest of your DNS as your default servers.
Here’s what we need. Assuming a DNS server address of 172.16.100.3 and a domain name of home.lab:
PostUp = resolvectl dns %i 172.16.100.3
PostUp = resolvectl domain %i home.lab ~home.lab
PreDown = resolvectl revert %i
The first PostUp configures a new DNS server on our Wireguard network interface at the address listed. Remember, this address doesn’t have to be on the same subnet as your Wireguard hosts; it only has to be accessible over the Wireguard tunnel. So if you have a DNS server in your lab that’s available via NAT/Masquerading like we set up in the last lab, you can use an IP address on a subnet to which you’re forwarding.
Now, if that’s all we did, the DNS resolution would still work, but a bit inelegantly. Systemd-resolved would attempt DNS queries on all configured servers at once, and first responder wins. We don’t need to bother with querying a DNS server we know won’t have the answer we want. That’s what the second PostUp directive does. We’re telling resolved to send DNS queries for the home.lab domain to the configured server on our Wireguard interface. We’re also telling it to search that domain, so that if we request webserver without a domain, resolved will attempt webserver.sec.lab on that DNS server.
Finally, a PreDown directive. Why PreDown and not PostDown? We can’t make changes that reference the Wireguard interface once it’s been deleted, so we need to do that before it goes away. revert removes any added config for the interface and sets it back to a default state.
You can add as many domains this way as you like with additional PostUp directives.
Again, this is fully optional. But having custom DNS really is quite a valuable tool in a private network.
Let’s practice setting this up.