← All projects

Personal home lab project

Pi-hole over Tailscale

I run Pi-hole in Docker for network-wide ad blocking and reach it from my phone over Tailscale, with no router port forwarded. I tested the setup with nmap: the Pi-hole ports were filtered from outside and open only on the tailnet.

My role

I set it up and tested it myself

Built with

  • Pi-hole
  • Docker Desktop
  • Tailscale
  • nmap

Links

View on GitHub

Design and fixes

  • Nothing is open to the home network or the internet, because no router port is forwarded. My phone uses the Pi-hole as its DNS on mobile data, through the Tailscale tunnel.
  • Chose Tailscale over a self-hosted WireGuard server. I don't control the router and the ISP may use CGNAT, so port forwarding wasn't an option.
  • Bound Pi-hole's DNS and admin ports to the Tailscale address only.
  • Fixed a startup problem. A fresh container inherited Tailscale DNS, which is the Pi-hole itself, so it couldn't download its blocklists. I gave the container its own resolvers.

How I tested it

  • Ran nmap scans from the same Wi-Fi, from another network and from inside the tailnet. The ports were filtered from outside and open only inside the tailnet.
  • Opened a test domain on my phone over 4G. The query showed in the Pi-hole log, first forwarded and then blocked after I added the domain to the denylist.

Limits and trade-offs

  • The laptop is a single point of failure. If it sleeps, DNS stops for every device on the tailnet.
  • Docker on Windows hides client addresses, so every query shows one internal address.

Screenshots

  • Phone on 4G showing the test domain cannot be reached
  • Pi-hole query log showing the test domain blocked