Worcester Area Linux Users Group // 2026-Feb-12

Your ISP is Spying
on You

DNS Hijacking, Reverse NAT, Broken Resolvers
& Fighting Back with Encrypted Tunnels

$ dig +trace example.com
;; WARNING: response from unexpected source

DNS: A Quick Refresher

Your computer asks "where is example.com?" ��� here's what should happen:

Your PC
���
Recursive
Resolver
���
Root
Servers
���
.com TLD
Servers
���
Authoritative
NS

Recursive Resolver

Does the legwork ��� walks the DNS tree from root ��� TLD ��� authoritative. Can be your ISP's, a third party (8.8.8.8, 1.1.1.1), or your own (Unbound). A forwarder like Pi-hole passes queries to an upstream resolver instead of walking the tree itself.

Forwarder vs. Recursive

A forwarder (Pi-hole, dnsmasq) sends your query to another server to resolve. A recursive resolver (Unbound) queries root servers directly and walks the tree itself ��� no single third party sees your full query.

Two DNS Approaches at Home

Forwarding (Common Setup)

Pi-hole ��� forwards to 1.1.1.1 / 8.8.8.8

Your Device
���
Pi-hole
���
Cloudflare / Google

Problem: Cloudflare or Google sees every query. Your ISP can also intercept this via Reverse NAT.

vs

Recursive (Private Setup)

Pi-hole ��� Unbound (recursive, talks to root)

Your Device
���
Pi-hole
���
Unbound (recursive)

Benefit: No single third party sees all your queries. Each authoritative server only sees its piece.

The Privacy Power of Recursive + Caching

1
Query splitting: When Unbound resolves www.example.com, it asks the root about .com, the TLD about example.com, and the authoritative NS for the final record. No single server sees the full query tied to you.
2
QNAME Minimization (RFC 7816): Unbound sends only the minimum necessary part of the name to each server. The root server sees "who handles .com?" ��� it never sees "www.example.com".
3
Aggressive caching: After the first lookup, the result is cached locally. TTLs for popular domains can be hours or days. Subsequent lookups never leave your network. No external server ��� ISP, Google, or otherwise ��� ever sees the repeat query.
4
Prefetching: Unbound refreshes expiring cache entries before they expire (prefetch: yes). Popular domains essentially never generate external queries after initial resolution.
The result: After a warm-up period, the vast majority of your DNS lookups are answered from local cache. They never leave your house. No ISP, no third party, no one can track what you're resolving ��� because the queries simply don't exist on the wire.

Tracking Exposure: Forwarder vs. Recursive

Forwarding to 1.1.1.1 / 8.8.8.8

Every query ��� cached or not by them ��� is sent with your source IP to that provider. They build a complete profile: every domain, when, how often. Cloudflare and Google publish privacy policies, but you're trusting a corporation with your entire browsing history. Even with DoH/DoT, the resolver operator sees everything.

Recursive + Cache (Unbound)

Authoritative servers see fragmented queries from your IP, but no single server sees the full picture. After caching, repeat queries are invisible ��� answered locally. Your browsing patterns become effectively untrackable.

The Cache Effect

Typical home network: 80-90% cache hit rate within hours. Only 10-20% of queries ever leave your network. With prefetching, even less. Every cached response is a query no one can spy on.

Think of it this way: Forwarding to Google is like telling one person every website you visit. Recursive resolution is like asking 50 different strangers for directions to 50 different places ��� and then memorizing the routes so you never have to ask again.

What Spectrum Did: Reverse NAT

Spectrum uses Reverse NAT (Destination NAT) to intercept all DNS traffic on port 53

Your Network
Pi-hole ��� Unbound
���
UDP :53
dst: 1.1.1.1
���
Spectrum
DNAT REWRITE
���
Spectrum's
DNS Servers

How Reverse NAT Works

Spectrum's network equipment performs Destination NAT (DNAT) on all outbound UDP port 53 packets. The destination IP is rewritten ��� regardless of what you set ��� to point at Spectrum's own resolvers. Your packet to 1.1.1.1, 8.8.8.8, or 198.41.0.4 never reaches its intended destination.

It Catches Everything

It doesn't matter if you configure Pi-hole to forward to Cloudflare, Google, Quad9, or run Unbound pointed at root servers. Any DNS packet on UDP 53 leaving your network gets its destination rewritten. You think you're talking to Cloudflare. You're not.

Why Reverse NAT is Insidious

Silent Interception

Most users never know it's happening. If Spectrum's resolver returns a valid answer, everything appears to work. You configured 1.1.1.1 in Pi-hole and believe queries go to Cloudflare. They don't. Spectrum answers and you'd never notice ��� unless something breaks.

