DEV Community

Cover image for The Ultimate ad-blocker: Configuring Pi-Hole with Unbound DNS

Posted on

The Ultimate ad-blocker: Configuring Pi-Hole with Unbound DNS

Ads: hate 'em

If you're like me, you hate ads disrupting your internet experience and slowing down your machine. This is especially true with news sources and other traffic-heavy sites.

Like many, I have an adblocker installed on all browsers to help reduce visual clutter, but there are a few inconveniences with it:

  1. Sites know when you have an adblocker enabled for a couple reasons, one of which is because a lot of the time they hide images behind the advertisements, so when the ad is removed the image is now unhidden, which tells the site the user has an adblocker.
  2. Adblockers are cosmetic and do not prevent ads from entering the network, so it still slows down browsing, sometimes considerably in my experience.
  3. Adblockers are single-machine only! I want to protect all my devices simultaneously with the same whitelists/blacklists.

Enter: Pi-hole to the rescue!

Pi-hole: what's that?

From the GitHub project README, Pi-hole is a DNS sinkhole that protects your devices from unwanted content, without installing any client-side software.

PiHole Architecture

It works at the network-level to prevent advertisements coming in to any device that is connected to that network.

I like to think of it in terms of a bait and switch: ad sites are baited by the request made from the DNS but a switch in IP addresses has been made between the IP address of the ad site, and the one that your computer ends up seeing when you receive the response.

So what ends up happening is that your computer just sees a blank page, and the advertisement is sent to some proverbial sinkhole!

I mostly followed the normal installation process, with a few caveats:

  1. I manually downloaded the installer before running
  2. I used Unbound DNS instead of Google, Cloudflare, or the other options you can select during setup (and made some specific configuration changes)
  3. I used an existing Nginx webserver instead of Lighttpd

You don't have to do these things, but if you're interested how/why I did them, keep reading!

Setting up Pi-hole

PiHole Install Art

I won't go into how to set up a Raspberry Pi and get a static IP address here, but there many helpful articles that can guide you thru it! I am using a RPi 3 Model A+ that just sits on my desk, but you can use any Linux machine.

Raspberry Pi 3 on my desk

Like I said, I didn't do much the first time around when I set up Pi-hole, other than manually downloading the installer:

wget -O

Then running it in my home directory:

sudo bash

This will take you thru the setup. I selected to have the web interface and server (admin portal) on, running in anonymous mode (to get aggregated anonymous statistics), and initially selected Google as the upstream DNS server.

This last selection will be changed after Unbound is installed and configured.

