Pi-hole + AdGuard — DNS as a network-level filter
Browser adblock leaves the TV and phone exposed. DNS-level filtering covers every device. Showing my Pi-hole + AdGuard upstream setup.

uBlock Origin blocks ads in the browser. The TV, has no uBlock. The phone, apps don't use uBlock. Console, smart home, IoT, all phone home with ads and telemetry.
Solution: blocking at the DNS level. Every device asks DNS for a server's IP, if DNS refuses (returns 0.0.0.0), communication doesn't happen. The whole network gets filtering at once.
Architecture
[Every device in LAN]
↓ DNS query
[Pi-hole on a Proxmox VM] ← filters known ad domains
↓ if OK
[AdGuard upstream] ← second filter + DoH (DNS over HTTPS)
↓
[Cloudflare 1.1.1.1 / Quad9]The local router has Pi-hole as primary DNS in DHCP. Every device follows automatically.
Pi-hole setup
A VM on Proxmox, Ubuntu Server, 1GB RAM (more than needed, Pi-hole works on 256MB).
curl -sSL https://install.pi-hole.net | bashInstaller asks:
- Interface (usually
eth0) - Upstream DNS (I pick Custom → AdGuard)
- Block lists (default is OK to start)
- Web UI (yes, port 80)
- Logging (yes, but TTL 7 days)
After 5 minutes the panel is at http://pi-hole.local/admin.
AdGuard as upstream
Why two filters? Pi-hole has a huge community blocklist, AdGuard adds:
- very aggressive anti-tracking lists
- DNS-over-HTTPS (DoH) to upstream
- regex matching (Pi-hole only domain match)
AdGuard setup as a VM or simpler, Docker:
services:
adguard:
image: adguard/adguardhome
ports:
- "8853:53/udp"
- "8853:53/tcp"
- "3000:3000"
volumes:
- adguard-data:/opt/adguardhome/confIn Pi-hole settings → DNS → custom upstream: 192.168.x.x:8853.
What's worth in the block list
Default lists handle ads. I add:
- OISD basic, modern, well-maintained
- Steven Black hosts, aggregates many lists, ad+tracking+malware
- AdGuard SDN trackers, mobile app telemetry
- Custom: smart-home domains that phone home too much
I block things like *.tuya.com (Chinese bulbs), *.miio.com (Xiaomi), *.tplinkcloud.com, their products work locally, telemetry isn't needed.
Whitelist — without it, things break
Some apps die when you block their telemetry. I have ~15 whitelists:
# Spotify telemetry - blocking breaks skip-between-devices
gew4-spclient.spotify.com
ap-gew4.spotify.com
# Apple - blocking breaks iCloud sync
*.apple.com (selectively)
# PL banks - PSD2 requires their telemetry
api.mbank.plRule: if something breaks, I check Pi-hole logs, identify the domain, add to whitelist. Max 5 minutes.
Results after a year
Stats from my Pi-hole:
- Total blocked queries: ~4M
- % blocked: 23%
- Most blocked:
app-measurement.com(Google Analytics mobile) - Top 3 query-generating devices: LG TV, wife's phone, Sonos
Pitfalls
1. Single point of failure. Pi-hole down → whole internet down. I have a second Pi-hole as secondary DNS in DHCP. Auto failover.
2. CDN load balancing. Some services use DNS for load balancing (return different IPs). Pi-hole's cache can disrupt that. TTL set to max 1h.
3. DoH/DoT bypass. Modern browsers (Firefox, Chrome) can use DoH directly to CF/Google, bypassing my DNS. Disable in browser settings OR block port 853 on the firewall.
4. Smart TV bypass. LG and Samsung hardcode Google DNS. Bypass. Solution: firewall rule blocking port 53 outbound for the TV's IP.
Bonus: Home Assistant integration
Pi-hole has an API. I have an HA integration:
- Blocked queries stat on the dashboard
- "Disable blocking for 5 min" button (when something breaks)
- Alert when blocking exceeds 50% (sign that something weird is happening)
# configuration.yaml
pi_hole:
- host: 192.168.1.10
api_key: !secret pihole_api_keyDNS-level blocking is the most leveraged thing you have on a home network. Configure once, works for everything, in the background. Pi-hole takes ~10 minutes to set up and gives ad, telemetry and malware filtering for every device on the LAN.