A set-and-forget network appliance: Pi-hole handles both DNS ad-blocking and DHCP for the whole house, resolves DNS privately through its own recursive resolver instead of trusting a third party, follows your phone over cellular via Tailscale, and is hardened against SD card wear and un-patched vulnerabilities.

Hardware: Raspberry Pi Zero 2 W (512MB RAM, ~415MB usable)

OS: Raspberry Pi OS Lite, Debian 13 "trixie" (64-bit)

Stack: Pi-hole v6 (ad-blocking DNS + DHCP) → Unbound (recursive resolver, DNSSEC) · Tailscale (VPN) · log2ram · unattended-upgrades · vnstat

---

Phase 1: The Foundation (Installation)

We're installing the core ad-blocking software. We use the "Lite" OS to save memory.

Step 1: Initial System Update

sudo apt update && sudo apt upgrade -y

Step 2: Install Pi-hole v6

curl -sSL https://install.pi-hole.net | bash

Prompts: Select wlan0 (Wi-Fi), accept the static IP, and enable the Web Interface. If your OS is newer than the installer's allowlist (trixie was, at time of writing), seed /etc/pihole/setupVars.conf first and run with PIHOLE_SKIP_OS_CHECK=true ... --unattended instead of the interactive installer.

✅ Check-in Point: Is it alive?

dig google.com @127.0.0.1

Success: You should see an ANSWER SECTION with an IP address.

---

Phase 2: Unbound — Your Own Private Resolver

Rather than forwarding every query to Google or Cloudflare, Pi-hole can resolve DNS itself, recursively, straight from the root servers — nobody outside your network ever sees your full browsing pattern.

Step 1: Install and Configure Unbound

sudo apt install unbound -y

Drop a config in /etc/unbound/unbound.conf.d/pi-hole.conf that listens on 127.0.0.1:5335, enables DNSSEC validation, and sets qname-minimisation: no. Strict qname-minimisation is more private in theory, but it produces SERVFAILs on some flaky CDN/AWS-hosted domains that public resolvers happily resolve — disabling it fixes those while DNSSEC still validates.

Disable unbound-resolvconf.service so it doesn't fight Pi-hole for port 53.

Step 2: Point Pi-hole at Unbound

In the Pi-hole admin, set upstream DNS to 127.0.0.1#5335. Set listening mode to ALL (not just LAN) so Tailscale clients can query it too.

✅ Check-in Point: DNSSEC Working?

dig sigfail.verteiltesysteme.net @127.0.0.1     # should SERVFAIL

dig sigok.verteiltesysteme.net @127.0.0.1 # should resolve, with the ad flag set

---

Phase 3: Router Integration — Pi-hole Becomes the DHCP Server

