Skip to content

BIND9 or Pi-Hole: Which One Is Better?

  • 16 min read
Bind9 vs Pi-Hole

In the words of the great Harry Hill: there’s only one way to find out…FIIIIGHT!!

And a fight it turned out to be. Not because there’s anything difficult about what I’m trying to do, it’s mainly because I’m an idiot from a corporate world of Windows servers.


What’s the goal here?

In the post: Tasting The Raspberry Pi(e), I’ve blathered on (at length) about running my own internal DNS server. Not only that, I wanted it to perform secure DNS lookups from a secure DNS provider, like Cloudflare or Google (actually, probably not Google. Big corporate behemoth that it is).

And that is the goal: setup a DNS server on a Raspberry Pi, point all of my network devices to it for DNS lookups and be able to browse internal resources from devices like my phone, or android tablet. That’s it.

Preparation

A bit of preparation first, however. My router was configured to use my ISP’s DNS addresses for its network connection, so I needed to change that. The router also issues DHCP leases to my network devices. I’ll need to access that a little later on, both to get my new server address and to swap over the client DNS addresses to the new server when built.

Following a bit of internet reading, I decided to use Quad9 as my DNS provider of choice. Quad9 doesn’t log anything on their servers, they provide a public DNS that is both encrypted and plain, have a blocking service that you can use (or not) and have quite an upstanding privacy policy. So I changed my router DNS addresses to 9.9.9.9 and 149.112.112.112 respectively.

In the interim period between then and commissioning the new DNS server, all my network clients pointed towards my router for DNS resolution – which now of course points to Quad9. All good so far.


The basics

The subject of building, configuring and testing isn’t extensively covered in Tasting The Raspberry Pi(e), so I’ll do that here, in slightly more detail. With my mistakes, obviously.

What am I going to need? A server and some software.

A server

A nice red and white case for a Raspberry Pi 5

For the server, I bought a Raspberry Pi 5 (RPi5), with its appropriate power supply and a lovely red and white case to put it in (which came with a cooling fan and a heatsink!). I also bought a 32Gb SD card to use as the “hard drive”, along with a USB micro SD card reader to plug into my laptop to flash the card with.

Quite early on, I discovered ThePiHut, which was great resource for me to start with – especially as I knew nothing about RPi machines. They did a starter kit for £82 of my finest English Pounds, which had most of the above in it, the only thing I had to add on to that was a card reader, which was £4.

A bit later on, I bought a 90 degree USB-C adaptor for the power cable, only because I had it on a shelf at such an angle, it was straining the power cable a bit. ThePiHut also sells those (of course they do!), but say they’re only for RPi4 machines. Probably because if you put it in a certain way, it’ll cover the HDMI ports so you can’t use them. Not that it’s a problem, as they’ll be headless anyway.

Some software

Nothing to actually buy concerning the software, of course. The Raspberry Pi official website is a wealth of information about everything RPi (as you would expect) including documentation, tutorials and forums. Software is also available for download, including the Raspberry Pi Imager (something that I’d get to use often in the following few days).

So I’m all set and ready to start.


The plan of action

The plan was this:

  • Set up a base O/S and then either BIND9 or Pi-Hole on it.
  • Configure those so that they’ll resolve the required internal and external addresses, using the public secure DNS servers “open” (i.e. not secure) addresses as forwarders to start.
  • Then once that’s done, configure the secure DNS part of it.

Easy, right?

Going headless

One of the beauties of the RPi server is that the normal keyboard, mouse and monitor is not required to build and configure them. Instead, the RPi Imager software can be configured to install the O/S of choice, along with a user name, password and server name. Oh and it can install SSH in order to configure from afar (e.g. with PuTTY). It’ll initially start with a DHCP leased address, so whatever device is used to distribute those on the network will have to be monitored (my router in this case), in order to get the address.

I had to decide which O/S I was going to use and whether I wanted to use Pi-Hole or BIND9 as my DNS provider.

