Note: Updated 6/28/2020 to include Gravity-sync and MacOS/iOS Pi-hole control apps. Note: Updated 11/15/2019 to optionally use the NextDNS.io DNS filtering and analytics service. Note: Updated 11/1/2019 for Anonymized DNS configuration, added Raspberry Pi 4 firmware update procedure, and apt package removal to free up more space. Recently I've become more and more aware of the lack of privacy on the internet, not to mention sites brimming with ads or malware. Or your ISP spying on all the sites you visit via plaintext DNS queries. I wanted a home network wide ad and malware blocker and fully encrypted DNS. After doing some research, I quickly found that Pi-hole was a very common, robust, and free (software wise) solution for DNS filtering, and that DNSCrypt is great for keeping your DNS queries private. Both can run on a variety of platforms, but I wanted something pretty cheap, small, and easy. So after much research, I decided to use a Raspberry Pi 4 B. It could possibly run on a Synology NAS, but the directions I found were quite complex and error prone. Now there are a bunch of configuration guides for Raspberry Pi, Pi-Hole and DNSCrypt on the internet. However, many of them were outdated, left out steps, or weren't as complete as I would like. So I'm doing my own version that I used to configure on my network. Plus, I have the Eero wi-fi mesh routers, so I have some tips on those configuration settings as well. I didn't have a RPi laying around the house (I know, I'm a bad geek). So I found this complete package on Amazon for $99. This package contains the Raspberry Pi 4 B, 4GB RAM, case, power supply, memory card, HDMI cable, and heat sinks. You don't have to buy this exact package, nor does it need to be a RPi 4 B. Pi-Hole and DNSCrypt hardware requirements are very minimal, so virtually any Raspberry Pi will suffice. I wanted the higher end model so I could repurpose it down the road if I needed or install more services like a VPN server.

1. What is Pi-Hole?

For those of you unfamiliar with Pi-Hole, it's basically an open source DNS server but is not a DNS resolver. What's the difference? Pi-Hole will service DNS requests for your local network, but it needs to contact an upstream DNS server for resolution. It will not connect to the root DNS servers on its own. Pi-Hole has a pre-defined list of upstream DNS servers it can use, or you can also add your own. In my case I point Pi-Hole to my Eero secure WiFi gateway, as it will encrypt and forward DNS queries to an upstream resolver while layering on more ad and malware filtering. If you don't have the Eero Wifi mesh, you can use DNScrypt to encrypt and forward the requests to a resolver. More on this later. Pi-Hole works via blacklists and whitelists. There a number of sources for these lists, and it's up to you (for the most part) to find the lists and import them. Pi-Hole does have a few built-in lists you can choose from, that block upwards of 100,000 domains. Blocking more domains is not always better, as it can break legitimate sites. In my case I'm blocking about 2.4M domains, but had a decent learning curve to whitelist some domains that I needed access to. You can customize the block lists to suit your needs (e.g. block porn, facebook, malware, gambling, etc.). Pi-Hole can block any DNS query that it receives, but you can't always point every device on your network to the Pi-Hole DNS server. For example, some devices like Chromcast and IoT have hard coded DNS servers that, without additional configuration, will totally bypass Pi-Hole blocks. Eero secure can intercept these requests and filter them via it's blacklilst, but it won't forward the requests to your Pi-Hole instance. For that, you'd need something like a Ubiquiti Edge Router X with a specific configuration to capture these 'rogue' DNS requests and forward them to Pi-Hole.

2. Raspberry Pi Storage

The Raspberry Pi uses an SD card for local storage, and as such, it's important to be smart about the SD card you use. I suggest at least a 32GB card, and for a few more dollars, you can get a high endurance card. I like the Samsung Pro Endurance 32GB micro SDHC card for $12. You won't need the full 32GB of storage, but this allows for extra write locations that can further extend the life of the card. The RPi kit that I linked to above has a run of the mill 32GB microSD card, so I'd spring for the extra $12 and get the Samsung Pro endurance card. You could then use the kit microSD card as a backup target.



3. Writing The Raspbian Lite to your MicroSD card

1. Download the latest version of Raspberry Pi OS.I got the 'desktop and recommended software' package. Do NOT unzip it. 2. Download and install Etcher.io, which we will use to write the Raspbian lite image to the SD card. There are both PC and Mac versions. 3. Connect your card reader and insert the microSD card. Warning: contents will be over-written! 4. Start Etcher, click "Select Image" and find the Raspbian Lite zip file you downloaded. 5. Click "Flash!" and wait for the zip to be written to the memory card and the validation to complete. If an error occurs, make sure the card reader/card is not locked. If it's not locked, possibly the download is corrupted or not complete. Try and re-download the Raspbian Lite zip.

6. If you are doing this on a Windows computer, you may get a pop-up about needing to format a drive. This is erroneous, and just click Cancel. 7. There is a small Fat32 partition in which we need to create a zero byte file called ssh. On Windows, open a command prompt, CD to the Fat32 partition and enter the following command (ignore the output error..that is expected). If you don't see a drive letter associated with the Fat32 partition, open Disk Manager and assign it a letter. Enter: .>ssh

8. If you are on a Mac computer CD to the Fat32 partition (e.g. cd /Volumes/boot) and type: touch ssh

If the boot partition is not mounted, pop the microSD card out of your reader and push it back in. 9. Cleanly unmount the microSD card. Yes, just don't pull it out! Insert the microSD card into the Raspberry Pi. 4. Powering Up and Configuring your Raspberry Pi



1. Connect your Raspberry Pi to a good power source. Since there's no power switch, it will start to immediately boot (unless you bought the kit I linked to from Amazon, where the power supply has an on/off switch). If you have a monitor and keyboard attached when booting the first time, a nice GUI wizard will appear to walk you through configuration of items such as locale, keyboard, timezone, new password, software updates, etc. I prefer this method over raspi-config (next step). Also take note of the IP assigned, which the wizard will show as well.



2. If you are doing the setup 'headless', wait a couple of minutes for the system to boot. If you are using the Eero wifi mesh system like I am, you should get a notification that a new device joined the network. Open the Eero app and take note of the IP address the Raspberry Pi was assigned. If you are not using Eero, you can find the IP via other means. That includes connecting a monitor/keyboard to the Raspberry Pi, looking at your router for a new device, or using a network scanning app like "InetTools" for iOS using the LAN scan feature to look at before/after maps to determine what's new. Or if you get lucky, you can open a terminal and type ping raspberry.pi and see if it responds.



3. SSH into the Raspberry Pi as user 'pi' and open the configuration tool (default password is raspberry):



ssh pi@RaspberryIP

sudo raspi-config



4. At a minimum consider configuring the following items with the tool. If you ran through the configuration with the desktop GUI using the keyboard and monitor, most of this will have already been done.



Change password (menu 1): very important

Network options (menu 2): Change hostname (optional)

Boot options (menu 3): console autologin (optional, bad for security, good for ease of use)

Localisation options (menu 4): keyboard layout, timezone (important)

Interface options (menu 5): Enable ssh



5. Next we should configure the Raspberry Pi for a static IP address. You can do this two ways. One, create a reservation in your router (which I did), or we can configure a static IP directly in the RPi. If you don't want to go the router route, enter the following command:



sudo nano /etc/dhcpcd.conf



Uncomment the line under # Example static IP configuration and fill in the proper IPs. You don't need an IPv6 address, so that line can be left commented. Save the configuration file and exit nano.

6. Now we need to update all of the packages, if you haven't done so during the desktop GUI configuration process. Let's also install DNS utils, so nslookup and other commands work. Type:



sudo apt-get update

sudo apt-get dist-upgrade

sudo apt-get install dnsutils



Wait for the updates to complete. I like to reboot after the updates, so type sudo reboot. 7. To be more secure and get automated updates, we will install unattended-upgrades. sudo apt-get install unattended-upgrades sudo nano /etc/apt/apt.conf.d/50unattended-upgrades Add the following two lines just after the origin-Debian section, and comment out the debian lines. "origin=Raspbian,codename=${distro_codename},label=Raspbian";

"origin=Raspberry Pi Foundation,codename=${distro_codename},label=Raspberry Pi Foundation";

Now we need to edit another file: sudo nano /etc/apt/apt.conf.d/20auto-upgrades Delete the existing lines and paste this in: APT::Periodic::Update-Package-Lists "1";

APT::Periodic::Download-Upgradeable-Packages "1";

APT::Periodic::Unattended-Upgrade "1";

APT::Periodic::Verbose "1";

APT::Periodic::AutocleanInterval "7"; To enable unattended updates type: sudo dpkg-reconfigure --priority=low unattended-upgrades

5. Update Raspberry Pi 4 EEPROM (Firmware)

From time to time new Raspberry pi 4 EEPROM (firmware) may be available. This procedure will install an auto-updater and keep you on the latest firmware version. Run these commands below. If it says update required, then merely reboot your RPI with sudo reboot and the update will be installed. sudo apt update

sudo apt full-upgrade

sudo apt install rpi-eeprom

sudo rpi-eeprom-update



6. Package Removal

Wolfram and Libreoffice are both space hogs on the Raspberry Pi 4, and likely you won't need them. Plus this makes your backups larger, so let's get rid of them. This will save over 1GB of space. If you want them, please skip this section.

sudo apt-get remove --purge wolfram-engine

sudo apt-get remove --purge libreoffice*

sudo apt-get clean

sudo apt-get autoremove

7. Installing and Configuring Pi-Hole

1. SSH into your RPi and type: curl -sSL https://install.pi-hole.net | bash Walk through the text based wizard and accept all of the default values. When it asks you for which DNS server to use, select one that you feel most comfortable with. Later in this blog post we will install and configure DNSCrypt, so doesn't really matter what you select now. Make sure at the end you write down the admin console password at the very end of the installer wizard. 2. There are a lot of block lists out there, but here are a few that should get you around 1.7M blocked domains. Login to Pi-Hole (http://YourIP/admin), click on Settings, then blocklists. Paste all at once the list below and click on 'Save and Update'. For a good discussion on more block lists you can check out the PI-Hole forum here. https://blocklist.site/app/dl/malware

https://blocklist.site/app/dl/ransomware

https://blocklist.site/app/dl/tracking

https://blocklist.site/app/dl/fraud

https://blocklist.site/app/dl/phishing

https://v.firebog.net/hosts/AdguardDNS.txt

https://1hos.cf

https://zeustracker.abuse.ch/blocklist.php?download=domainblocklist

https://hosts-file.net/grm.txt

https://reddestdream.github.io/Projects/MinimalHosts/etc/MinimalHostsBlocker/minimalhosts

https://raw.githubusercontent.com/StevenBlack/hosts/master/data/KADhosts/hosts

https://raw.githubusercontent.com/StevenBlack/hosts/master/data/add.Spam/hosts

https://v.firebog.net/hosts/static/w3kbl.txt

https://v.firebog.net/hosts/BillStearns.txt

https://adaway.org/hosts.txt

https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt

https://v.firebog.net/hosts/Easyprivacy.txt

https://raw.githubusercontent.com/quidsup/notrack/master/trackers.txt

https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt

https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/SmartTV.txt

https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt

https://www.malwaredomainlist.com/hostslist/hosts.txt

https://dbl.oisd.nl/ 3. After some web surfing, I found that Facebook comments were somewhat broken with all the blocks. So I had to add the following two whitelist entries for comments to fully work: b-graph.facebook.com

graph.facebook.com 4. If you used all of the block lists above, be prepared to troubleshoot apps or websites that don't work because of blocked domains. If you run across a non-functional site or app, review the Pi-Hole logs for blocked domains and try whitelisting one at a time and re-testing your site/app to see what fixes the problem.

8. Installing and Configuring DNSCrypt



Note: If you are using the Eero Wi-Fi mesh system, see the bottom of this blog post about DNSCrypt and Eero secure. If you are using Eero secure you won't need DNSCrypt. If you aren't using Eero secure, go ahead and install DNSCrypt. Also, if you want to use NextDNS.io for an additonal layer of DNS security and filtering (highly recommended), go through this section, then follow the instructions later in this section.

1. Enter the following commands to do a base DNSCrypt installation. As this blog post ages, the exact download path WILL change. Check out the latest version listing here and modify the wget and tar commands as needed to use the latest binary. cd /opt sudo wget https://github.com/jedisct1/dnscrypt-proxy/releases/download/2.0.31/dnscrypt-proxy-linux_arm-2.0.31.tar.gz



sudo tar -xf dnscrypt-proxy-linux_arm-2.0.31.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 Under Global settings add one or more servers. I like the iOS app DNSCloak to sift through the plethora of servers you can use. For example, you can search for DNS servers that block ads, support doh (DNS over HTTPS), view locations, etc. I like AdGuard DOH. You can also check out the public DNSCrypt server list here and pick one or more that fits your requirements. Note: If you want to use DNSNext.io service, just leave the default servers here and we will configure this later in this section.



server_names = ['adguard-dns'] Under List of Local addresses change the port number to something you like, above 1024. I'm using 5350 in this example. Pi-Hole will be using port 53 (standard for DNS), so that's why we must use a custom port number for DNSCrypt. listen_addresses = ['127.0.0.1:5350', '[::1]:5350']



Change the following: require_dnssec = true

require_nofilter = false

cache = false (we will use the Pi-Hole cache)

Anyonmized DNS is a new feature in the most recent versions of DNSCrypt. If you want to use this feature, scroll all the way down to the bottom of the TOML file. For server_name add the same server name you used above. For the 'via' servers, review the relay list here, and pick a couple that suite your needs. I used servers in close proximity to my house. You may want to use servers in a different country, or have other unique requirements. Note: If you want to use NextDNS.io service, you don't want to anonymize your queries, so don't configure this section.

routes = [

{ server_name='adguard-dns', via=['anon-cs-usca', 'anon-cs-ca2'] },

]



Save and exit the nano editor.

8A. Configuring DNScrypt for the NextDNS.io service

If you want to use the NextDNS.IO service with DNS crypt, it's pretty straight forward. This gives you a second layer of DNS filtering and protection. They also give you some great analytics and stats for your network. If you don't want to use NextDNS.io, skip this section. 1. Login to your NextDNS account and click on the Setup tab. Look for the sdns 'dns stamp' section under EndPoints and copy the sdns string to the clipboard.

2. In the DNSCrypt dnscrypt-proxy.toml file look for the [static] section towards the very bottom. Add the following lines, using your custom sdns stamp string that's on the clipboard. [static.'NextDNS-Custom']

stamp = 'sdns://xxxxxxxxxxxxx' 3. At the top of the DNSCrypt configuration file change the server_names line to exactly match the static name you used above. server_names = ['NextDNS-Custom'] 4. Save the configuration file and exit the editor.



8B. Testing DNSCrypt

1. Now we need to start the service and test it to make sure it's working before we configure Pi-Hole to use it. sudo ./dnscrypt-proxy -service install

sudo ./dnscrypt-proxy (validate the server runs without errors, then control-C to stop)

sudo ./dnscrypt-proxy -service start

sudo systemctl status dnscrypt-proxy The sudo ./dnscrypt-proxy command will provide detailed startup information and return any errors it encounters. sudo systemctl status dnscrypt-proxy does the same for DNScrypt when it's started as a service. Both should have the same output, as shown below. If the Anonymized setting is properly configured those relay servers will be shown in the DNSCrypt output.

To run a quick test that DNSCrypt can perform name resolution type: ./dnscrypt-proxy -resolve www.aol.com



8C. Configuring Pi-Hole for DNSCrypt

1. Login to the Pi-Hole console (http://RPIAddress/admin). Go to Settings, DNS. Uncheck all upstream DNS servers and enter 127.0.0.1#5350 in Custom 1 (IPv4) and tick the box. For IPv6, enter ::1#5350 If you are running a VPN server on your Raspberry Pi, you will likely need to change the listening behavior to listen on all interfaces. Save the change.

2. If you configured the Raspberry Pi for a static IP address, you can change the DNS server to point to localhost so that all Raspberry Pi DNS requests get filtered and encrypted. Find the eth0 section and change the DNS server to 127.0.0.1. sudo nano /etc/dhcpcd.conf 3. Reboot your Raspberry Pi and verify all DNS queries are working properly and that Pi-Hole is blocking some requests.



sudo reboot

ssh pi@RPiAddress

nslookup www.aol.com (should return real addresses)

nslookup www.aol.com RPiAddress (e.g. nslookup www.aol.com 10.13.2.200)

nslookup xp.apple.com (should return 0.0.0.0 as it's blocked) Both AOL results should return valid public IP addresses. The XP.apple.com address should NOT work and just give you 0.0.0.0 since it is on the block list. If the apple address returns a valid public IP, something is misconfigured.

9. Reconfiguring your Router for Pi-Hole

The final step is to reconfigure your network to use the new Pi-Hole DNS server. First, any devices with a static IP address need to have their DNS changed to only use the RPi address. Second, if your network uses DHCP (most home networks do), the DHCP/router will need to be reconfigured to use the new Pi-Hole DNS server. The exact steps vary widely, so I can't cover all options here. I use the Eero mesh Wi-Fi system, so it's a simple matter of opening the Eero app then going to Network Settings, Advanced settings, DNS, Custom DNS, and enter the Pi-Hole IP address. The mesh will then reboot. After your router reboots, open a command prompt or shell on your computers and do various lookups: nslookup www.aol.com (should return real addresses)

nslookup xp.apple.com (should return 0.0.0.0 as it's blocked) If permitted lookups work and the blocks work as well, then your device is fully utilizing Pi-Hole and DNSCrypt! Congratulations.

10. Eero Wi-Fi Mesh Configuration Tips

If you are using the Eero wi-fi mesh system (which I absolutely love), there's a few tips you need to be aware of: 1. You don't want to use Pi-Hole WITH CryptDNS along WITH Eero Secure. Although you could technically configure this, 99% of the DNS requests would go through CryptDNS and Eero Secure would only catch the 'rogue' requests going out. Regular DNS queries would not be routed through Eero secure...so you'd be mostly wasting your money.

2. You can use Pi-Hole (alone) with Eero Secure. Eero Secure will encrypt your DNS requests instead of CryptDNS, AND intercept rogue DNS requests from the network. This allows defense in depth by using Pi-Hole and Eero secure to filter DNS requests.

3. You can use Pi-Hole with CryptDNS and not pay for Eero secure, and enjoy the benefits of secure DNS but won't get the defense in depth with using Eero secure and Pi-Hole together. To use Pi-Hole with Eero secure (and not use CryptDNS), follow these general steps: 1. Configure Pi-Hole to point to the Eero gateway IP address for upstream DNS resolution

2. If Eero secure is enabled, disable it. (just temporary)

3. In the Eero app configure a Custom DNS IP, and point it to the Pi-Hole IP

4. Re-enable Eero secure

5. Review Pi-Hole logs to ensure queries are being redirected to Pi-Hole In this configuration Eero secure will then take care of encrypting and forwarding the DNS requests to their curated servers for more defense-in-depth. In this configuration you would NOT be using CryptDNS. If you aren't using Eero secure, then you would want to use CryptDNS to ensure the security of your DNS requests.

One big plus about Eero secure is that it will filter ALL DNS outbound requests, even those not pointed to the Eero as the DNS server. This is great for devices that have hard coded DNS servers, and prevents DNS leaks. With the Pi-Hole configuration devices that use hard coded DNS servers can bypass Pi-Hole/CryptDNS. I'd love to see Eero add an advanced "DNS Redirection" option that would point these 'rogue' requests to an IP of your choice (like Pi-Hole) for full DNS protection just like they do with Eero secure. Please "up" vote for that feature here. We don't want Eero to cache DNS lookups, as this will add the Eero gateway to the DHCP DNS scope options and potentially clients can bypass Pi-Hole/DNSCrypt. We don't want that! So go into the Eero network settings, Eero labs, and make sure Local DNS Caching is NOT enabled. And that's it. If you want to verify that the Eero's are only setting Pi-Hole as your DNS server, on Windows type ipconfig /all and look for the ethernet interface. It should only list your Pi-Hole IP address. If you are on a Mac, type the following command: scutil --dns | grep 'nameserver\[[0-9]*\]'

11. Raspberry Pi Backup

Now that you have spent a few hours configuring your Raspberry Pi 4, you might want to back up your work. For Mac and Windows users, I really like Apple Pi Baker. Simply launch Apple Pi Baker, cleanly shutdown down your RPi (sudo shutdown -h now), pull out the microSD card and insert it in your computer's reader. Then launch Apple Pi Baker and dump the contents to a zip file. Viola....now you have a full Raspberry Pi backup file that you can restore from at any time in the future. 12. Gravity-Sync is a free project on Github that will allow you to sync some of the configuration settings (e.g. blocklist) between two Pihole 5.0 instances. It's very simple to configure and can be done in just minutes. Highly recommended for redundant Pihole 5.0 situations. 13. Pi-Hole apps. If you are in the Apple ecosystem and want to easily control your Pi-hole instances (e.g. temporarily disable, monitor stats, etc.), there are a few MacOS and iOS apps to choose from. For MacOS, I suggest PiBar or PiStats. For iOS and Apple Watch I recommend Pi-hole Remote.

13. Final Thoughts

As you can see from this post, there's quite a bit of manual configuration to setup a Raspberry Pi, Pi-Hole, and DNSCrypt. However, you should be able to do it in an afternoon if you don't run into any major issues. If you think this is all way too much work and want something easier, then look at the Eero mesh Wi-Fi system. It has a feature called Eero Secure which intercepts and encrypts all DNS requests and forwards them to a curated DNS server that blocks a lot of ads, malware, and tracking sites. Using Eero Secure is way easier then doing a Pi-Hole and DNSCrypt setup, but doesn't offer the ability to do custom blacklists, white lists, or anonymized DNS. For the average consumer Eero Secure is the better choice, but for super nerdy people Pi-Hole and DNSCrypt works very well. Note: You may have devices on your network that have hard coded DNS servers, such as Chromecast. These will bypass your Pi-Hole without more work. You can capture these DNS queries and forward them to Pi-Hole/DNSCrypt by following my blog post:

Redirect Hard-coded DNS To Pi-hole Using Ubiquiti EdgeRouter











Insert Image