Defeats "Just Change Your DNS"

The common advice ��� "change your DNS to 8.8.8.8 or 1.1.1.1" ��� is completely useless against Reverse NAT. The destination IP is rewritten at the network level before your packet ever reaches the intended server.

Why Reverse NAT is Insidious

Breaks DNSSEC Validation

If Spectrum's resolver doesn't properly support DNSSEC or returns different records, DNSSEC validation fails. Your security tooling breaks because your ISP is tampering with the chain of trust.

Complete Surveillance

Spectrum now has a complete log of every DNS query from your network ��� every site, every device, every timestamp. This data can be sold to advertisers, shared with third parties, or handed to law enforcement.

How Reverse NAT Breaks Unbound

1
Unbound (behind Pi-hole) sends a recursive query to 198.41.0.4 (a.root-servers.net).
2
Spectrum's Reverse NAT rewrites the destination IP ��� the packet goes to Spectrum's resolver instead.
3
Spectrum's resolver processes the query and responds ��� but the source IP is Spectrum's address, not 198.41.0.4.

How Reverse NAT Breaks Unbound

4
Unbound performs source address validation ��� it sent to 198.41.0.4 but got a reply from a different IP. Response rejected as potentially spoofed.
5
DNS fails across your entire network. Pi-hole can't get answers from Unbound. Every device loses DNS.
unbound[1234]: error: reply from unexpected source
  96.x.x.x#53, expected 198.41.0.4#53
  for query example.com. A IN

Detecting DNS Reverse NAT Hijacking

Test 1: Who's actually answering?

$ dig +short txt whoami.ds.akahelp.net @1.1.1.1
# Should show Cloudflare's resolver
# If it shows your ISP ��� hijacked

Test 2: Trace the path

$ dig +trace example.com
# Watch for responses from unexpected IPs in the chain

Detecting DNS Reverse NAT Hijacking

Test 3: tcpdump ��� definitive proof

$ sudo tcpdump -n -i eth0 udp port 53
# Send: dig @1.1.1.1 example.com
# Watch: does the response come from 1.1.1.1 or a different IP?

Test 4: Compare resolver identity

$ dig +short @1.1.1.1 o-o.myaddr.l.google.com TXT
# Returns IP of who's querying Google's authoritative servers
# Should be Cloudflare, not your ISP

The Solution: Encrypted Tunnel + VPS

Move recursive resolution outside your ISP's network ��� connect over an encrypted tunnel they can't DNAT

Your Devices
���
Pi-hole
Block + Cache
���
Headscale
Tunnel
WireGuard
���
VPS Unbound
Recursive
���
Root / Auth
Servers
Your ISP sees encrypted WireGuard traffic to your VPS. DNS queries are inside the tunnel ��� Spectrum can't inspect or redirect them. Reverse NAT is completely bypassed. Most queries hit Pi-hole's local cache and never leave your house at all.

Solution Components

Pi-hole (Local)

Your local DNS server. Handles ad/tracker blocking, caching, and local DNS zones. Queries it can't answer go through the encrypted tunnel. Most queries hit cache and never leave your network.

Headscale + WireGuard

Self-hosted Tailscale control server. Creates an encrypted WireGuard tunnel. DNS forwards travel inside this tunnel ��� Spectrum can't see or redirect the contents. Reverse NAT is irrelevant.

VPS Unbound (Recursive)

Full recursive mode on a VPS outside Spectrum's network. Queries root and authoritative servers directly with QNAME minimization. Combined with Pi-hole's caching, only 10-20% of queries ever reach this point.

Why Headscale?

Self-Hosted Tailscale

Headscale is an open-source, self-hosted Tailscale coordination server. You get mesh networking without trusting a third party with your network topology or traffic metadata.

Defeats Reverse NAT

DNS queries travel inside an encrypted WireGuard tunnel. Spectrum's Reverse NAT targets plaintext DNS on port 53 ��� it can't intercept what it can't read. The encrypted tunnel makes their DNAT rules irrelevant.

Why Not Just DoH/DoT?

DNS-over-HTTPS / DNS-over-TLS

These encrypt the transport, but you're still forwarding to someone else's resolver. Cloudflare/Google still see every query. With your own recursive resolver, nobody sees the full picture.

Full Mesh Network

Headscale gives you more than DNS ��� access your homelab remotely, SSH, route traffic between sites. One encrypted overlay for everything.

Setup: VPS ��� Headscale

Install on a cheap VPS ($5/mo ��� Hetzner, Linode, DigitalOcean)

# Install headscale
sudo apt install headscale

# Configure and start
sudo systemctl enable --now headscale

# Create a user & pre-auth key
headscale users create homelab
headscale preauthkeys create \
  --user homelab --reusable
