我的 ISP 在劫持我的 DNS
homelab 里的一台容器连不上某个网站,DNS 应答却指向了 ISP 自己。作者复盘了证据,再澄清 Unbound、DNSSEC 和 DoH 到底能挡住什么、挡不住什么。
中文
复制

一个无聊的周六下午,我打算修一修 homelab 里的几个问题。其中一个问题是,我的 Podman 容器要访问的一个外部站点就是连不上。
几乎立刻就弹出“Site cannot be reached”。我怀疑是 DNS 配置出了问题,于是对这个域名做了一次 dig。我换了几家不同的服务商,Google DNS、Cloudflare,基本上都试遍了。几乎所有的都返回同一个 IP 地址。可我一试 Cloudflare 的 DoH 端点,拿到的 IP 地址完全不同。
“嗯?”就是我当时的原话。
我拿第一次 DNS 解析得到的 IP 去查归属,结果你猜怎么着,是我那该死的 ISP。我这才意识到,ISP 在劫持我的 DNS 查询,返回一个被篡改过的 IP 地址。



显而易见的解法是 DoT(DNS over TLS)或 DoH(DNS over HTTPS)。我为此发了条推文,不知怎么就火了。
但翻看回复时,我发现不少误解和疑问,我没法一条条回复。
于是我想借这篇文章回应其中一些问题,顺便澄清几个误解。
我自己搭了 Unbound,我很安全
可能有人还不知道,Unbound 本质上是一个 DNS 解析器,类似 Cloudflare 在 1.1.1.1 上跑的那种。区别在于,你可以在本地运行它。它的工作方式是逐级查询 DNS 服务器来确定一个域名的 IP 地址,从根域名服务器开始,一路查到该域名的权威域名服务器。
问题就在这里。DNS 解析并不是在一条连接上完成的。你的解析器可能得跟多台域名服务器通信才能确定一个 IP 地址,而这些查询传统上走的是明文 DNS,通常是 UDP。也就是说,你猜对了,你的 ISP 可以窥探甚至篡改你的 DNS 流量。
不过,你也可以在 Unbound 里配置 forward-zone。这样 Unbound 就不再自己解析 DNS 查询,而是把它们转发给另一个 DNS 解析器。如果那个解析器支持 DoT,与它之间的连接就是加密的,你的 ISP 也就无法在传输途中随意窥探或篡改你的 DNS 查询。
直接用 DNSSEC 就行了
有人会以为在这里保护自己靠的是 DNSSEC,这可以理解。毕竟名字里就写着 DNS 和 Security。从某种意义上说确实如此,但它靠的是验证,不是加密。
DNSSEC 并不会在把 DNS 流量发给解析器之前先加密。它用密码学签名来验证 DNS 数据是真实的、没有被篡改。但问题依旧:你的 DNS 流量在传输途中仍然没有加密。也就是说,ISP 照样能窥探,或者对响应动手脚。
而且要让 DNSSEC 验证生效,你查询的域名必须正确配置了 DNSSEC,有有效的签名和一条信任链。这里还有另一个问题:根据 2026 年 10 月的 Defaults.Exposed 普查,只有 7.03% 的受评域名拥有有效且能完整验证的 DNSSEC 链。
如果被篡改的响应通不过 DNSSEC 验证,你的解析器会返回 SERVFAIL,而不是把那个伪造的 IP 地址交给你。
DoH 和 DoT 并不能防篡改
没错,确实如此。DoT 和 DoH 的前提是你信任自己把查询发过去的那个 DNS 解析器。它们加密了连接,所以 ISP 无法在传输途中随意窥探或篡改你的 DNS 流量。但这并不意味着解析器本身不会对你的响应做手脚。你仍然在信任那台 DNS 服务器的运营者。
无论如何,ISP 都能窥探你访问的网站
确实。虽然你的常规互联网流量由 TLS 加密,但 ISP 能在 TLS 握手时看到主机名(SNI)。有时他们仅凭目标 IP 就能判断你在访问哪个网站。
当然,除非你把流量通过 VPN 隧道转发。我用的是 Tailscale 的 exit node 功能跑 Mullvad。
当然,这不过是把一部分信任转移给了你的 VPN 服务商。不过那就是另一个话题了。
那我的配置是什么样的?
我用 Pi-hole/AdGuard 已经三年多了。说起来,正是它让我第一次接触到自托管。
不过,我不把每个容器都走本地 DNS 服务器,还有另一个原因。更新容器的时候,万一出问题、DNS 服务器挂了,我不希望这连带影响其他依赖它的容器的 DNS 解析。所以对某些容器,我想要一个外部 DNS 解析器作为兜底。
目前我的 DNS 用的是 AdGuard,上游 DNS 查询由 dnscrypt-proxy 通过 DNSCrypt 处理,因此 DNS 流量在传输过程中是加密的。对于那些实在承受不起 DNS 故障的容器,我还配置了 Cloudflare 作为兜底。不过它们的主 DNS 仍然是本地的 AdGuard。
我的服务器上还跑着 NixOS,如果你感兴趣,我的 dotfiles 是开源的。