STFN

Using PiHole and Tailscale to block ads on all my devices, including mobile

10 minutes

This post is a continuation of my WireGuard and PiHole for secure ad blocking on your smartphone post. I’m writing it because I changed my PiHole setup and wanted to showcase it. Also PiHole released version 6, which changes a lot, and I thought it would be good to write about the new way of configuring it.

My Fairphone 4 with the PiHole admin interface opened in Firefox. The queries graph is mostly empty because I reinstalled PiHole on a new server.

I recommend reading the previous post as well, there I talk about some things not mentioned here, like reasons for restricting DNS server access from the public Internet, I did not want to repeat myself too much.

Here’s my current situation:

I am running PiHole on a Hetzner VPS. The server is a part of my Tailscale Virtual Private Network (VPN). The PiHole DNS service and its admin panel are only accessible via Tailscale, they are shielded from the open Internet by the firewall and PiHole interface restrictions. The PiHole VPS is configured in the Tailscale settings as the DNS server of the network, so any of my devices connected to Tailscale will use PiHole as its DNS automatically. This way I can use PiHole ad blocking anywhere I am, with any device, even my mobile phone, just by connecting them to Tailscale.

And now, how did I achieve that?

Setting up the machine

The first requirement is a machine that PiHole will be running on. It can be a Raspberry Pi, or any local computer, it can also be a rented VPS. The only requisite is that it has a stable and low-latency Internet connection. I went with a VPS, because I plan to also run public services on it. Running it on a local machine, not reachable from the open Internet will make the setup easier. In that case you can skip most of the security steps like setting up the firewall. Or you can do them nonetheless, it won’t hurt :)

I bought the cheapest available VPS from Hetzner. I went with the preferred way of providing SSH keys instead of password authentication, and this is what I highly recommend for security. After SSHing into the new server I went through the usual initial setup and hardening steps, described very well in Initial Server Setup with Ubuntu article on DigitalOcean .

For now, open ports 22 (SSH), 80 (HTTP) and 443 (HTTPS) when configuring the firewall:

sudo ufw allow OpenSSH
sudo ufw allow "Nginx Full"

Installing Tailscale

All the different ways to install Tailscale are described in the installation docs. There’s also an Ansible Collection for Tailscale if you’re into such things.

Installing Pihole

PiHole can be installed from an installation script. On the installation page in the docs I went with the last option “Alternative 2: Manually download the installer and run”. Before running the install script I gave it a quick run down. Still, not the safest option, but I felt it to be just a tiny bit safer than just piping curl to bash.

In the PiHole initial configuration wizard, on the “Choose an interface” step, I chose tailscale0. If there is no such option for you, make sure you have Tailscale properly installed and running. However, even with choosing the right interface, I encountered interface problems later on, more on that soon.

PiHole initial wizard, choosing the interface step

And write down the admin password before you close the wizard! If you are like me and forgot to do it, you can always reset it by running

pihole -a -p

in the VPS console.

Enabling Pihole

You should now be able to access the PiHole admin panel at http://<vps_ip>/admin. The admin panel is accessible, but the DNS service that PiHole needs to work is still being blocked by the firewall. To enable it run

sudo ufw allow in on tailscale0 to any port 53

This will open the DNS port 53, but only for the tailscale0 interface, meaning that only machines talking to the VPS through the Tailscale VPN will be able to reach it. This is a security measure to stop anyone from the public Internet using our new DNS server.

PiHole DNS service can now be reached, but it will still not work with any clients. To finish the setup we need to go to the PiHole settings in the admin panel.

In the admin interface go to Settings -> DNS, and start with switching to Expert settings. This will show a new box, “Interface settings”. Most probably it will be on its default settings “Allow only local requests”. This will not work for us, as PiHole does not consider the Tailscale network to be local.

PiHole DNS settings, the interface name is missing

Now, when I first opened those settings, I had the interface name span empty in the “Respond only on interface” option. Not sure if I did something wrong, or if there is a bug. If you right away have an option “Respond only on interface tailscale0” then just select it and skip the next paragraph. If not…

Setting the interface name

Go to All settings and scroll down to the dns.interface box, and set it to tailscale0. Save & Apply. Go back to the DNS options and now the interface options should show and work properly.

Testing it all

Now PiHole DNS should work. From any other client connected to the same Tailscale network as our PiHole machine, try out DNS resolving. I use the nslookup tool that can be installed on any Linux machine. For Windows or Mac machines: sorry, I have no idea.

First try:

nslookup en.wikipedia.org <vps tailscale IP>

This should return a successful response with the Wikipedia IP address.

Then try:

nslookup en.wikipedia.org <vps public IP>

This should timeout, because DNS is not reachable from the public internet, as we defined in the firewall and Pihole settings.

If you have different results go throught the previous steps and make sure you have everything configured correctly.

Configuring Tailscale DNS

In the Tailscale admin panel go to DNS settings, and under Nameservers enable the “Override DNS servers option” and add a new Global nameserver, paste the PiHole machine Tailscale IP. Not the public IP, the Tailscale one.

And boom, le voila por favor, now every machine connected to your Tailscale network will automagically use PiHole as its DNS server, and so will have ads and trackers cut out.

Restricting access to Admin Panel

As I said in the beginning, I am deploying PiHole on a VPS that also has other, publicly accessible services. And I don’t want for the PiHole admin panel to be publicly accessible, it should also be restricted to only my Tailscale network. I also don’t care that much about providing a TLS certificate for it, as it’s shielded by the VPN.

Changing the admin interface port

To do that I went in the admin panel to All settings -> Webserver and API and in the webserver.port box I replaced everything in the Value box with just 8080. The current connection the admin panel will be broken if you do this change, but that’s fine. Now in the VPS console run:

sudo ufw allow in on tailscale0 to any port 8080

This will do the same as with the DNS port 53, enable connections on the port 8080 only through the Tailscale network. The admin panel can now be accessed only through http://<vps_tailscale_ip>:8080/admin/

PiHole on the phone

To use PiHole on your mobile phone, just install the Tailscale mobile app and login to your account. No other actions needed, your phone will now use PiHole as the DNS, and a lot of unneeded or straight malicious traffic will be cut out, wherever you are. How cool is that?!

There’s one downside however, the Tailscale application is a bit of a drain on the battery from what I observed, but I can life with that.

Bottom Line

And that’s basically it. I have been running this setup for months now, and at this moment it would be hard for me to live without an ad blocker on all my devices. Thank you PiHole team for making such an awesome tool, and just a reminder that they accept donations for their hard work.

If you enjoyed this post, please consider helping me make new projects by supporting me on the following crowdfunding sites: