João Victor Risso

Writes About Stuff

Pi-Hole Setup on Raspberry Pi 3

In this post, I will cover how to install a Raspbian system from scratch, along with the setup of pi-hole, to block internet trackers on the network level.

Pi-Hole serves both as a DNS forwarder and cache, and should be configured as the DNS server for your network. This guarantees that all users of your network will be automatically shielded from internet tracking. You also might notice a reduction in bandwidth usage, since assets from ad networks and trackers are not loaded because of the ‘blackholing’. This process is explained further down in this post.

In order to follow this tutorial, there are a few hardware requirements:

  • Raspberri Pi, either version 2 or 3 should work.
  • HDMI cable
  • Monitor with a HDMI port
  • USB keyboard
  • SD Card
  • Ethernet cable, to connect the Pi to the router

If you have Raspbian already setup, you can skip to the section ‘Pi-hole and DNS Forwarding’. Make sure, however, that your Raspbian has a static IP address setup for it.

Raspbian Setup

Insert the SD card in the computer, and check for its name using the following command:


Which shows an output like the following:

sda               8:0    0 931,5G  0 disk 
├─sda1            8:1    0   512M  0 part /boot/efi
├─sda2            8:2    0     1G  0 part /boot
└─sda3            8:3    0   930G  0 part 
  ├─fedora-root 253:0    0    50G  0 lvm  /
  └─fedora-home 253:1    0   880G  0 lvm  /home
mmcblk0         179:0    0  14,9G  0 disk 
├─mmcblk0p1     179:1    0   1,6G  0 part 
├─mmcblk0p2     179:2    0     1K  0 part 
├─mmcblk0p5     179:5    0    32M  0 part 
├─mmcblk0p6     179:6    0    69M  0 part 
└─mmcblk0p7     179:7    0  13,2G  0 part 

In this case, sda is the hard drive from the computer, and mmcblk0 is the SD card. Therefore, mmcblk0 is the device we must use to flash the SD card. Beware, that (wrongly) writing to the hard drive would corrupt your filesystem!

Download the Raspbian Lite image from the Raspbian website. Then, we extract the image and write its contents to the SD card using the dd Linux utility, as follows:

unzip && \
sudo dd bs=4M conv=fsync status=progress \
    if=2018-04-18-raspbian-stretch-lite.img \

In Unix and Linux operating systems, everything is represented as a file, including disks and SD cards. dd takes the content of a file specified by if and writes its contents to the file of. In our case, we are taking an input file (2018-04-18-raspbian-stretch-lite.img) and writing it to a special file (/dev/mmcblk0), which represents the SD card.

The parameters passed to dd have the following meaning:

  • if: stands for input file, the file from which the content will be read.
  • of: stands for output file, the file to which the contents of if will be written.
  • bs: stands for block size, how many bytes are read from the input and written to the output file at once.
  • conv: stands for conversion, it applies comma separated operations on top of the input file, before writing it to the output file. fsync ensures that the kernel writes the data to the output file as well as metadata to the physical device before finishing. This is required, because the kernel might not promptly write the data to the SD card, which would leave the SD card corrupt if we took it off the computer before all the data was written to it.
  • status: amount of information printed to stderr. progress shows periodic transfer statistics, which allows one to track the speed and amount of data copied to the SD card.

Depending on your disk and SD card performance, this might take a while as the image is around 1.7 GB large. After the data is written to the SD card, take it off the computer and put it in to the Raspberry Pi.

Connect the Pi to an energy source, the keyboard and the monitor (using the HDMI cable). It should boot to a screen like the following:

Raspbian 9 Login

Log in using pi as the username and raspberry as the password. Change the default password for pi:


You will have to provide the current password (raspberry), and type the new password twice (once more, for verification purposes).

In the next section, a static IP address and SSH are setup, so there will be no more need for the monitor and keyboard.

Static IP Address

nano /etc/dhcpcd.conf

Add the following to the end of the file:

interface eth0
static ip_address=
static routers=
static domain_name_servers=

In your setup, replace the:

  • IP address (ip_address) with the local IP address of the Pi in your network, in this case with a network mask of 24 bits, i.e.
  • routers with the IP address of your router, in this case it is
  • domain_name_servers with the IP address of the DNS resolver for your network. If you don't know what is the IP address of your DNS resolver, you can use either (Google DNS) or (Cloudflare DNS).

SSH Setup

systemctl enable ssh.service
systemctl start ssh.service

After configuring the static IP adress and SSH, reboot the Pi:

sudo reboot

You can now take off the keyboard, and HDMI cable from the Pi. After a couple of seconds, log in to the Pi using the SSH on your machine:

ssh pi@

Note that we are using the user pi with the static IP address configured in a previous step. Replace the IP address with the one you have configured.

Pi-hole and DNS Forwarding

Pi-Hole works both as a cache and DNS forwarder. This means that:

  1. It takes a domain name query such as
  2. If the domain is in one its blocklists, then the IP address returned is, which is not routable, i.e. it cannot be accessed over the internet. Therefore, its renders blocked domains unaccessible. Otherwise, it goes to step 3.
  3. If it doesn't know the IP address of this domain locally (i.e. the address is not in cache), it queries an upstream DNS server (e.g. Google DNS) to obtain the IP address
  4. The IP address is saved locally in the cache, and the address is returned to the user.

Pi-hole Setup

Update the system packages:

apt-get update && apt-get upgrade -y

Install pi-hole using the following command:

curl -sSL | bash

Follow the installation process, selecting your upstream DNS providers (e.g. Google DNS or Cloud9). I would also recommend installing the web interface, this option will be shown in the pi-hole installer. Your output should be something like the this.

Change the administration password of Pi-Hole:

pihole -a -p

Firewall (optional)

In order to secure our Pi, we will install ufw (short for ‘Uncomplicated Firewall’), which is simpler to configure than iptables.

First, install ufw:

sudo apt-get install -y ufw

Allow the ports of the services provided by pi-hole:

sudo ufw allow 22/tcp
sudo ufw allow 53/udp
# DHCP server (optional), only if pi-hole will be your DHCP server
sudo ufw allow 67/udp
sudo ufw allow 68/udp
# pi-hole web interface
sudo ufw allow 80/tcp

and enable the firewall:

sudo ufw enable
sudo ufw status verbose

Web Interface

Access the web interface on, and use the password you have configured earlier on. It should look like the following:

Pi-hole Web Administration Interface

Concluding Remarks

Make sure all the hosts on your network use the IP address of the pi-hole as their only DNS server.

As a bonus, one can also harden the SSH server, if the Pi is accessible to the public internet, and restrict the SSH port only to local addresses is also a good security measure.

If you reached this point, please let me know if you have any thoughts or comments on this post, the details for contact can be found in the About page.