Things I Learned While Quarantined - Part 1: piHole + Docker (macOS) - running a local ad-blocking DNS server in your home
I've heard and read about piHole for a long time - a DNS server you can run in your home that blocks ad traffic at the DNS level; giving all your devices on your WiFi the benefit of some ad-blocking tech without having to configure your devices. I never got around to it because, well, I just didn't have the time. Until now, that is. With so much time at home these days, I finally got around to it.
It's worth nothing there are several approaches to ad blocking:
- Application Level: Like using Ad Block Plus in your browser
- Device Level: Usually done via root or some hack to get DNS on your device to do what I am doing here.
- DNS Level: This is what we are doing here.
That said, DNS Level is just one layer of protection, but I recommend using this AND an ad blocker like Ad Block Plus. piHole + Ad Block Plus = No Ads!
To get started I used an older MacBook Pro that has been being used as a media center for iTunes. As I went through the process, I had to install a "docker container" to run piHole, but the whole thing wasn't very difficult setup. I had DNS filtering going in about an hour.
I mostly followed two articles on how to get this done on my MBP:
- This article: https://www.imore.com/how-run-pi-hole-your-mac
- This post: https://www.reddit.com/r/pihole/comm...e_with_docker/
This is where you get started and follow their directions on downloading and installing Docker and pihole on your MBP, I dont need to repeat those steps here since I followed the first source with no problems.
I've had so much fun with this, though, that I ordered a Pi 4 setup that will arrive tomorrow so I can run it without the container and also do DHCP (havent been able to get it to work in a container and suspect the overhead of the container is better as a backup DNS server since my router requires two IP addresses).
https://www.amazon.com/gp/product/B0..._title_o00_s00
I know you can get the setup cheaper, but the kit just meant no fussing with the extra parts, so a convenience.
I was able to get EasyList from AdBlocker Pro added in and can automate that with a cron. For this I used this reference link on Reddit. You run this inside the Docker container under the /etc/pihole directory (although, its worth noting that there is a directory in your home directory called "~/pihole" which is a mounted file system inside the container, so you can edit file in there as well).
# download adblock lists curl -s -L https://easylist-downloads.adblockplus.org/easylist.txt https://easylist-downloads.adblockplus.org/malwaredomains_full.txt > adblock.unsorted # look for: ||domain.tld^ sort -u adblock.unsorted | grep ^\|\|.*\^$ | grep -v \/ > adblock.sorted # remove extra chars sed 's/[\|^]//g' < adblock.sorted > adblock.hosts # remove files we no longer need rm adblock.unsorted adblock.sorted
After you create this file, you add it inside the interface under the Adlist tab under Group Management:
file:///etc/pihole/adblock.hosts
And then re-start your docker container from your Docker Desktop application.
A couple of things I have learned going through this process:
- This is not an ideal setup, but can work in a pinch with a few tweaks around using Docker and your MBP that is mostly closed and set aside.
- You do have to have some basic understanding of how your router works and DNS because you'll need to reconfigure your router to ignore externals DNS servers and point to your local DNS server. You also have to assign a static IP to your piHole.
- You need to use command line interfaces for some things, although the new Docker Desktop does make some tasks easier, but I still start my server from a CLI.
- On OSX, the container thing does have one annoyance, the container is a virtual network, so while you can access DNS and HTTP from your local ip, thats about it. I tried to do routing for the container, but in the end it wasn't worth the time or frustration because the only benefit of doing so was the potential use of DHCP (see next bullet), which I am saving for the next device. Once I decided to go with a dedicated box, I stopped trying to get this to work.
- piHole does have DHCP functionality and I intend to use it once I get the device that is dedicated to DNS/DHCP, but thats just a nice to have, no real need. The problem is that DHCP wants to return an IP inside its Docker network and you end up having to do a workaround to get everyone running in that network (or configuring Docker as part of your network). Despite the effort to get it to work, I was unable to in a short amount of time.
- And a big one - this doesnt remove the need for AdBlock Plus in your browsers, because piHole doesn't do element blocking. The best setup is a combination of the two. Even on this composing page there are still 26 blocked elements related to ads and tracking that are being blocked by ABP.
- Another "big" thing - with the lid closed, even with the power settings set, Docker goes to sleep. I tried a number of stay awake apps but only one worked - Anti-Sleep in the App Store (PRO version, 30 day trial). Best I could figure, wake on network does not consider DNS/DHCP requests when waking. A continuous PING would keep it alive, but the other anti sleep apps did not successfully prevent the Docker app from going to sleep.
If you are using OSX, I use a script to spin up a new docker container - docker_run.sh:
#!/bin/bash # https://github.com/pi-hole/docker-pi...ster/README.md # docker run -d --name pihole -e ServerIP=192.168.1.5 -e TZ=America/New_York -e WEBPASSWORD=xxxxxxx -e DNS1=1.1.1.1 -e DNS2=1.0.0.1 -p 80:80 -p 53:53/tcp -p 53:53/udp -p 443:443 -v ~/pihole/:/etc/pihole/ --dns=127.0.0.1 --dns=1.1.1.1 --cap-add=NET_ADMIN --restart=unless-stopped pihole/pihole:latest # Note: ServerIP should be replaced with your external ip. docker run -d \ --name pihole \ -p 53:53/tcp -p 53:53/udp \ -p 80:80 \ -p 443:443 \ -e TZ="America/New_York" \ -e WEBPASSWORD=xxxxxxxx \ -v ~/pihole/:/etc/pihole/ \ -v ~/etc-dnsmasq.d/:/etc/dnsmasq.d/ \ --dns=127.0.0.1 --dns=1.1.1.1 \ --restart=unless-stopped \ --hostname pi.hole \ -e VIRTUAL_HOST="pi.hole" \ -e PROXY_LOCATION="pi.hole" \ --cap-add=NET_ADMIN \ -e ServerIP="192.168.1.5" \ pihole/pihole:latest printf 'Starting up pihole container ' for i in $(seq 1 20); do if [ "$(docker inspect -f "{{.State.Health.Status}}" pihole)" == "healthy" ] ; then printf ' OK' echo -e "\n$(docker logs pihole 2> /dev/null | grep 'password:') for your pi-hole: https://${IP}/admin/" exit 0 else sleep 3 printf '.' fi if [ $i -eq 20 ] ; then echo -e "\nTimed out waiting for Pi-hole start, consult check your container logs for more info (\`docker logs pihole\`)" exit 1 fi done;
Reference for above code: https://github.com/pi-hole/docker-pi-hole/blob/master/docker_run.sh
I did have to spin up a half dozen containers to get the right configuration working, so this could save you time if you use a script like this. I did have to add a couple of lines to the configuration to get it working on OSX/Docker.
It went online yesterday afternoon and my stats this morning are: 37,143 queries - 17,773 blocked (47.8%).
Pretty impressive! And everything in the house is running noticeably faster - even my XBOX! And on my SMART TVs it appears the ads have stopped showing, although I need to do some more research on that.
But, more importantly, I'll be curious how that 47% number does in the coming weeks. If 47% of the URLs on my network are blocked as "as networks", that's a pretty staggering number.
I'm looking forward to getting the little box to spin up as my primary DNS/DHCP server this weekend and will post about that experience as well.
Experienced Site Reliability Engineer Knowledgeable in Ansible, Docker, and Python.
4 年I run pihole with unbound DNS using docker compose. You get ad filtering and privacy with those, and I recommend putting them on an always-on system like a local PC or NAS ( Synology, QNAP, UnRaid ) that supports docker containers.
Technology Leader - FinTech, Risk and Compliance, Payments, Core Banking
4 年Have done the same during this pandemic time. works like a champ
CES Area Service and Maintenance Manager at Messer Americas
4 年Very innovative! Nice work.
Technology & Transformation
4 年Great idea! I had an old Raspberry Pi Model B laying around so you gave me a good afternoon project to play with.