Once Pi-hole is set up, mosey over to /etc/pihole and create a whitelist.txt file. Initially, I just pasted this list of domains into the file, and saved it. (If you're using a RPi, you may need to sudo write to the file.)

I did a similar thing for the blocklist, using this aggregated list from Reddit.

The blocklist is updated at 5:00am CST by changing the Pi-hole cron job located in /etc/cron.d/pihole, and the whitelist is updated at 5:05am CST, setup in the system crontab located in /etc/crontab. The blocklist is provided for you, I just changed the times it pulls the new ad sources. The whitelist is what is added manually by you; those sources are pulled from here.

Lastly, I edited /etc/pihole/pihole-FTL.conf to disable long term data storage in SQLite by setting:


So all stats are wiped every morning.

Choosing the DNS

Quickly: what is DNS

I did not know much about network programming before deep-diving into setting this up with a housemate; I didn't even know what a DNS really was.

All I knew is that I use HTTP to access websites, which have a domain name (like I also knew that my own computer had a unique identifier in the form of an IP address that gave the green light to these websites so I could access content.

DNS stands for Domain Name System, and what I was missing was that websites have their own IP addresses, and DNS is the process of translating the domain names into those IP addresses. The way a red light turns to green, so to speak.

The DNS servers used on your computer are probably specified by your ISP (internet service provider), but you don't have to use them. How you can change them, and why you'd want to, are good questions to ask, but I won't detail them here!

Anyway, there are two types: recursive DNS servers and authoritative DNS servers. Briefly, authoritative servers can satisfy queries from their own data without needing to query another source. Google Cloud DNS is an example of this. DNS Recursive servers are like a middleman: on behalf of the client, they resolve any query by traversing the path of the domain across the Internet to deliver the answer to the question. They can cache the results to make it faster the next time around.

How DNS Works


Unbound has a really nice about page that goes in-depth about the product. Concisely, Unbound is a recursive DNS that focuses on security and privacy.

You can configure Unbound using this short guide, and then you can re-run your Pi-hole installation script to re-select the upstream DNS provider.

The last thing I did was update the configuration file located in /etc/unbound/unbound.conf.d/pi-hole.conf to do a couple of things:

  • Only let Unbound query authoritative servers (not other recursive servers). This is to prevent leaking queries to a middle man. To do this, remove these lines:
  name: "."

There are other optimizations that can be made, but they are dependent on your network environment. These are things like number of threads, message cache size, and a few others.

Using Nginx

I had already created a webserver to use as a testing ground for my webpages, so I wanted to use the same server, just a different port.

To do this, I had to install php-fpm and then alter the Nginx configuration file at /etc/nginx/site-enabled/default to parse PHP:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html index.php;

    server_name _;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404
        try_files $uri $uri/ =404;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.3-fpm.sock;

    location ~ /\.ht {
        deny all;


Pi-hole is a great out of the box piece of software to take control of your browsing experience, but it is a bit fickle to configure everything to satisfy your particular tastes.

Unfortunately, Pi-hole does block some normal websites. There is no way around it from what I can tell: there are always going to be some false positives. You'll need to keep manually updating the whitelist to deal with these as they come.

Some browsers respond better to Pi-hole than others: Chrome seems to only partially use Pi-hole, because it is given an inconsistent response time. Firefox and Safari are roughly consistent. If you use Chrome, its best to have a backup server of Cloudflare or Google, in addition to Unbound.

This setup has had me jump down more rabbit holes than I anticipated, and I learned a lot because of it. If you take the time to do the same, I believe you can learn something about network programming too! Hopefully I'll also be able to see your writeups when you're finished 😎

Top comments (11)

slavius profile image

Isn't it that Pi-hole uses dnsmasq (a recursive DNS resolver) itself that you can point to any DNS server you want? Why the need to use another DNS resolver? Did I miss something? Maybe better would be to setup a DoH (DNS over HTTPs) to enhance the privacy?

jldohmann profile image
Jesse • Edited

Isn't it that Pi-hole uses dnsmasq (a recursive DNS resolver) itself

dnsmasq is a DNS forwarder that can cache results. Unbound is a recursive resolver that can also cache results. If dnsmasq doesn't have the answer, it will pass the query to the upstream DNS, which can be anything you want, including Unbound.

Maybe better would be to setup a DoH (DNS over HTTPs) to enhance the privacy?

I don't know enough to say. I think with recursion, it makes sense to minimize middle men who get the query. With DoH I think that would introduce a middle man. So my setup would go from:

client -> unbound -> authoritative DNS


client -> DoH -> Google -> authoritative DNS

So there is nothing preventing Google from storing the query, which is not something I want πŸ˜…

The GitHub issue I linked to has another link to a longer discussion for the caching optimization (which requires disabling dnsmasq caching), and may have more specifics

slavius profile image
Info Comment hidden by post author - thread only accessible via permalink

No, no, no. Pi-hole comes by default bundled with dnsmasq (at least on my Arch). The client is pointing his/her DNS settings to DNS resolver under Pi-hole control so Pi-hole can intervene and return not-found or invalid IP for blocked domains. That's the whole point.

So by default you have:
client -> Pi-hole DNS (dnsmasq) -> recursive query to Google, Quad9, CloudFlare, OpenDns, Level3, Comodo, DNS.WATCH

You'd introduce additional DNS resolver in the middle somewhere which has no obvious benefit to me.

It's all in the Pi-hole settings. Pi-hole has predefined settings to access all aforementioned DNS providers over IPv4 or IPv6. There's nno need to configure any additional DNS resolver.

BTW, whether the resolver is recursive or not is matter of configuration rather picking another resolver. Dnsmasq, unbound, knot or plain bind can all act as recursive caching resolvers. Even from command line the tool dig can act as recursive or not.
dig @ +recurse +trace

Regarding DoH, there might be some misunderstanding. The DoH tunnels your DNS request over HTTPS, encrypted from the point within your browser or Pi-hole to the last exit node, which then resolves it and relays the answer back over the same HTTPS tunnel. The obvious benefit is that nobody on the path, be it your hotel WiFi provider, his ISP or sneaky admin can see the DNS requests you are sending. Then if thousands of users are using it it looks like a single public IP address is resolving all possible DNS records and it is not easily possible to track the DNS requests back to you.
The DoH providers are not Google and without investigators having access to the logs of the DoH provider it is not possible to trace DNS requests back to you.

slavius profile image

You seem to be right, dnsmasq does not support recursive queries. However using unbound does not solve your privacy concerns as unbound in recursive mode sends all DNS requests to your preconfigured upstream DNS anyways. so sends DNS requests for ".", "com", "" and "". If your concern is Google tracking you, use different DNS provider or public DoH (like the one by Mozilla in Firefox).

Thread Thread
jldohmann profile image

No, no, no. Pi-hole comes by default bundled with dnsmasq (at least on my Arch). The client is pointing his/her DNS settings to DNS resolver under Pi-hole control so Pi-hole can intervene and return not-found or invalid IP for blocked domains. That's the whole point.

Yes, I understand this. But it doesn’t know where legitimate sites are. Its these requests that are forwarded to an upstream, recursive server. Unbound is that server for me. Cloudflare and Google are big providers and susceptible to attackers. Using Unbound as a local recursive DNS server reduces this risk. I thought that was cool and wanted to use it and that's why it was chosen.

Like I said in the post, I think Pi-hole is really great out of the box software, but it wasn't what I wanted. You're welcome to disagree with that. There is a lot I didn't explain in the post and linked to that could be read for additional context, and that was intentional.

Thread Thread
slavius profile image

Cloudflare and Google are big providers and susceptible to attackers

Well I have to disagree with that. They are IMHO least susceptible to attackers. It is far more easier and less suspicious to poison local DNS cache than that of Google or CloudFlare protected by numerous technologies, constantly monitored on all possible ISO/OSI layers, where millions of worldwide users would notice if something is off immediately and start reporting over their servicedesk and on Reddit. That simply does not make any sense.

Thread Thread
jldohmann profile image

Your comments are not constructive. Please do not comment on this post again. Thanks

thomasbnt profile image
Thomas Bnt β˜•
jldohmann profile image

These are awesome! Thanks for sharing. Definitely gonna use this dark theme πŸ™‚

tagware profile image

Guys. You need to ensure that the browser itself has not had the DESEC setting applied, otherwise the browser will ignore the PI-Hole DNS and talk directly to

So, once you have "Unbound" setup and working with DESEC confirm. Turn off the option at the browser level. :o)

whatitdojames profile image
cranky james

you mention that you setup the pihole to use your nginx server instead of lighttpd but when you said you initially ran the setup script that you turned on the web interface, and server/admin portal (default? lighttpd?) ... at what point did you switch to nginx and tell the pihole config that you did so?

Some comments have been hidden by the post's author - find out more