We're going to setup a Raspberry Pi 4B computer as a Pi-hole device. The goal is to minimize annoying ad traffic, especially as Proposition 24 in California has passed. Since I'm not up for paying for quality-of-service or "play-to-play," I've decided to try rid myself of the annoyances in another way.

If you're not familiar with the Pi-hole project, check it out here: https://pi-hole.net/

OS Installation

Our Pi needs an operating system. From their official documentation, this is the route I took: https://www.raspberrypi.org/documentation/installation/noobs.md

  • Download the Raspberry Pi Imager software, run it, and install your flavor of OS. I choose Ubuntu Server 20.10 since I'm familiar with it.
  • Next, select your microSD from the list. I used a Sony camera as a medium since that's all I had as a reader/writer device!
  • Write!
  • Writing the OS to the microSD card might take some time. For me, it took about 15 minutes. Once the OS is on the card, you can just slap it into the Pi.

Next, we need to physically setup the Pi and start it up. The Pi immediately starts when connected to power and the Ubuntu OS just loads and prompts you for a login. I ended up connecting to it via the tty and set a password initially. I then immediately went back to my desktop and connected via SSH.

I wanted to test the speed of this SD card. It's not going to break any records. Note that the microSD card I used is an older 16GB U1 device.

root@ubuntu:~# dd if=/dev/zero of=1gb_file bs=1024k count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB, 1000 MiB) copied, 68.4339 s, 15.3 MB/s

It should suffice, let's check the space real quick:

root@ubuntu:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           383M  4.0M  379M   2% /run
/dev/mmcblk0p2   15G  2.9G   11G  21% /
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           4.0M     0  4.0M   0% /sys/fs/cgroup
/dev/mmcblk0p1  253M   58M  195M  23% /boot/firmware
tmpfs           383M  4.0K  383M   1% /run/user/1000

Lastly, I ran apt update and set the hostname.

root@ubuntu:~# hostnamectl set-hostname pi

Good enough to proceed!

Pi-hole Installation

Next, let's install the Pi-hole service. Their documentation makes it really simple. The install is launched with a shell command, and throughout some TUIs are shown. I ended up choosing mostly default options for this initial setup just to breeze through.

root@ubuntu:~# curl -sSL https://install.pi-hole.net | bash

  [✓] Root user check

        .;;,.
        .ccccc:,.
         :cccclll:.      ..,,
          :ccccclll.   ;ooodc
           'ccll:;ll .oooodc
             .;cll.;;looo:.
                 .. ','.
                .',,,,,,'.
              .',,,,,,,,,,.
            .',,,,,,,,,,,,....
          ....''',,,,,,,'.......
        .........  ....  .........
        ..........      ..........
        ..........      ..........
        .........  ....  .........
          ........,,,,,,,'......
            ....',,,,,,,,,,,,.
               .',,,,,,,,,'.
                .',,,,,,'.
                  ..'''.

  [✓] Update local cache of available packages

  [✓] Checking apt-get for upgraded packages... up to date!

  [i] Installer Dependency checks...
  [i] Checking for dhcpcd5 (will be installed)
  [✓] Checking for git
  [✓] Checking for iproute2
  [✓] Checking for whiptail
  [i] Checking for dnsutils (will be installed)
  [i] Processing apt-get install(s) for: dhcpcd5 dnsutils, please wait...
--------------------------------------------------------------------------------

First TUI which presents some choices that you go through. Again, I went mostly default. If you need to changes settings post install, Pi-hole is totally flexible and will allow it via the CLI or web admin UI.

