I had heard about Pi-Hole years ago on a Linus Tech Tips video about it (click here). Since that point I have wanted to implement it, however, my first attempt miserably failed.
I want to take this moment to say that BT is a terrible ISP, and if you are able to leave it then you should. Their provided routers are locked down to a degree that Apple would the zealous of, and their predatory business model is that of “keep upselling vulnerable customers things they don’t need, so if they ever do want to leave they would have to give up all the add ons”. The original issue stemmed from the fact that their provided router does not allow you to set a custom DNS server, and this was fairly easily fixed just by buying 3rd party router (currently I use the TP-Link AX5400). The next issue comes from the fact that BT does not allow you to put their router into bridge mode, so currently, my new router is plugged into their router, which is plugged into the demarcation port on the wall. This does not present an issue currently, but I know it will when it comes to when I want to set up wireguard (I’ll explain why in that section).
PiHole is a network-wide ad blocker, and it does this through the power of DNS. DNS is a name resolution process that converts IPs to domain names, and it is both simple and complicated at the same time. Without getting into the rigmoral of root domains and top-level domains, the process of resolving an IP is as follows.
- The client reaches out to the DNS resolver server looking for the address of
eddiequinn.xyz
. If the resolver has the IP it will respond back to the client with an IP address. If not it continues to step 2 - If the DNS resolver has the address of the
.xyz
TLD server, you can move on to step 3. If not it will reach out to the DNS root Name Server. The root server responds with this address, and we move on to step 3. - etc.
Essentially the name resolution process works on a hierarchy, where each part of the domain has a name server that reaches out to another domain server and it goes down the chain until eventually you get the IP for eddiequinn. xyz
. The place that pi-hole fits into this, is it has a list of all the major advertisement domains and if a name resolution request is made to it for one of these ad domains pi-hole will return 0.0.0.0
. If this domain is not in the list it will forward the request to the DNS resolver that you would normally use if PiHole wasn’t there. While this is awesome, this is not the only reason I wanted to bring in PiHole. One of the other reasons is that as I scale out my home lab, I ideally don’t want to remember a list of IPs - I would much rather type in pihole.box
to reach the web server rather than 10.0.1.2
. Thankfully, given that Pi-hole is fundamentally a DNS server, it has a local DNS option which allows this. The other benefit is that I can set it up so PiHole calls out to another self-hosted DNS server, unbound.
Unbound is a recursive DNS server, which is a type of DNS server that is responsible for fully resolving DNS queries by recursively traversing the DNS hierarchy. Recursion in this context means the resolver follows a chain of authoritative DNS servers from the root down to the specific domain being queried to find the answer. The primary role of a recursive DNS resolver is to provide complete and accurate DNS resolution for client requests. This is different from an authoritative DNS server, which is responsible for holding and providing authoritative DNS records for a specific domain. It doesn’t perform recursive resolution but instead returns authoritative answers for queries related to the domain(s) it is responsible for. The main benefit of this is that my DNS server is now reaching out to the name servers directly, rather than going through a service like Google, or god forbid my ISP. This has the major benefit of increased privacy, and reduced dependency on external services.
First and foremost in the process, I installed Ubuntu onto my Raspberry Pi 4 - I made the mistake of using the Raspberry Pi imager during this process, in future, I will just use the dd
command. I say this because it came prepackaged with a lot of things I didn’t want i.e. an Ubuntu user. Once it was installed I did some basic hardening: setting up automatic updates; creating a non-root user; setting up SSH public key authentication; hardening SSH; adding a firewall. These are all general steps I follow on every server I deploy, and I don’t think there is any excuse not to. Also worth mentioning, I gave it a reserved IP address, to avoid setting it statically on the machine - this will mean less administrative overhead in the future. Once the basic preparation was done, it was time to install pi-hole using curl -sSL https://install.pi-hole.net | bash
. This drops you into an install script, of which I just accepted all of the basic settings. Following this and updating the firewall to allow ports 80
and 53
PiHole was up and running
Now for Unbound, which is a tad more complicated than PiHole. This is mainly because it requires you to “write” your own configuration profile - luckily PiHole has a premade one here. I installed it using apt
, and copied the configuration file to /etc/unbound/unbound.conf/pi-hole.conf
. Theoretically, I could do some tinkering in this file in the future, but for now, it works fine. One thing of note is that Unbound on this configuration uses port 5335
- It seems obvious, but it does this because the standard DNS port 53
is already locally assigned to PiHole. After this, I started the service using service unbound start
and performed a dig request on eddiequinn.xyz using localhost:5335 to make sure it was working. After confirming that, I pointed the upstream DNS server on PiHole to 127.0.0.1#5335
.
For now, the system works but there are a couple of things I want to note down for the future:
- It is quite annoying that I have to type in
pihole.box/admin
to access the console, rather than justpihole.box
- I’m pretty sure this will be an easy fix, but I’ll do it another day - When I eventually segment my network to create a guest subnet, I’ll have to think about what to do regarding DNS requests then. Do I still want to sinkhole them mainly?
- In future, especially once I get a K3S cluster going, there is a way to make a high-availability PiHole instance. Something to bear in mind if the time ever comes