Setting up a Pi Hole for whole-home ad/tracker blocking

Pi Hole - Admin DNS query request dashboard page in Safari

Pi Hole is a nifty open source project that allows you to offload the task of blocking advertisements and annoying (and often malicious) trackers to a Raspberry Pi. The installation is deceptively simple (a curl | bash affair), but I wanted to document how I set up mine headless (just plugging the Pi into power and the network).

Set up Raspbian Lite

I bought a Raspberry Pi model 2 B along with the official Raspberry Pi foundation Case. Then I bought a Samsung Evo+ 32GB microSD card (which comes with a full-size SD card adapter), and did the following steps on my MacBook Pro to set up the Pi's OS:

  1. Download Raspbian Jessie Lite. Expand the downloaded Zip file.
  2. Insert the microSD card (in the SD adapter) into your SD card reader.
  3. Open Terminal, and run diskutil list
  4. See which disk the microSD card is (e.g. /dev/disk2), then unmount the card: diskutil unmountDisk /dev/disk2).
  5. Change directories into the directory where you downloaded Raspbian Jessie Lite (e.g. cd ~/Downloads).
  6. Run the following command to write the disk image to the microSD card: sudo dd if=2017-03-02-raspbian-jessie-lite.img of=/dev/rdisk2 bs=1m
    • Use the filename for the image version you downloaded; it might be different than the if shown above.
    • Note that the of (output) is using /dev/rdisk2—don't use /dev/disk2 because that will result in a much slower copy operation.
    • If you have pipeviewer installed, you can use pv yyyy-mm-dd-raspbian-jessie.img | sudo dd of=/dev/rdisk2 bs=1m instead to show copy progress.
  7. After the copy is finished, you should see a new boot SD card mounted on your computer.
  8. Create an 'ssh' file to tell Raspbian to enable SSH on boot (so you can log into the Pi remotely): in Terminal, run touch /Volumes/boot/ssh
  9. Eject the boot volume, and put the microSD card into your Raspberry Pi.

Note: Don't use WiFi for Pi Hole, because that would introduce a lot of latency for DNS calls. It's better to plug your Pi (no matter what flavor) into the wired network so it doesn't become a bottleneck for your Internet connection!

Set up the Raspberry Pi

  1. Plug your Pi into the network, and plug in power so the Pi will boot.
  2. Use nmap (e.g. sudo nmap -sP 10.0.1.1/24) or fing (e.g. sudo fing 10.0.1.1/24) to discover your Raspberry Pi's IP address (see how in my post on setting up a Pi as a remote time-lapse camera).
  3. Log into the Pi via SSH: ssh pi@ip_address (where ip_address is the IP of the Pi) — accept the hostkey by typing yes when prompted, then enter the default Pi password, raspberry.
  4. Set a static IP address: sudo nano /etc/dhcpcd.conf to edit the configuration, then add the following to the end (using the settings specific to your network/IP):

    interface eth0
    static ip_address=10.0.1.24
    
    static routers=10.0.1.1
    static domain_name_servers=10.0.1.1
    
  5. Reboot the Pi (sudo reboot) and log back in via SSH.

  6. Run sudo raspi-config to configure basic settings:
    • Set a new (secure) password.
    • Set a hostname (e.g. pi-hole).
  7. Restart the Pi after changing those settings.

It's a good idea to set a static IP address for your Pi—either in the Pi's own settings, or (preferably) on your network's router (if the router allows you to assign static IP addresses to devices based on MAC address).

Set up Pi Hole

  1. Install Pi Hole with curl -sSL https://install.pi-hole.net | bash
  2. Follow the entire Pi Hole setup process (it will ask you to confirm settings at a few different points).
  3. Note the admin dashboard password at the end of the install process; you can visit the dashboard afterwards and see DNS statistics.

Tell your router to use Pi Hole (for network-wide protection)

If you have a decent network router (in my case, I have an AirPort Extreme), you can use its administration interface to set up DNS settings for the entire network. Point the DNS at the Pi Hole's IP address, and then you should start seeing that all the network's DNS requests are routed through the Raspberry Pi's DNS. You should also note a lack of advertisements in your browsing :)