More output...I also chose to install the web UI. Seems cool enough and the Pi I have is powerful enough.


  [✓] Enabling lighttpd service to start on reboot...
  [✓] Creating user 'pihole'

  [i] FTL Checks...

  [✓] Detected ARMv7 processor (with hard-float support)
  [i] Checking for existing FTL binary...
  [✓] Downloading and Installing FTL
  [✓] Installing scripts from /etc/.pihole

  [i] Installing configs from /etc/.pihole...
  [✓] No dnsmasq.conf found... restoring default dnsmasq.conf...
  [✓] Copying 01-pihole.conf to /etc/dnsmasq.d/01-pihole.conf

  [i] Installing blocking page...
  [✓] Creating directory for blocking page, and copying files
  [✓] Backing up index.lighttpd.html

  [✓] Installing sudoer file

  [✓] Installing latest Cron script

  [✓] Installing latest logrotate script
  [i] Backing up /etc/dnsmasq.conf to /etc/dnsmasq.conf.old
  [✓] man pages installed and database updated
  [i] Testing if systemd-resolved is enabled
  [✓] Disabling systemd-resolved DNSStubListener and restarting systemd-resolved
  [✓] Restarting lighttpd service...
  [✓] Enabling lighttpd service to start on reboot...
  [i] Restarting services...
  [✓] Enabling pihole-FTL service to start on reboot...
  [✓] Restarting pihole-FTL service...
  [i] Creating new gravity database
  [i] Migrating content of /etc/pihole/adlists.list into new database
  [✓] Deleting existing list cache
  [i] Neutrino emissions detected...
  [✓] Pulling blocklist source list into range

  [✓] Preparing new gravity database
  [i] Using libz compression

  [i] Target: https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
  [✓] Status: Retrieval successful
  [i] Received 58501 domains

  [i] Target: https://mirror1.malwaredomains.com/files/justdomains
  [✗] Status: Not found
  [✗] List download failed: no cached list available

  [✓] Storing downloaded domains in new gravity database
  [✓] Building tree
  [✓] Swapping databases
  [i] Number of gravity domains: 58501 (58501 unique domains)
  [i] Number of exact blacklisted domains: 0
  [i] Number of regex blacklist filters: 0
  [i] Number of exact whitelisted domains: 0
  [i] Number of regex whitelist filters: 0
  [✓] Flushing DNS cache
  [✓] Cleaning up stray matter

  [✓] DNS service is listening
     [✓] UDP (IPv4)
     [✓] TCP (IPv4)
     [✓] UDP (IPv6)
     [✓] TCP (IPv6)

  [i] Pi-hole blocking will be enabled
  [i] Enabling blocking
  [✓] Flushing DNS cache
  [✓] Pi-hole Enabled
  [i] Web Interface password: HCK7tZ5_
  [i] This can be changed using 'pihole -a -p'

  [i] View the web interface at http://pi.hole/admin or http://192.168.1.155/admin

  [i] You may now configure your devices to use the Pi-hole as their DNS server
  [i] Pi-hole DNS (IPv4): 192.168.1.155
  [i] Pi-hole DNS (IPv6): fd65:2ee2:5c65:0:dea6:32ff:fe7f:c555
  [i] If you set a new IP address, please restart the server running the Pi-hole

  [i] The install log is located at: /etc/pihole/install.log
Installation Complete!

Finally, you will get one final TUI, like so:

That's it! The installer is very well polished and a joy to use.

Lastly, I updated the web UI password, like so:

root@pi:~# pihole -a -p
Enter New Password (Blank for no password):
Confirm Password:
  [✓] New password set

Setup Router to Use Pi-hole as DNS Server

With the pi-hole service running, I need to setup my clients to use it. I'm running a device with OpenWRT installed. To adjust the DNS settings, you have to modify the LAN interface, similar to the images below. This will force the router to send modified  DHCP options to the clients.

...and

Once that is done, you can apply the change and your clients should start getting their DNS request forwarded to the pi-hole service (you may need to refresh the DHCP leases via reboot or manually). I also setup the pi-hole to have a static lease so its IP doesn't change. This is an important step as you could just accidentally send DNS requests to some other host if the IP were to change and things would be...very broken.

Testing Effectiveness

I didn't test too much with any quantitative metrics, but here's some screen caps showing improvement.

Before adjusting the DNS server in router, not much going on.

After adjusting DNS server in router, we can see the traffice rolling in. It comes quickly!

Also, as we can see, the cnn.com site is less cancerous.

I also found this page: http://fuzzthepiguy.tech/adtest/

Seems good! I'll start driving my network around more and see what other improvements I notice, but so far, so good.

Conclusion

I was expecting this install and deployment to take a lot of time. Surprisingly, this took about an hour without much ado. Assuming you're familiar with all the technologies involved, it's not terribly difficult to accomplish. I would seriously recommend this setup. The Raspberry Pi is a cool device and the Pi-hole service is perfect for it. I may slap some more services on the Raspberry Pi in the near future but Pi-hole was the killer service I wanted first.

Lastly, I'd recommend donating the Pi-hole project: https://pi-hole.net/donate/