For the O/S choice, there’s only two that were available in the RPi Imager software that I’d consider using. One was the RPi O/S Lite (which is the RPi version of Debian 12 Bookworm, cut down without any of the desktop shenanigans). The other one was Ubuntu 24.04.2 – again cut down with no desktop software.

In terms of the DNS provider software, both Pi-Hole and BIND9 can be installed from the CMD line using the built in package manager, so that wasn’t an issue. I’d also decided to use Webmin as a kind of remote configuration/monitoring tool, as I’ve had a good deal of experience with it from building various Linux servers over the years (if it would go on, that is!).


Secure DNS

Meanwhile, I did some extensive research about what to use to provision the “secure” bit of secure DNS. There are only a few programs that would do it on Linux, dnscrypt-proxy was one of them, but that wasn’t incorporated in Ubuntu (but it is in RPi O/S). There was DNDdist and DNSmasq, but they didn’t appear to do secure DNS as an option. I looked at various (future) versions of BIND9: the very next version of the one I could install on Ubuntu or RPi would (apparently) support secure DNS natively. But it was only available on Debian 13 (unstable). All of these options would (in theory) do what I wanted, but there was a modicum of manual building, installation and maintenance that I wasn’t prepared to do at that time.

I had a few hours of back and forth on search engines, before I stumbled upon this article about installing a program called cloudflared to provide secure DNS with Pi-Hole. This looked promising.

That webpage is part of the documentation and tutorial section of the Pi-Hole website. I spent some time on that site, familiarising myself with what I about to build.

A plan was born

Now that I’d discovered a veritable wealth of information about Pi-Hole, I was ready to start doing some actual server building.

The plan was this:

  • Image a micro SD card with Ubuntu 24.04.2
  • Insert the card into the Pi and boot – get the IP address from network router.
  • PuTTY to the server, and do all the things that I need to do: change root password, updates.
  • PuTTY back in (after updates reboot) and install Webmin.
  • Use Webmin to set the hostname to an FQDN (fully qualified domain name), apply my https cert (for the Webmin web interface), assign a static IP.
  • Setup Webmin-ny things like package update notifications, email transport, system time sync with uk.pool.org and tidy up Webmin.
  • Install either BIND9 or Pi-Hole and setup the Quad9 servers as forwarders.
  • Configure BIND9 or Pi-Hole to host my internal domains DNS and assign addresses.
  • Test by doing various remote DNS lookups, using the new server as the DNS Server
  • If all that’s good, proceed to secure DNS setup

Cracking.


A series of unfortunate events

Or more like, “there’s an idiot at the wheel”. I’ll cut this process short for the sake of tedium, but I was doing this over and over for days!

Attempt number one was Ubuntu (24.04.2) with BIND9. All went reasonably well, and I set the server up as I would normally do. I did all the Webmin customisation and niceties and sat back to admire it all. It worked. I could successfully look addresses up with it, both internally and externally. Excellent.

Then I noticed that every time I issued a sudo command, I got back “sudo: unable to resolve host ubuntu.therigormortist.me” (ubuntu.therigormortist.me being the name of the server). Although it did continue to execute the command I issued. Odd. I looked it up. Yada-yada-hostname quoth the internet. I duly went off and fiddled with my /etc/hosts file until the error disappeared. Great. (Enter rolling clouds of foreboding-ness-icity.)

Cloudflared

I consulted the article from the Pi-Hole docs site about installing cloudflared. The document referenced Pi-Hole as the DNS server, but I considered it for a bit and determined that it didn’t really matter what the overall DNS mechanism was, cloudflared would be the secure forwarding method. So in theory, cloudflared would work with either BIND9 or Pi-Hole, it shouldn’t matter.

I duly installed cloudflared as described in the article and tested it. It worked a treat, as in it returned a “doh” response (meaning DNS-over-https, rather than a Simpsons doh!!). Great.

