Media Server
Raspberry Pi Projects
Project 2 — Setting up a Pi-hole (Network-Wide Ad Blocker)
What is Pi-hole?
Pi-hole is a DNS sinkhole — it acts as a DNS server for your whole network and intercepts requests for known ad-serving and tracking domains, returning nothing instead of the ad. Because it works at the DNS level, it blocks ads in every app and on every device — phones, smart TVs, game consoles, tablets — without installing anything on those devices.
What You Will Need
Step 1 — Update Your Pi
Start with a clean, up-to-date system:
pi@raspberrypi:~$ sudo apt update && sudo apt upgrade -y pi@raspberrypi:~$ sudo reboot
Reconnect via SSH after about 30 seconds.
Step 2 — Set a Static IP Address
Before installing Pi-hole, give your Pi a fixed local IP. If your router restarts and assigns the Pi a different IP, DNS will break for your whole network — so this step is important.
Option A (recommended): DHCP reservation in your router. Find the MAC address of your Pi and tell your router to always give it the same IP. The MAC address is shown by:
pi@raspberrypi:~$ ip link show eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ... link/ether dc:a6:32:ab:12:34 brd ff:ff:ff:ff:ff:ff
Option B: Static IP in /etc/dhcpcd.conf (see Project 1 for the full configuration snippet).
192.168.1.100 works well and is easy to remember.
Step 3 — Run the Pi-hole Installer
Pi-hole provides a single installer script that handles everything. The project recommends inspecting the script before running it — you can view it at install.pi-hole.net.
pi@raspberrypi:~$ curl -sSL https://install.pi-hole.net | bash
The installer launches a blue text-based setup wizard. Work through the screens:
- Network interface: choose
eth0(wired) orwlan0(Wi-Fi). Wired is preferred. - Upstream DNS provider: choose who Pi-hole asks when a domain is not blocked. See the options below — Cloudflare (
1.1.1.1) is a good default choice. - Blocklists: accept the default StevenBlack list. You can add more lists later from the admin dashboard.
- Admin web interface: select On. This gives you the statistics dashboard.
- Web server (lighttpd): select On — this serves the admin interface.
- Log queries: select On — useful for seeing what is being blocked.
- Privacy level: Show everything gives you the most useful statistics on a home network.
At the end of the install, the wizard will display your admin dashboard URL and the randomly generated admin password. Copy this password now — you will need it to log in.
[i] The install log is in /etc/pihole/install.log Pi-hole installation complete! ────────────────────────────────────────────────────────── Web interface address: http://192.168.1.100/admin Admin password: a7fX92mQ ← copy this! ──────────────────────────────────────────────────────────
pihole -a -p
Step 4 — Choose Your Upstream DNS
Pi-hole only handles blocked domains itself. For everything else it forwards the query to an upstream DNS provider. You set this during install but can change it at any time in the admin dashboard.
Step 5 — Point Your Router to Pi-hole
This is the step that makes Pi-hole work for every device on your network. You need to change your router's DNS setting to use the Pi's IP address instead of your ISP's DNS servers.
- Log in to your router admin panel (usually
http://192.168.1.1) - Find the DHCP settings — not the WAN/Internet DNS, but the DNS that your router hands out to local devices
- Set the Primary DNS to your Pi's IP (e.g.
192.168.1.100) - Set the Secondary DNS to a fallback such as
1.1.1.1(optional — see note below) - Save and apply
1.1.1.1), devices will fall back to it if Pi-hole is unreachable — meaning they will get ads again but won't lose internet. If you leave secondary DNS blank (or set it to the same Pi IP), you get more consistent blocking but lose internet if Pi-hole goes down. On a home network, setting a secondary is the safer choice.
After saving your router settings, reconnect a device (or wait for its DHCP lease to renew) then verify it is using Pi-hole as its DNS:
# On Windows: nslookup google.com Server: 192.168.1.100 ← this should show your Pi's IP Address: 192.168.1.100#53 # On Mac / Linux: dig google.com | grep "SERVER:" ;; SERVER: 192.168.1.100#53(192.168.1.100)
Step 6 — Explore the Admin Dashboard
Open http://192.168.1.100/admin (replace with your Pi's IP) in a browser and log in with the password from Step 3.
Dashboard overview
The home screen shows your key statistics at a glance:
| Stat | What it means |
|---|---|
| Queries today | Total DNS lookups made by all devices on your network today |
| Queries blocked | Number (and %) of queries blocked as ads/trackers |
| Domains on blocklist | Total number of domains currently blocked |
| DNS queries / 10 min | Live traffic graph — great for spotting unusual activity |
Useful dashboard sections
| Section | Where | What you can do |
|---|---|---|
| Query Log | Tools → Query Log | See every DNS request in real time — which device asked for what, and whether it was blocked |
| Top Blocked Domains | Dashboard home | See which ad/tracker domains are most active on your network |
| Top Clients | Dashboard home | See which device makes the most DNS queries |
| Whitelist | Whitelist menu | Un-block domains that Pi-hole incorrectly blocks (false positives) |
| Blacklist | Blacklist menu | Manually block specific domains not on any blocklist |
| Adlists | Group Management → Adlists | Add community blocklist URLs to expand coverage |
| Settings → DNS | Settings menu | Change upstream DNS, enable DNSSEC, configure conditional forwarding |
Step 7 — Add Extra Blocklists
The default StevenBlack blocklist is solid, but the community maintains many specialist lists. Add them in Group Management → Adlists in the admin dashboard, then update gravity:
pi@raspberrypi:~$ pihole -g [i] Pi-hole version is v5.18.3 [i] Neutrino emissions detected... [✓] Pulling blocklist source list into range [✓] Preparing new gravity database [✓] Retrieving blocklist from: https://raw.githubusercontent.com/StevenBlack/hosts/... [✓] Storing downloaded list in temporary space [✓] Number of domains being pulled in by gravity: 131,818 [✓] Gravity blocking is enabled
Popular additional lists:
| List | URL | Focus |
|---|---|---|
| StevenBlack Fakenews | https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews/hosts | Fake news sites |
| OISD (full) | https://big.oisd.nl | Very comprehensive; low false-positive rate |
| Developer Dan | https://www.github.developerdan.com/hosts/lists/ads-and-tracking-extended.txt | Ads & trackers extension |
| Energized Porn | https://block.energized.pro/porn/formats/hosts.txt | Adult content (optional parental filter) |
Step 8 — Whitelisting and Blacklisting
Whitelisting (un-blocking a domain)
Sometimes Pi-hole blocks something it shouldn't — a streaming service CDN, a bank's security check, a game's update server. Whitelist from the command line or the admin dashboard:
pi@raspberrypi:~$ pihole -w domain.example.com [i] Adding domain.example.com to the whitelist... [✓] domain.example.com has been whitelisted
Blacklisting (blocking an extra domain)
pi@raspberrypi:~$ pihole --blacklist annoyingsite.example.com [i] Adding annoyingsite.example.com to the blacklist... [✓] annoyingsite.example.com has been blacklisted
Regex blacklisting
You can block entire patterns using regular expressions:
pi@raspberrypi:~$ pihole --regex '(.+\.)?ads\..*' # blocks any domain matching this regex pattern
Step 9 — Keeping Pi-hole Updated
Pi-hole has its own update mechanism separate from apt:
pi@raspberrypi:~$ pihole -up [i] See a log of this update at: /var/log/pihole/pihole_updatecheck.log [✓] Pi-hole core files are up to date [✓] Pi-hole Web Interface files are up to date [✓] FTL binary is up to date
Also update your blocklists regularly to catch new ad domains:
pi@raspberrypi:~$ pihole -g # update gravity (blocklists)
Automate blocklist updates with cron
pi@raspberrypi:~$ sudo crontab -e
Add this line to update gravity every Sunday at 03:00:
0 3 * * 0 pihole -g > /dev/null 2>&1
Optional: Enable DNSSEC
DNSSEC verifies that DNS responses haven't been tampered with in transit. Enable it in Settings → DNS → Advanced DNS settings → Use DNSSEC in the admin dashboard. Your chosen upstream DNS provider must also support DNSSEC (Cloudflare, Google, and Quad9 all do).
Optional: Enable Conditional Forwarding
By default, the Query Log shows device IP addresses (like 192.168.1.12) rather than device names (like Phillips-iPhone). Conditional forwarding tells Pi-hole to ask your router to resolve local IP addresses to hostnames.
Enable it in Settings → DNS → Advanced DNS settings → Use Conditional Forwarding and enter your router's IP and local domain (often local or home).
Troubleshooting Common Problems
pihole status. As a quick fix, revert your router DNS to its original value while you investigate.pihole -w the-blocked-domain.com. Common culprits: font CDNs, analytics endpoints used for licence checking, game anti-cheat systems.sudo systemctl status lighttpd then sudo systemctl restart lighttpd. Also verify Pi-hole itself is running: pihole status.ipconfig /release && ipconfig /renew on Windows / sudo dhclient -r && sudo dhclient on Linux.8.8.8.8) and ignore your router's DNS setting. To force them through Pi-hole, add a firewall rule on your router that intercepts all UDP traffic on port 53 destined for anything other than your Pi and redirects it to your Pi. This is called "DNS hijacking" and the steps vary by router model.htop. Also check if your blocklists have grown very large — a combined list over 2 million entries can slow down a Pi Zero. Try removing some of the larger adlists in Group Management → Adlists and re-running pihole -g. Also ensure the Pi has a reliable power supply — under-voltage causes throttling.sudo rm /etc/pihole/gravity.db-journal then re-run pihole -g.pihole -a -p — you will be prompted to enter a new password (or press Enter twice to set no password).Quick Reference
| Task | Command |
|---|---|
| Check Pi-hole status | pihole status |
| Update Pi-hole software | pihole -up |
| Update blocklists (gravity) | pihole -g |
| Whitelist a domain | pihole -w domain.com |
| Remove whitelist entry | pihole -w -d domain.com |
| Blacklist a domain | pihole --blacklist domain.com |
| Remove blacklist entry | pihole --blacklist -d domain.com |
| Disable blocking (5 min) | pihole disable 5m |
| Disable blocking (permanent) | pihole disable |
| Re-enable blocking | pihole enable |
| Reset admin password | pihole -a -p |
| View recent queries (CLI) | pihole -t (live tail) |
| View Pi-hole logs | sudo tail -f /var/log/pihole/pihole.log |
| Admin dashboard URL | http://<pi-ip>/admin |
| Restart Pi-hole FTL | sudo systemctl restart pihole-FTL |
| Restart web interface | sudo systemctl restart lighttpd |