Update, added ODOH and DNSCrypt: Removed cloudblock, and added dnscrypt-proxy to enable Oblivious-DNS-Over-HTTPS (ODoH) via DNSCrypt. In brief, DNS requests are now sent encrypted to an 'oblivious' relay, which then sends anonymized DNS requests to the resolver.
These are my install notes for setting up Pi-Hole, PiVPN, and Homebridge on my new Raspberry Pi Zero 2w. Please feel free to contribute notes, suggestions, clarifications, etc.
Pi-Hole provides DNS-based adblocking. This setup will block ads and telemetry on all devices in the home, and specific devices on-the-go using Wireguard.
Homebridge allows my home to recognize my assorted smart devices as HomeKit compatible. With this setup I can access both PiHole and Homebridge on my local network or out-of-home.
- Equipment
- Build Pi Zero 2
- Setup the Pi - add ZRAM and over/unclocking
- Install Pi-Hole
- Install PiVPN
- Install DNSCrypt - customize the config for ODOH
- Router setup
- Useful Pihole addons - add lists, sync multiple pi-holes, check which lists are being used
- Install HomeBridge
- Support this project
I purchased a Raspberry Pi Zero 2 Starter kit, which included:
- Raspberry Pi Zero 2 W
- A UniPiCase Zero Standard Case
- Mini HDMI to HDMI Adapter
- USB OTG Cable
- 32GB Class 10 SD Card - blank
- 5.1V 2.5A Power Supply
- 2x20 Male Header Strip
- Set of two heatsinks
For this project, I won't be using the adapters or the header strip.
- Select the largest of the two heatsinks, peel off the sticker backing on the bottom, and attach it to the chip. You don't need the smaller heatsink.
- Open the UniPiCase by pinching the tabs on the bottom and lightly pulling up on the top of the case
- Put the front plate from the UniPiCase onto the Pi Zero 2, then gently push the front plate and Pi Zero 2 down into the bottom of the case. There's a little tab on the left that will hold it in place.
- Leave the top off for now, but you can stick the little rubber feet onto the bottom of the case at this point
- Go to raspberrypi.com and download and install the Raspberry Pi Imager. I'm using a Mac for this install
- I selected Raspberry Pi OS Lite 32-bit (legacy) by going to "other" section.
- Lite: we don't need a desktop environment
- Legacy: Bullseye (legacy) is presently required for cloudblock, and it looks like gravity-sync as well.
- 32 vs 64: There's an exceptionally detailed techincal writeup on the Pi Zero 2 here that suggests 32-bit systems are more memory efficient on a memory-limited system such as this. However, some things like cloudflare are dropping 32-bit support. Hence, I switched to a 64-bit build for longer-term stability.
- Before continuing, select advanced options:
- Enable SSH: I selected allow public-key authenitcation only
- You can leave the default/prefilled option for set authorized_keys for 'pi'. This automatically creates the required authorization keys. That means I don't have to use a password when connecting to my Pi from this computer
- I entered a key generated by Termius, my new SSH program.
- Set username and password
- Set-up wifi: Set wifi SSID and password
- Write the SD card
- Insert the SD card into the Pi, snap on the lid, and plug your Pi in to the A/C adapter using the right-most slot
- Your Pi will automatically connect to your wifi. For me, the easiest way to find the Raspberry Pi's IP address was to look for it on my network using my router's app
- (Recommended) Set a static IP for the Pi I used my wireless router settings to reserve its IP address (i.e., so the Pi doesn't change its IP on me)
- Open Terminal and connect to it remotely by using SSH. To do so type or copy/paste
ssh pi@rasberrypi.local
. If you changed your Pi username, replacepi
withusername
. If you selected allow public-key authentication only, you shouldn't have to use a password to connect. - Additional troubleshooting step if you've re-flashed the SD card (e.g., setting it up again from scratch):
- Use
ssh-keygen -R raspberrypi.local
If you are re-creating your SD card using your previous/existing keys you may get a scary-looking error when you try and connect via SSH. This command will delete your previous, unique fingerprint and generate a new one to fix this error. If you do so, run this on your home machine prior to ssh.
Prior to running ansible as part of installing Cloudblock, we need to increase the available memory or we run into errors during the install process due to limited free memory on the Pi Zero 2. There are two ways to do this, I've tested both and I'm using ZRam currently:
-
Zram creates compressed RAM based block storage. This compression allows additional memory inside RAM in exchange for the processing power used for compression. This has the benefit of being faster than using the SD card for swap memory.
-
To enable, use
sudo apt install zram-tools
-
(optional) increase Pi's tendency to use swap now that we are using Zram (for more information, see source for more details).
-
Use
sudo nano /etc/sysctl.conf
to add the following to the end of your /etc/sysctl.conf file:vm.vfs_cache_pressure=500 vm.swappiness=100 vm.dirty_background_ratio=1 vm.dirty_ratio=50
Then enable with:
sudo sysctl --system
-
This carries risk. Please read and review your options first. In particular, you'll need some way to deal with heat. See discussion here for tested values, I went with relatively safe numbers: https://forums.raspberrypi.com/viewtopic.php?t=322734
sudo nano /boot/config.txt
Then paste the following to the end of the file:
# Overclock
arm_freq=1200
over_voltage=2
core_freq=500
Reboot
Rather than overclocking the Pi, you may wish to underclock it for additional power savings and/or thermal management. Follow the same steps above and use
# Underclock
arm_freq=600
gpu_freq=300
sdram_freq=400
- On your other computer that you want to also be able to log into the Pi from, open terminal and use
ssh-keygen -t rsa
to create a new SSH key pair. Alternatively, use one you already have. - Copy the contents of the public key using
cat ~/.ssh/id_rsa.pub
- Login to the Pi using your working device, then use
echo [paste public key content here] >> ~/.ssh/authorized_keys
. - Alternatively, use a text-editor like
nano ~/.ssh/authorized_keys
and paste your public key content to a new line in that file. If you're working with nano, pressesc
then$
to wrap long strings of text (like these keys) to make it easy to read. Then hitcontrol + x
theny
thenenter
to save your changes. - Log out using your old device
- Log in using your new device, assuming you're using the defaults, you should be able to log-in using
ssh pi@raspberrypi.local
orssh -i ~/.ssh/[key name] [username]@[raspberry pi ip]
if you're not using defaults keys and/or user names - Repeat steps 1-6 on any other devices you want to add
-
If you're not using the default key name of
id_rsa
(e.g., you created your own name), make a file calledconfig
in your home computer's ~/.ssh/ directory and include the following -
Host [Raspberry Pi IP] IndentityFile ~/.ssh/[key name]
-
This will allow you to connect to your Pi in Terminal by just using
ssh [username]@[raspberry pi ip]
. If you skip this step, you'll need to specify the name of your key file every time you connect, as in:ssh -i ~/.ssh/[key name] [username]@raspberry pi ip]
- The most up-to-date Pi-Hole installation instructions can be found here: https://docs.pi-hole.net/main/basic-install
- Otherwise, go ahead and use the official install script:
curl -sSL https://install.pi-hole.net | bash
- The most up-to-date PiPVN instructions can be found here: https://www.pivpn.io
- Otherwise, go ahead and use the official install script:
curl -L https://install.pivpn.io | bash
Note: if you have a dynamic dns (DDNS) address, when PiVPN asks you if you want to use an IP or a DNS address, select DNS and enter the domain here.
- First, we want to change the default settings for Wireguard that are used to create the device configs.
- I set this up as 'split-tunnel' meaning that I only send DNS and not all my data through my Pi. I also add my home network so when I'm on the VPN, I can access the services in my home server.
- edit the PiVPN configuration with:
sudo nano /etc/pivpn/wireguard/setupVars.conf
. Change theAllowedIPs
line to = the IP/32 above under DNS (which is your Pi-Hole DNS address), and optionally, add your home gateway (e.g., 192.168.68.0/24) - Then use
pivpn add
to create a new device config (e.g.,iphone
) andpivpn qr
to display the qr cod
- Use the Wireguard QR codes that were generated to setup your mobile devices. I set the profiles to on-demand except when connected to my home wifi SSID. That means that as soon as I leave home, Wireguard will connect remotely to continue ad-blocking.
- To download the Wireguard config files to your computer, use the following secure-copy commands. Make sure you are not connected by SSH when running this on your home computer:
scp -r pi@raspberrypi.local:/opt/wireguard/peer*/ [destination on home computer]
- For example, I saved them to a folder called pihole_configs in My Documents using:
scp -r 'pi@raspberrypi.local:/opt/wireguard/peer*' ~/Documents/pihole_configs
- Refer to this guide, or proceed making sure to update the links to the most recent release from the main repo here.
- Install DNSCrypt-proxy, and add the configuration file:
cd /opt
sudo wget https://github.com/DNSCrypt/dnscrypt-proxy/releases/download/2.1.5/dnscrypt-proxy-linux_arm-2.1.5.tar.gz
sudo tar -xf dnscrypt-proxy-linux_arm-2.1.5.tar.gz
sudo mv linux-arm dnscrypt-proxy && cd dnscrypt-proxy
sudo cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml
sudo nano dnscrypt-proxy.toml
- This will open a text-editor with the example configuration file, which you can customize for your setup
- Here is mine already set to use ODOH: dnscrypt-proxy.toml
- Save any changes to the file:
CTRL + X then Y and Enter
- Then start the service:
sudo ./dnscrypt-proxy -service install
sudo ./dnscrypt-proxy -service start
sudo systemctl status dnscrypt-proxy
- Test the service with
./dnscrypt-proxy -resolve www.google.com
, you should get something like:
Resolving [www.google.com] using 127.0.0.1 port 5350
Resolver : 172.69.207.24
Canonical name: www.google.com.
IPv4 addresses: 142.251.32.68
IPv6 addresses: 2607:f8b0:400b:807::2004
Name servers : no name servers found
DNSSEC signed : no
Mail servers : no mail servers found
HTTPS alias : -
HTTPS info : [alpn]=[h2,h3]
Host info : -
- Login to Pi-hole web interface, Goto settings / DNS / Select Custom 1 (IPv4) and enter:
127.0.0.1#5350
. Select Custom 3 (IPv6) and enter::1#5350
. - Uncheck everything else in Upstream DNS Servers section.
- Reboot the Pi via
sudo reboot
- Go to your router settings, note these steps depend entirely on your own router model
- Forward port 51820 to your Pi's local IP address to enable Wireguard to work properly
- Set your primary DNS in your DHCP server settings to your Pi's local IP. Leave the secondary DNS blank.
I like the pihole list tool for adding adlists and whitelists, you can install it by SSH back to your Pi, then running sudo pip3 install pihole5-list-tool --upgrade
. Select the Docker version once it launches, then choose the blocklists and whitelists options from the list that appeal to you.
You can use PiHole apps (e.g., Pi-Hole remote) by selecting https://, using your [Raspbery Pi IP] and port: 443 along with your PiHole's API token. I set up two PiHoles in the app PiHole - local and PiHole - remote. To set up remote, I used https://, 172.18.0.5, and port:443
The Pihole Adlist Tool is a script that will analyze 30 days worth of adblocking to see which lists you're actually using. After running the script, it can automatically disable any lists that aren't being used. To run it, ssh into your PiHole then run:
wget https://github.com/yubiuser/pihole_adlist_tool/archive/refs/tags/2.6.3.zip
unzip 2.6.3.zip
rm -r 2.6.3.zip
cd pihole_adlist_tool-2.6.3
sudo ./pihole_adlist_tool
Then follow the prompts, noting that it may take some time to run. Note that you might want to check for the latest release of the tool, as v2.6.3 might be out of date when you read this.
If PiHole is all you wanted, then you can stop here. If you're interested in also adding HomeBridge read on!
Use Gravity Sync to sync lists with a secondary Pi-Hole
First, you'll need to set a password for user Pi if you don't already have one using:
sudo passwd pi
Then run the installation script, you'll be prompted for your secondary Pi's IP address, and the username (e.g., root) and password of the system on which it is installed.
curl -sSL https://raw.githubusercontent.com/vmstan/gs-install/main/gs-install.sh | bash
I use gravity-sync push
to push my lists from Cloudblock over to the new, secondary Pi.
If you found this guide helpful, please consider buying me a coffee by clicking the link below. I'll do my best to keep this guide up to date and as user-friendly as possible. Thank you and take good care!