As I am wont to do, I restarted the server to see if was consistent. It wasn’t. It didn’t work. BIND9 wasn’t forwarding – but was working. I checked the cloudflared service – not running. Tried to start it: no.

Reset the forwarder in BIND9 back to the Quad9 plain servers. That worked OK. Cloudflared, inexplicably (to me at the time) also started back up and tested just fine.

Reset the forwarder back to cloudflared. It all stopped again. Hmm. Cloudflared said: “failed to create listening socket for port 53, permission denied.”. But it’s not supposed to be on port 53, it’s 5053 (I screamed at the void).

I did that all several times. I tried changing IP addresses of the BIND9 forwarders, network interface DNS, hosts file. Nothing worked.

OK. Maybe cloudflared doesn’t like Ubuntu (?). I’ll rebuild, but this time with RPi O/S Lite, Webmin and BIND9.

Waaaaaaaaaaah! It’s exactly the same

I built several servers over the next couple of days, all with exactly the same results, apart from cloudflared. I couldn’t get it to work at all in some builds and I couldn’t figure out why!

I decided to swap the DNS server of choice from BIND9 to Pi-Hole. It was exactly the same as with BIND9. I could get Pi-Hole to work just fine, Webmin worked fine on RPi O/S, but cloudflared wouldn’t work at all.

Days passed

Several of them, all with the same negative results. And still that nagging “sudo: unable to resolve host ubuntu.therigormortist.me” error.

A thought occurred to me. I am building these Linux servers as if I were building Windows servers in an Active Directory environment (because that’s what I used to do for a living). What if I just build the Linux server with no “Windows-isations”. That is, no FQDN allocation for the hostname, in fact leave /etc/hosts alone completely. Build an RPi O/S Lite server and only make minimal changes to it: the IP to a static (using nmtui), change the root password and apply updates. Then install Pi-Hole and cloudflared.

And that was exactly what I did. The server name is configured in the RPi Imager software anyway, so I didn’t have to do that. I just used nmtui to fix the static address and pointed its DNS towards my network router. That’s all I did (in terms of the server).

Although reticent about fiddling with the /etc/hosts file, I thought I’d add the servers IP address to it against the hostname, in a bid to resolve (ha!) the “sudo: unable to resolve host ubuntu.therigormortist.me” error. Which, much to my surprise, it did. I thought well, if it breaks something else, I can always take it out, it’s only one line.

I installed Pi-Hole, configured it a little so it would work as a DNS resolver and installed cloudflared. Pi-Hole worked great, cloudflared didn’t. Yet again.

Following much head scratching and staring at files, I noticed something. Looking through the cloudflared config files, I noticed that the service start file (/etc/systemd/system/cloudflared.service) didn’t have its section headings in colour, when viewing with nano. I remembered that the very first time I built cloudflared with Ubuntu and BIND9, it did. I also remembered that I had copied and pasted the config text from the Pi-Hole documentation website directly.

Now let’s bugger off on a tangent. It won’t take long.

I use a note taking app called Joplin. I absolutely love it, it's great. I'd copied the salient info from the Pi-Hole documentation website to a note in Joplin. Then I'd copied that info from Joplin and pasted it into my config file in a PuTTY session to my new DNS server. It turns out that (for a reason that I've not yet fully investigated) the text is pasted in a format that nano didn't like. I could tell, as all of the text was in the same colour (white), whereas if I'd copied and pasted it in from the Pi-Hole documentation website, the text became coloured. Not only that, the service would work correctly, whereas it wouldn't work if the text was all white. Isn't that a cute little foible (said nobody, ever)?

So with that out of the way, I checked to make sure that all of the config files looked like they had coloured text in them and started the cloudflared service. Successfully.

By that time, I’d also discovered that you could install the cloudflared program using a repository and the built-in packagae manager: apt. That’ll make it easier to update, rather than having to monitor for any updates and do it manually. So far so good on that one!

Success, my Lord!

