Your DNS ad blocker is a man in the middle you invited
DNS-level ad blocking with public blocklists is great, until you realise you've given strangers the power to rewrite where your traffic goes.
I run DNS-level ad blocking at home, like many engineers I know. One resolver for the whole network, a few public blocklists, and suddenly every device is quieter: the laptop, the phones, the TV, the kids’ tablets. It’s one of the best things you can set up in an afternoon.
But I’ve started to look at it differently. A DNS resolver doesn’t just block. It decides where your traffic goes. And when you subscribe to a public blocklist, you let someone else write part of that decision.
A blocklist you didn’t write is configuration you didn’t review, applied to every device you own.
Blocking versus rewriting
Most people think of a blocklist as a list of domains that return nothing. That’s how Pi-hole treats them: if a list contains 1.2.3.4 ads.example.com, it strips the IP address and simply blocks the domain.
Not every tool works that way. AdGuard Home, for example, supports /etc/hosts-style rules and answers with the IP address in the rule. Its filter syntax also has a $dnsrewrite modifier that can replace the answer with any record you like. That’s useful for your own rules. In a list maintained by a stranger, it means one line is enough:
203.0.113.66 login.yourbank.example
Every device on your network now resolves your bank to a server of the list maintainer’s choosing. Nobody needs to hack anything. A maintainer turns malicious, an account gets taken over, or a popular list is quietly handed to a new owner, and you pull the update automatically, every night.
“But HTTPS protects me”
Mostly, yes. A redirected browser will usually refuse to connect, because the attacker can’t present a valid certificate for your bank. That’s a real and important protection.
But a lot of traffic on a home or office network doesn’t have that protection:
- Plain HTTP, still used by plenty of devices, update checks and captive portals.
- Email. Server-to-server SMTP often uses opportunistic TLS without strict certificate checks, and older mail clients aren’t much better.
- FTP, NTP, syslog and other old protocols with no authentication of the server at all.
- IoT devices that skip certificate validation, which is more of them than you’d like.
- Internal tools where someone once set
verify=Falseto get past a self-signed certificate.
And even when TLS holds, an attacker who controls DNS still learns where you go, and can block things selectively: security updates, your password manager’s sync server, your MFA provider.
DNSSEC doesn’t save you here either. It protects the answer on its way to your resolver. If the resolver itself is the one rewriting, the client has nothing to compare it against.
How I’d do it
I’m not giving up DNS blocking. I’m treating the blocklists like any other third-party dependency:
- Use fewer lists, from maintainers with a track record. Ten overlapping lists give you more risk, not much more blocking.
- Make sure rules can only block. Use software that ignores IP addresses in lists, or check that your setup does. In AdGuard Home, keep rewrites for your own rules only.
- Watch for anything that isn’t a block. A simple check on each update for lines that map a domain to a real IP address, or contain
$dnsrewrite, catches the obvious attack. - Pin and review. For an office network, mirror the lists yourself, diff the updates and roll them out deliberately, the same way you’d treat a dependency update in code.
- Fix the protocols that need it. Don’t let internal services fall back to plain HTTP or unvalidated TLS. Give them real certificates instead.
Ad blocking at the DNS level is still worth it. Just remember that the resolver is the most trusted component on your network. Treat whatever feeds it with the same suspicion you’d give any other code you run.