Some routers (Verizon's included) don't let you actually override the DNS server they hand out to clients — the "DNS" page is often just a hostname table. The reliable fix is to turn off the router's DHCP entirely and let Pi-hole hand out IP addresses itself — since Pi-hole is the DHCP server, it can hand out itself as the DNS server, no router cooperation required.

Step 1: Give the Pi a Static IP First

Before touching the router, lock in the Pi's own address via netplan (or dhcpcd.conf on older OS releases) — otherwise disabling router DHCP will strand it without an address.

Step 2: Router Settings

1. Log into your router's admin page.

2. Find DHCP (often under Network / Advanced settings) and set it to Disabled.

3. Find IPv6 and disable it — otherwise devices grab an IPv6 DNS server from the ISP and bypass Pi-hole entirely; ads leak through over IPv6 even with IPv4 DNS locked down.

Step 3: Configure DHCP on Pi-hole

In the admin UI (or pihole.toml directly), set:

dhcp.active    = true

dhcp.start = 192.168.1.10

dhcp.end = 192.168.1.240

dhcp.router = 192.168.1.1

dhcp.leaseTime = 168h # 7 days — rides out long Pi outages

dhcp.ipv6 = false

Step 4: Add a Failsafe Backup DNS

Hand out a second DNS server alongside Pi-hole so the internet keeps working during a Pi outage or reboot:

misc.dnsmasq_lines = [ "dhcp-option=6,192.168.1.249,1.1.1.1" ]

Pi-hole stays primary; Cloudflare's 1.1.1.1 only kicks in if the Pi doesn't answer. Trade-off: a slice of everyday queries can land on 1.1.1.1 even while the Pi is healthy, so a few ads leak through — a deliberate uptime-over-purity choice for a single point of failure serving your whole house.

---

Phase 4: Remote Access — Tailscale Everywhere

Part A: Install Tailscale on the Pi

curl -fsSL https://tailscale.com/install.sh | sh

sudo tailscale up --ssh --accept-dns=false --hostname=pihole

  • --accept-dns=false stops Tailscale from overriding the Pi's own resolver with its own.
  • --ssh turns on Tailscale SSH, so any device on your tailnet can SSH in without managing keys.

Part B: Tailnet-Wide Ad-Blocking (Including Cellular)

This is the upgrade over "just use the Tailscale IP when away from home": in the Tailscale admin console under Nameservers, add the Pi's Tailscale IP (e.g. 100.x.x.x) as a custom nameserver, add 1.1.1.1 as a backup, and enable "Override local DNS."

With that flipped, every device on your tailnet — including your phone on cellular data, nowhere near your Wi-Fi — routes its DNS through Pi-hole. Ad-blocking follows you out of the house. Only the small DNS lookups tunnel through Tailscale, so there's no meaningful speed hit. Trade-off: the 1.1.1.1 backup means some off-network queries can leak to Cloudflare if you want strict blocking, list only the Pi's Tailscale IP — but then a Pi outage means no DNS at all while Tailscale is active.

Part C: Admin Access Over the Tailnet

Because Pi-hole's listening mode is ALL, the web admin (http://<tailscale-ip>/admin) and any third-party Pi-hole controller app work the same over Tailscale as they do on the LAN — just swap the LAN IP for the Tailscale IP when you're away from home.

---

Phase 5: The "Block" Configuration (Lists & Regex)

We're layering a "Mobile Game Killer" configuration on top of the base blocklists.

Step 1: Add Adlists (The Big Lists)

1. Go to Adlists in the Web Interface.

2. Add these URLs:

List NameURL
Steven Blackhttps://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
Hagezi Prohttps://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/pro.txt
Phishing Armyhttps://phishing.army/download/phishing_army_blocklist_extended.txt
AdGuard DNShttps://v.firebog.net/hosts/AdguardDNS.txt

3. Crucial: After adding them, go to Tools > Update Gravity and click Update.

Step 2: Add Regex Filters (The Smart Filters)

These block entire ad networks (Unity, AppLovin, etc.) used by mobile games. Go to Domains > Regex and add as Blacklist:

Mobile Game Ad Networks:

^ads\.unity3d\.com$

^config\.unityads\.unity3d\.com$

^.*applovin\.com$

(\.|^)unity3d\.com$

(\.|^)unityads\.unity3d\.com$

(\.|^)ironsrc\.com$

(\.|^)supersonicads\.com$

(\.|^)vungle\.com$

(\.|^)liftoff\.io$

(\.|^)chartboost\.com$

(\.|^)adcolony\.com$

(\.|^)tapjoy\.com$

(\.|^)inmobi\.com$

(\.|^)mintegral\.com$

(\.|^)rayjump\.com$

(\.|^)pangle\.io$

(\.|^)moloco\.(com|net|map\.fastly\.net)$

(\.|^)inner-active\.map\.fastly\.net$

Video/Streaming Ads:

^.*\.mediatailor\.us-east-1\.amazonaws\.com$

^g[0-9]+-vod-us-cmaf-prd-fy\.cdn\.peacocktv\.com$

^star\.fallback\.c10r\.facebook\.com$

Google Aggressive Ads:

(\.|^)googleads\.g\.doubleclick\.net$

^adservice\.google\.com$

^pagead2\.googlesyndication\.com$

Step 3: Exact Blocking (Privacy Features)

Go to the "Exact" tab in Domains and add these as Blacklist:

Block iCloud Private Relay (forces Apple devices to use Pi-hole instead of tunneling DNS to Apple):

  • mask.icloud.com
  • mask-h2.icloud.com

Block Firefox DoH (forces Firefox to use Pi-hole instead of its own DNS-over-HTTPS):

  • use-application-dns.net

---

Phase 6: Longevity & Maintenance

A Pi running 24/7 needs three things a default install doesn't give you: protection for the SD card, automatic security patching, and a way to see it's actually healthy without SSHing in.

Log2Ram — Save the SD Card

Constant log writes are the #1 way SD cards die in appliances like this. Log2Ram mounts /var/log as a RAM-backed tmpfs and flushes to disk periodically instead.

curl -L https://github.com/azlux/log2ram/archive/master.tar.gz | tar zxf -

cd log2ram-master

chmod +x install.sh

sudo ./install.sh

cd ..

rm -r log2ram-master

Pi-hole's query database and vnstat's database live outside /var/log, so historical stats survive reboots normally even with logs in RAM.

unattended-upgrades — Automatic Security Patching

sudo apt install unattended-upgrades -y

sudo dpkg-reconfigure --priority=low unattended-upgrades

Runs daily; logs to /var/log/unattended-upgrades/unattended-upgrades.log. One less thing to remember on an appliance you might not touch for months.

vnstat — Know Your Bandwidth

sudo apt install vnstat -y

Tracks wlan0 traffic over time — handy for spotting a device gone rogue or just satisfying curiosity about how much the household actually streams.

✅ Check-in Point: Verify Storage

df -h | grep log2ram

Success: You should see a line starting with log2ram.

Final Step: Reboot to lock everything in.

sudo reboot

---

Phase 7: A Home Page for Your Appliance (Optional)

Pi-hole's own web server already has a document root — drop a static index.html there and you get a status dashboard at http://pihole.local/ with zero extra services to run. A small generator script (cron'd every couple of minutes) can pull live numbers straight from the sources you already have running and re-render the page:

  • Pi-hole's query DB — 24h queries/blocked/rate, top clients and domains, latest blocked query
  • vcgencmd/free/df — CPU temp, RAM, disk, load
  • vnstat — today/month bandwidth
  • tailscale status — connected peer count
  • systemctl is-active per service — live up/down cards for Pi-hole FTL, Unbound, Tailscale, log2ram, vnstat, unattended-upgrades, and the cron job itself

The page auto-refreshes client-side every 60 seconds, so it works as a fallback status board even if you don't want to build a full separate dashboard.

---

Summary

Your Pi-hole is now configured as a full home network appliance:

  • ✅ Network-wide ad blocking and DHCP, both served by one small Pi
  • ✅ Private recursive DNS resolution via Unbound — nobody sees your query history but you
  • ✅ Mobile game and streaming ad elimination via targeted regex
  • ✅ iCloud Private Relay and Firefox DoH blocked so nothing bypasses the filter
  • ✅ Ad-blocking that follows your phone over cellular via Tailscale tailnet DNS
  • ✅ Failsafe backup DNS so a Pi reboot never takes down the internet
  • ✅ SD card longevity (log2ram), automatic security patching (unattended-upgrades), and bandwidth visibility (vnstat)
  • ✅ A zero-extra-services status page for at-a-glance health checks