Headscale is the coordination server ��� it handles key exchange and node registration. The actual data flows over WireGuard peer-to-peer between your home and VPS.

Setup: VPS ��� Unbound

Full recursive resolver ��� no forwarders, talks directly to root servers

# /etc/unbound/unbound.conf
server:
  interface: 100.64.0.1  # Headscale IP only
  access-control: 100.64.0.0/10 allow

  # Full recursive ��� no forwarders
  root-hints: /etc/unbound/root.hints

  # DNSSEC validation
  auto-trust-anchor-file:
    "/var/lib/unbound/root.key"

  # Privacy + performance
  qname-minimisation: yes
  prefetch: yes
Unbound only listens on the Headscale interface (100.64.x.x) ��� invisible to the public internet. Only devices on your Headscale network can reach it.

Setup: Home ��� Tailscale Client

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

# Connect to YOUR Headscale server
sudo tailscale up \
  --login-server https://hs.yourdomain.com \
  --authkey YOUR_PREAUTH_KEY
Your Pi-hole machine now has a 100.64.x.x address and an encrypted tunnel to the VPS. Spectrum sees encrypted WireGuard UDP ��� nothing else.

Setup: Home ��� Pi-hole

# Pi-hole upstream DNS setting:
# Set to VPS Unbound via Headscale IP
100.64.0.1#53

# Pi-hole still handles:
# ��� Ad/tracker blocklists
# ��� Local DNS / CNAME records
# ��� Caching (most queries)
# ��� Query logging & dashboard
That's the whole change. Pi-hole forwards uncached queries to 100.64.0.1 ��� traffic goes through the WireGuard tunnel automatically. Pi-hole's caching means most queries never leave your network at all.

The Complete Picture

Your Home Network
All Devices
192.168.1.0/24
���
Pi-hole
Blocklists �� Cache
Local DNS �� Logging
cache miss ���
Tailscale Client
WireGuard Encrypt
��� Encrypted WireGuard Tunnel
Spectrum's Network
Spectrum
Sees encrypted UDP
to your VPS IP
Nothing else
���
Your VPS
Headscale
Coordination
���
Unbound
Full Recursive
QNAME Minimization
���
Root & Auth
DNS Servers
Unintercepted

Spectrum Sees

Encrypted WireGuard traffic to your VPS. Zero DNS visibility.

Nobody Sees

Cached queries (80-90%) never leave your network. Completely invisible.

You Get

Untampered, DNSSEC-validated, private, ad-free DNS.

Considerations & Caveats

Latency on Cache Miss

Cache misses add a VPS round-trip (~20-50ms). Mitigate with Pi-hole + Unbound caching, prefetch: yes, and a geographically close VPS. With warm cache, most users never notice.

VPS = Single Point of Failure

If VPS goes down, uncached queries fail. Add a fallback in Pi-hole: a DoT/DoH provider (Quad9, Mullvad) as secondary upstream. Less private, but better than no DNS.

VPS Provider Trust

Your VPS provider could see recursive queries leaving the server. Choose a privacy-respecting provider.

DNS Only, Not a Full VPN

This routes only DNS through the tunnel. Your ISP still sees destination IPs of HTTPS connections via SNI/IP headers. For full traffic privacy, route everything ��� but that's a different talk.

The Bigger Problem

What ISPs Are Doing

DNS Reverse NAT is just one piece. ISPs also perform deep packet inspection, sell browsing history to advertisers, inject tracking headers (Verizon's "supercookies"), and lobby against privacy regulations.

The FCC repealed broadband privacy rules in 2017. ISPs have no legal obligation to protect your DNS privacy in the US. They are financially incentivized to collect and monetize your data.

What You Can Do

Run Pi-hole + recursive Unbound ��� stop feeding the data machine. Use encrypted tunnels to bypass Reverse NAT. Push for ECH adoption. Support privacy legislation. Teach others.

Every person who takes control of their DNS is one fewer data point. With caching, that data simply ceases to exist.

Resources

Pi-hole

pi-hole.net ��� Network-wide ad blocking + local DNS
docs.pi-hole.net/guides/dns/unbound/ ��� Unbound integration guide

Unbound

nlnetlabs.nl/projects/unbound ��� Validating, recursive, caching resolver

Headscale

github.com/juanfont/headscale ��� Self-hosted Tailscale control server

Testing & Further Reading

dnsleaktest.com �� browserleaks.com/dns �� RFC 7816 (QNAME Minimization) �� RFC 7626 (DNS Privacy)

Questions?

Let's dig into it

$ dig +short txt whoami.ds.akahelp.net
"Your resolver: YOU, not your ISP"