As the Klingon said to the General.

Success indeed. Now I had a working Pi-Hole server, forwarding DNS requests to Quad9 over https (securely). Lovely.

Bearing in mind I had done the minimum in terms of software (to see if it would work), it was time to install Webmin and tcptrack (software to track any traffic on an interface).

Webmin. You bastard.

I don’t know why I did it (but I’m very glad I did!), but I thought at that point I’ll make a backup of the micro SD card. I use W32diskimager for that – an old bit of software, but it works. Booted up the laptop, inserted the USB microSD card reader and shut down the new DNS server. (Remembering to unplug the power first) removed the microSD card and took a copy (30 mins, approx.). Then replaced it, booted the server back up and installed Webmin. Did all the Webmin-ny stuff I like to do and all was well.

Or was it?

I started to configure Pi-Hole (and Webmin) with 2FA for security. I’d work on Pi-Hole for a bit, close the interface for that, then go to Webmin. Which I then had to relog in to. Odd, normally, that’s a cached session. Oh well. Did some work in Webmin, then closed the web interface.

Opened the Pi-Hole interface, which asked me to log in. Which I did. I then opened Webmin (at the same time as Pi-Hole) which asked me to reauthenticate… which then logged me out of Pi-Hole.

That told me that something was amiss somewhere in the authentication process for each application: but I couldn’t be bothered to find out what! Instead, I decided to not bother with Webmin, as the Pi-Hole server would do time sync and list any outstanding system updates anyway (which is basically all I would use Webmin for in this instance).

So I restored the backup image that I’d serendipitously taken and installed tcptrack.


Finally! A working server!

Indeed it is. Pi-Hole is working properly with cloudflared forwarding secure DNS requests to Quad9. No webmin, no Windows-isations. And it’s all working perfectly. I’ve configured my internal servers in the local DNS area (the advantage of this over BIND9 is that I don’t have to put the external records in as well). I’ve configured all the services I need to (apart from DHCP) and that’s all logging and working well, producing some interesting entries in the logs.

What about BIND9?

Given that the configuration difficulties were mostly down to me and not the software I was using, I decided to have a go at building Ubuntu with BIND9 to see if it now worked, especially copying the cloudflared config from the Pi-Hole docs website instead of Joplin. Just for fun, really.

I am pleased to say that it went flawlessly and worked perfectly, to the point where it was consistent and repeatable. And of course Webmin has no issue with Ubuntu, so that is all good too. But did I actually want to use BIND9?

By then, I’d had the opportunity for a glance at the capabilities of Pi-Hole. I knew a bit more about BIND9 (as I’d been using it for years), but Pi-Hole is so much more than just a DNS server, like BIND9. Pi-Hole could do DHCP for a start (OK, you could install a DHCP server on Ubuntu and configure it through Webmin), but it’s the local blocking and the statistics that attracted me towards Pi-Hole. It acts as a DNS sinkhole, using block lists similar to uBlock Origin (of which I am a big fan) to block DNS queries to return adverts and malicious websites (and more). Although Quad9 will do some filtering, I could configure Pi-Hole to do as much (or as little) as I wanted to. Running the network’s DHCP from there too, means that I get name to IP resolution, so I can see what device is trying to go where.

Yes indeed. I think I’ll go with a Pi-Hole server.

The Pi-Hole server was duly restored.

Give me that Pi!

After a day or so of uptime with out issue, I swapped the DNS settings on the router DHCP to point to the Pi-Hole, for all of the clients. That also produced some interesting results, but I couldn’t see what was making (blocked) requests out. For that, I needed to configure the Pi-Hole DHCP server as my home DHCP (instead of the router).

Two days later, I swapped that service over successfully, turning off the router DHCP first and then enabling the DHCP service on the Pi-Hole server.

I now have full stats and full visibility of what’s happening on my home network! And what’s more, I am using secure DNS.

Happy days in the Rigor Mortist house!