The Ultimate ad-blocker: Configuring Pi-Hole with Unbound DNS
Tags: webdev, dns, server, network
Published: 2020-03-01 21:31:29

## 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](https://github.com/pi-hole/pi-hole/blob/master/README.md), _Pi-hole is a DNS sinkhole that protects your devices from unwanted content, without installing any client-side software._

![PiHole Architecture](https://dev-to-uploads.s3.amazonaws.com/i/4e5jcjg78zxe8ajuus1l.png)

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](https://dev-to-uploads.s3.amazonaws.com/i/ec32tha6zankec278t0b.PNG)

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.

<img src="https://dev-to-uploads.s3.amazonaws.com/i/209ymalhsl6i7pbv4pnj.jpg" alt="Raspberry Pi 3 on my desk" width="500"/>

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

```bash
wget -O basic-install.sh https://install.pi-hole.net
```

Then running it in my `home` directory:
```bash
sudo bash basic-install.sh
```
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](https://raw.githubusercontent.com/raghavdua1995/DNSlock-PiHole-whitelist/master/whitelist.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](https://firebog.net/) 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](https://github.com/anudeepND/whitelist).

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

```
MAXDBDAYS=0
```

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 www.google.com). 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](https://dev-to-uploads.s3.amazonaws.com/i/8lcc4rb8p6419ts35h8k.png)

### Unbound

Unbound has a really nice [about page](https://www.nlnetlabs.nl/projects/unbound/about/) 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](https://docs.pi-hole.net/guides/unbound/#configure-unbound), 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:

```
forward-zone:
  name: "."
  forward-addr: 8.8.8.8
  forward-addr: 8.8.4.4
```

- Adding caching, which is explained [here in this GitHub issue](https://github.com/pi-hole/docs/issues/207).

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;
    }
}
```

## Conclusions

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 😎