Alternatively, you can configure any of your computers to use the Pi Hole's DNS (instead of the router) if you don't want the Pi Hole to be used on the entire network.

Comments

Hi Jeff, I am getting 'could not resolve host' error on the set up stage.

Think it may be something to do with the static IP settings: interface eth0
static ip_address=10.0.1.24

static routers=10.0.1.1
static domain_name_servers=10.0.1.1

I presume the top one stays as.24, but what about the other two, are they the pi's IP address?

Thanks

The instructions in this post presuppose your local network is using the private IP range 10.0.1.0/16. If your local network uses a different range, you need to adjust all those settings. (E.g. if your computer is getting the address 192.168.x.x, then you'd need to use your network router address for the routers, your default DNS server (usually same as your router) for domain_name_servers, and an IP in that range for ip_address.

Hi Jeff. Since I have an Airport Extreme too, it was suggested I follow your instructions for installing pi-hole on my new Raspberry PI 3B, bought for that purpose. The good news is that pi-hole thinks it is working. The bad news is that when I point the primary DNS setting of the Airport Extreme at the pi-hole address, the Airport Extreme is happy with the change, but I lose access to the Internet from it.
Normally, I use the OpenDNS DNS servers, 208,67,222,222 and 208.67.220.220. I set the pi-hole up to also use those without issue as it was one of their main choices. My current suspicion as to the problem is that The Network Information for the System in pi-hole shows the Pi-hole IPv4 address as: 192.168.1.13/24, rather than its specific address of 192.168.1.13 and sadly, I'm not seeing a way to change that via the admin settings for pi-hole. I do have a DHCP reservation for the pi-hole at 192.168.1.13 set up in the Airport Express, and am using the OpenDNS Updater to make sure OpenDNS knows about our real Internet address for our home network's cable box if that ever changes. I know it is close to working because the pi-hole dashboard shows a lot of traffic, from lots of stations on my LAN to lots of domains on the Internet during the time I had the Airport Extreme trying to point its DNS at the pi-hole. Somehow, that just didn't translate into actual Internet access according to the Airport Extreme and my iMac. Any idea where I've gone wrong and how to fix it? Thanks much.

the example information in this tutorial is only valid for the authors unique setup, yours will be different, for example:

if your raspberry pi has an IP address of 192.168.0.12 and your routers IP address is 192.168.0.1 then the code would be as follows;

interface eth0
static ip_address=192.168.0.11
# above is the IP address of your Pi
# it is a good idea to set your router to reserve the ip address for your Pi.

static routers=192.168.0.1
static domain_name_servers=192.168.0.1
# above is the IP address of your router.

if you follow the authors example exactly you will not be able to surf the internet once you configure your router or device (phone/laptop/tablet/etc...)

then change your router to use the ip address of the raspberry pi for the DNS, leave the 2nd DNS server address blank.

Hope this helps.

"If you have pipeviewer installed, you can use pv yyyy-mm-dd-raspbian-jessie.img | sudo dd of=/dev/rdisk2 bs=1m instead to show copy progress."

Or just type Ctrl- T
This will show the status of your process so that you know what is going on.

As soon as I read this post I ordered all of the components you mentioned and am now a happy user. The only comment I would make is to swap steps 5 and 6 as if you don't enable the SSH server before you reboot it won't come back on again.

The SSH server should be enabled by default, though—at least if you run the touch /Volumes/boot/ssh when you're setting up the OS on the freshly-built microSD card on your Mac/PC...

Raspbian sees the ssh file, then from that boot on, it toggles the ssh server on (even though the boot process cleans up that boot file). At least that's how it's worked on my various Pis since the Pixel update—note that I've only used the lightweight image, not the full Raspbian install. Maybe that's different, but on the small image (no UI), you'd have to manually go into raspi-config and turn off SSH to have it not available.

When trying to run touch/volumes/boot/ssh I'm getting the message "No such file or directory". I've confirmed that that is the location of everything, but no luck. Any ideas? Thanks

Don't forget to put a space after "touch". Else it believes you're looking in a dir starting with touch. Type "touch /volumes/boot/ssh".

Hi, would you mind to compare Pi hole with NextDNS and AdGuardHome? Thanks for that!