Using Pi-hole as a DNS Server for my Tailnet
After recently setting up Pi-hole as my home DNS server and network-wide ad blocker, I wanted to be able to use it when I’m away from home on mobile data as well. I also wanted all of my servers (such as my Mastodon instance) to use the same DNS infrastructure.
I already use Tailscale across my devices. My Raspberry Pi, which runs Pi-hole, is configured as an exit node for situations where I’m on dodgy Wi-Fi. However, I don’t want to route all traffic from all devices through my home network. Exit nodes are inherently slower: they’re limited by upstream bandwidth and by the CPU cost of decrypting and re-encrypting every packet.
Fortunately, with a small amount of additional configuration, it’s possible to make every device in your Tailnet use Pi-hole only for DNS, without routing general traffic through an exit node. Here’s how.
Configure Pi-hole to accept Tailnet traffic
First, Pi-hole needs to accept DNS queries originating from your Tailnet. By default, Pi-hole only accepts connections from local devices, which is the correct and safe default, as you don’t want to open your Pi-hole to the internet.
However, if your firewall rules are sane and you understand the implications, you can relax this restriction. In the Pi-hole admin UI, go to Settings → DNS → Interface settings and select Permit all origins.
Before enabling this, make sure you read the official documentation so you understand exactly what this option does and when it’s appropriate.
Install Tailscale on the Pi-hole host
Tailscale has excellent installation documentation, so I won’t repeat it here.
If you’re feeling lazy, don’t mind running a remote install script directly from the internet, and generally live the YOLO lifestyle, you can install it with:
curl -fsSL https://tailscale.com/install.sh | sh
Otherwise, follow the manual installation steps in the docs.
Configure Tailscale DNS to use Pi-hole
Next, tell Tailscale to use your Pi-hole instance as a DNS resolver for the entire Tailnet.
- Open the Tailscale Admin Dashboard and navigate to the DNS tab.
- Scroll to Nameservers and click Add nameserver.
- Select Custom.
- Enter your Pi-hole’s Tailscale IP address.
- Optionally enable Use with exit node if you also want DNS to work when an exit node is active.
- Click Save.
At this point, most devices should automatically start using Pi-hole for DNS resolution.
Accept DNS and subnet routes on Linux clients
In practice, I found that some Linux machines picked up the new DNS configuration immediately, while others didn’t. I haven’t dug deeply into why this happens, but the fix was simple.
On the affected machines, explicitly tell Tailscale to accept both DNS settings and subnet routes:
tailscale set --accept-routes
tailscale set --accept-dns
After running these commands, DNS resolution started flowing through Pi-hole as expected.
Result
That’s really all there is to it. Every device in my Tailnet now uses Pi-hole for DNS, regardless of location, without forcing all traffic through an exit node. This gives me ad blocking, internal name resolution, and consistent DNS behaviour everywhere, while keeping latency and bandwidth usage to a minimum.