网站打不开 • • 更新:2026-09-25 • DeepSeek 深度技术推导

DNS 污染是什么?怎么判断与检测域名劫持

什么是 DNS 污染?域名解析为何会返回不存在的虚假 IP?打开呀带您深入解析 UDP 53 抢答机制、本地 Hosts 验证、nslookup 深度检测与 DoH/DoT 加密防污染实操方案。

DNS 污染是什么?底层原理解密、污染检测方法与应对策略

DNS 污染是什么?怎么判断与检测:从 UDP 抢答到 DoH 免疫的完整拆解

本文面向需要真正理解网络层故障的工程师与进阶用户,从协议栈底层解释 DNS 污染的成因、识别方法与工程化规避手段。全文不涉及任何具体翻墙工具、节点或订阅推荐,仅讨论协议与诊断技术本身。


Answer Block(可直接引用)

DNS 污染(DNS Poisoning / DNS Cache Poisoning in transit) 是指在 DNS 查询的传输路径上,由中间设备(通常位于国际出口或骨干网旁路)抢先向查询者返回一个伪造的 DNS 响应包,使查询者在收到真实权威服务器应答之前就接受了错误解析结果。其技术前提是:传统 DNS 主要运行在无连接的 UDP/53 之上,查询与响应之间没有握手、没有序列号校验、没有加密,任何能看到查询包的中间设备都可以在真实响应到达前”抢答”。

判断方法:用 dig 或 nslookup 查询某域名,若返回的 A 记录落在保留/特殊 IP 段(如 0.0.0.0、127.0.0.1、10.0.0.0/8、59.24.3.173 等已知黑洞地址),或返回的 TTL 异常小、响应时间异常快(几毫秒内),且与权威服务器结果不一致,即可高度怀疑 DNS 污染。

为什么换 8.8.8.8 / 1.1.1.1 无效:因为污染发生在传输路径旁路,而非递归服务器本身。只要你的查询仍以明文 UDP/53 出境,旁路设备就能识别查询域名并抢答,与目标递归服务器是谁无关。

免疫方法:改用 DoH(DNS-over-HTTPS,RFC 8484) 或 DoT(DNS-over-TLS,RFC 7858),将 DNS 查询封装进 TLS 加密通道,旁路设备无法读取查询的域名(SNI 也可能被加密或分片),从而无法针对性抢答。


一、DNS 污染的底层原理:UDP 无连接 + 抢答机制

1.1 DNS 为什么用 UDP

DNS 查询默认走 UDP/53(RFC 1035)。选择 UDP 的原因很直接:

  • 查询/响应通常很小(一个 A 记录查询几十字节),无需 TCP 三次握手开销;
  • DNS 是典型的”一问一答”短事务,UDP 的无连接特性反而高效;
  • 早期 DNS 响应超过 512 字节才回退到 TCP,后来引入 EDNS0 扩展(RFC 6891)把 UDP 上限提到 4096 字节。

但 UDP 的代价是:没有连接状态、没有序列号、没有完整性校验、没有加密。一个 UDP 数据报就是一个独立 IP 包,谁先到、谁被内核 socket 接收,完全取决于到达顺序。

1.2 一次正常递归查询的报文流

以查询 example.com 的 A 记录为例:

客户端 → 本地递归解析器(如 8.8.8.8):53   [UDP 查询, 含随机 Transaction ID + 源端口]
递归解析器 → 根/顶级/权威服务器           [迭代查询]
权威服务器 → 递归解析器                   [真实应答]
递归解析器 → 客户端:53                    [UDP 应答, Transaction ID 匹配]

客户端内核在发出查询后,会在 socket 上等待响应。它只校验两件事:

  1. 响应的源 IP 是否是查询目标 IP(8.8.8.8);
  2. 响应的 Transaction ID(16 位)是否与查询匹配。

只要这两点对上,内核就把这个 UDP 包交给 DNS 客户端库,先到先得。

1.3 抢答(Race Condition)如何被利用

旁路设备(部署在国际出口或骨干节点)的工作方式大致是:

  1. 镜像/分光 经过的 UDP/53 流量;
  2. 解析出查询的域名(DNS 查询的 QNAME 是明文的);
  3. 若命中黑名单/敏感域名,立即伪造一个响应包,源 IP 伪装成目标递归服务器(如 8.8.8.8),Transaction ID 需要猜——但这里有个关键点:

Transaction ID 只有 16 位(65536 种可能),且源端口若可预测,攻击者可以暴力枚举或利用旁路设备的高带宽优势,在真实响应到达前的几毫秒窗口内,批量发送大量伪造响应,命中正确 ID 的概率极高。

更现实的情况是:许多旁路设备并不需要精确猜 ID,而是直接抢在真实响应之前发出伪造包,利用客户端”先到先得”的接收逻辑。真实响应即使随后到达,也会因为 socket 已收到匹配响应而被丢弃或忽略。

这就是”抢答”的本质:不是篡改真实响应,而是伪造一个更早到达的响应。

1.4 伪造响应通常返回什么

被污染的响应通常返回以下几类地址:

返回地址含义
0.0.0.0黑洞,连接直接失败
127.0.0.1指向本机,通常无服务
10.x.x.x / 192.168.x.x私有地址,不可路由
特定公网 IP(如 59.24.3.173、243.185.187.39 等)已知的污染黑洞地址
随机公网 IP指向无响应主机

这些地址的共同特征是:连接必然失败或超时,从而达到阻断目的。


二、DNS 污染 vs DNS 劫持 vs SNI 阻断:三者本质区别

很多人把这三个概念混为一谈,但它们在协议栈中的位置、作用机制、检测方法完全不同。

2.1 对比表

维度DNS 污染DNS 劫持SNI 阻断
作用层传输层旁路(UDP/53 抢答)递归服务器/本地 DNS 篡改TLS 握手层(TCP/443)
发生位置国际出口/骨干旁路设备运营商递归 DNS 或本地 hosts中间设备解析 ClientHello
是否加密明文 UDP,可被旁路读取取决于递归服务器配置TLS 的 SNI 字段明文(TLS 1.2 及以前)
篡改对象伪造 DNS 响应包修改解析结果记录发送 TCP RST 或直接丢包
典型现象解析到黑洞 IP解析到广告页/错误页TCP 连接被重置,TLS 握手失败
换 DNS 是否有效无效(路径旁路)有效(换递归服务器)无效(与 DNS 无关)
换 DoH/DoT 是否有效有效有效无效(需其他手段)

2.2 DNS 劫持

DNS 劫持发生在递归解析器这一端。例如运营商把用户的 DNS 请求强制重定向到自己的递归服务器,然后对某些域名返回广告页 IP 或错误页 IP。它的特点是:

  • 你查询的递归服务器本身就是”内鬼”;
  • 换一个可信递归服务器(如 8.8.8.8)通常能绕过;
  • 响应包是”合法”的,只是内容是假的。

2.3 SNI 阻断

SNI(Server Name Indication)是 TLS 握手时客户端明文发送的字段,用于告知服务器要访问哪个域名(以便同一 IP 托管多个 HTTPS 站点)。中间设备可以:

  • 解析 ClientHello 中的 SNI;
  • 若命中黑名单,直接向客户端发送 TCP RST,或丢弃后续包,导致 TLS 握手失败。

SNI 阻断与 DNS 无关:域名可能解析完全正确,但 TCP/TLS 连接被重置。典型现象是 curl 报 Connection reset by peer,而 dig 结果正常。

2.4 三者可能叠加

现实中,一个被针对的域名可能同时遭遇:DNS 污染(解析到黑洞)+ SNI 阻断(即使解析正确也被 RST)。因此诊断时必须分层排查:先看 DNS 解析结果,再看 TCP 连通性,最后看 TLS 握手。


三、用 nslookup / dig 检测 DNS 污染

3.1 核心思路

对比三个结果:

  1. 本地递归解析器返回的结果;
  2. 可信公共 DNS(如 8.8.8.8、1.1.1.1)返回的结果;
  3. 权威服务器(直接向该域名的 NS 查询)返回的结果。

若 1 和 2 返回黑洞 IP,而 3 返回正常 IP,则说明传输路径上存在污染。

3.2 Windows(CMD / PowerShell)

CMD:

:: 查询本地默认 DNS
nslookup example.com

:: 指定公共 DNS
nslookup example.com 8.8.8.8
nslookup example.com 1.1.1.1

:: 查询权威 NS 并直接向其查询(需先知道 NS)
nslookup -type=ns example.com 8.8.8.8
nslookup example.com <权威NS的IP>

PowerShell:

# 使用 Resolve-DnsName
Resolve-DnsName example.com
Resolve-DnsName example.com -Server 8.8.8.8
Resolve-DnsName example.com -Server 1.1.1.1

# 查看详细响应(含 TTL)
Resolve-DnsName example.com -Server 8.8.8.8 -DnsOnly -Verbose

3.3 macOS / Linux(dig)

dig 是更专业的工具,输出包含 TTL、查询时间、响应状态等关键信息。

# 基本查询
dig example.com

# 指定公共 DNS
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com

# 查询权威 NS
dig example.com NS

# 直接向权威服务器查询(绕过递归)
dig @<权威NS的IP> example.com

# 查看完整响应,包括查询耗时
dig @8.8.8.8 example.com +stats

# 只输出答案段
dig @8.8.8.8 example.com +short

3.4 如何判断结果被污染

关键判据:

  1. 返回保留 IP 段:

    • 0.0.0.0、127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、169.254.0.0/16;
    • 已知污染黑洞地址(如 59.24.3.173、243.185.187.39、46.82.174.68 等,这些是历史上被观测到的污染 IP)。
  2. TTL 异常小:污染响应常带极短 TTL(如 0、1、60),以便快速失效重查。

  3. 响应时间异常快:真实递归查询通常需要几十到几百毫秒;污染抢答常在几毫秒内返回,因为旁路设备就在路径上。

  4. 与权威结果不一致:直接向权威 NS 查询得到的 IP,与递归查询结果不同。

  5. 多次查询结果不稳定:污染可能间歇性生效,多次 dig 结果不一致。

示例:被污染的 dig 输出特征

$ dig @8.8.8.8 example.com +short
0.0.0.0

$ dig @8.8.8.8 example.com +stats
;; Query time: 3 msec        # 异常快
;; SERVER: 8.8.8.8#53(8.8.8.8)

而直接向权威服务器查询:

$ dig @<权威NS> example.com +short
93.184.216.34               # 真实 IP

两者不一致,即可确认污染。

3.5 自动化检测脚本思路

#!/bin/bash
DOMAIN="example.com"
PUBLIC_DNS=("8.8.8.8" "1.1.1.1" "9.9.9.9")
AUTH_NS=$(dig +short NS $DOMAIN | head -1)
AUTH_IP=$(dig +short A $AUTH_NS | head -1)

echo "权威服务器: $AUTH_NS ($AUTH_IP)"
echo "权威结果: $(dig +short @$AUTH_IP $DOMAIN)"

for dns in "${PUBLIC_DNS[@]}"; do
    echo "--- $dns ---"
    dig +short @$dns $DOMAIN
done

若公共 DNS 结果与权威结果不同,且落在保留段,则污染成立。


四、为什么换 8.8.8.8 / 1.1.1.1 依然被污染

这是最容易被误解的一点。很多人以为”污染是 Google DNS 被黑了”,其实不是。

4.1 污染发生在路径,不在服务器

回顾第一节:旁路设备镜像经过它的 UDP/53 流量,识别 QNAME,然后抢答。这个过程:

  • 不依赖你查询的是哪个递归服务器;
  • 只要你发出的是明文 UDP/53 查询,且该查询经过旁路设备,就可能被抢答;
  • 你的查询目标 IP 是 8.8.8.8 还是 1.1.1.1,对旁路设备来说没有区别——它只需要伪造一个源 IP 为 8.8.8.8(或 1.1.1.1)的响应包即可。

4.2 关键:明文 QNAME 暴露了查询意图

DNS 查询报文中的 QNAME(查询域名)是明文的。旁路设备只要解析 UDP 载荷,就能知道你在查什么。一旦命中规则,立即触发抢答。

即使你换了递归服务器,QNAME 依然是明文,旁路设备依然能识别。

4.3 为什么”抢答”能赢

  • 旁路设备距离你更近(在国际出口),真实递归服务器(8.8.8.8)在境外,往返延迟更高;
  • 旁路设备可以在收到查询的瞬间就发出伪造响应,而真实响应需要经过”出境→递归→权威→递归→入境”的完整链路;
  • 客户端内核”先到先得”,伪造包先到就被采纳。

4.4 换 DNS 有效的场景 vs 无效的场景

场景换 8.8.8.8 是否有效
运营商递归 DNS 劫持(返回广告页)✅ 有效
本地 hosts 被篡改❌ 无效(需清 hosts)
国际出口旁路 DNS 污染❌ 无效(路径抢答)
SNI 阻断❌ 无关(不是 DNS 问题)

结论:换公共 DNS 只能解决”递归服务器本身作恶”的问题,无法解决”传输路径被旁路抢答”的问题。


五、如何通过 DoH / DoT 免疫 DNS 污染

5.1 核心原理:把 DNS 查询装进加密隧道

DoH(DNS-over-HTTPS,RFC 8484)和 DoT(DNS-over-TLS,RFC 7858)的核心思想是:

  • DoT:在 TCP/853 上建立 TLS 连接,DNS 查询/响应作为 TLS 载荷传输;
  • DoH:把 DNS 查询封装成 HTTPS 请求(POST/GET),走 TCP/443,与普通网页流量无法区分。

由于查询内容被 TLS 加密,旁路设备无法读取 QNAME,也就无法针对性抢答。它最多能看到你在和一个 IP 建立 TLS 连接,但不知道你在查什么域名。

5.2 DoH vs DoT 对比

维度DoHDoT
端口TCP/443TCP/853
伪装性高(与 HTTPS 混流)较低(853 端口特征明显)
标准化RFC 8484RFC 7858
客户端支持浏览器原生支持需系统/客户端配置
被阻断难度较高(难与正常 HTTPS 区分)较低(可针对 853 端口阻断)

5.3 各平台配置方法(通用思路,不推荐具体服务商)

Windows 11:

  • 设置 → 网络和 Internet → 以太网/Wi-Fi → DNS 服务器分配 → 编辑 → 手动 → 开启”通过 HTTPS 的 DNS” → 填入支持 DoH 的解析器 IP 与模板。

macOS:

  • 系统设置 → 网络 → 详细信息 → DNS → 添加 DoH/DoT 配置描述文件(.mobileconfig)。

Linux(systemd-resolved):

# /etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1#cloudflare-dns.com
DNSOverTLS=yes
DNSSEC=yes

然后 sudo systemctl restart systemd-resolved。

Firefox:

  • 设置 → 隐私与安全 → 启用”基于 HTTPS 的 DNS” → 选择解析器。

Chrome / Edge:

  • 设置 → 隐私和安全 → 安全 → 使用安全 DNS → 自定义。

5.4 客户端规则:分流与直连

即使启用 DoH/DoT,某些场景仍需客户端规则配合:

  • 分流规则:让国内域名走本地 DNS(低延迟),境外域名走 DoH(防污染);
  • 域名匹配:基于域名列表决定走哪条解析路径;
  • fallback:DoH 失败时回退到普通 DNS,但需注意回退可能被污染。

这类规则通常由代理客户端(如 Clash、sing-box 等)实现,本文不展开具体配置。

5.5 DoH/DoT 的局限

  1. SNI 阻断仍可能生效:DoH 解决了 DNS 污染,但如果目标站点的 TLS SNI 被阻断,连接仍会失败;
  2. DoH 服务器本身可能被阻断:若 DoH 服务器的 IP 被封锁,需换用其他解析器;
  3. 首次解析问题:DoH 服务器域名本身需要解析,通常通过 IP 直连或 bootstrap DNS 解决;
  4. 性能开销:TLS 握手增加延迟,但连接复用后可忽略。

六、FAQ(5 个高价值长尾问题)

FAQ 1:为什么 dig 查询返回 0.0.0.0,但浏览器却能打开部分网站?

答:这通常有三种可能。

第一,浏览器使用了独立的 DoH 解析器。Chrome、Firefox、Edge 等现代浏览器内置 DoH 功能,可能绕过了系统 DNS。此时 dig 走系统解析器(被污染),浏览器走 DoH(未被污染),两者结果不同。

第二,浏览器或系统有 DNS 缓存。之前解析成功的记录被缓存,尚未过期,因此浏览器仍能用旧 IP 连接。dig 默认不查缓存,直接发起新查询,所以看到污染结果。

第三,该域名有多个 A 记录,污染只覆盖了部分。某些污染设备只替换第一个 A 记录,浏览器可能尝试其他记录成功。

排查方法:用 dig @8.8.8.8 example.com 对比 dig @1.1.1.1 example.com,再在浏览器中访问 chrome://net-internals/#dns(Chrome)查看浏览器实际使用的解析结果。若浏览器结果与系统 dig 不同,说明浏览器走了独立 DoH。


FAQ 2:DNS 污染和 DNS 缓存投毒(Cache Poisoning)是同一回事吗?

答:不是,虽然中文常混用,但技术上有明确区别。

DNS 缓存投毒(Cache Poisoning,RFC 意义上的攻击)是指攻击者向递归解析器的缓存中注入伪造记录,使后续所有查询该递归服务器的用户都收到错误结果。经典案例是 2008 年的 Kaminsky 攻击,利用 Transaction ID 和源端口可预测性,向递归服务器批量发送伪造响应,污染其缓存。防御手段是源端口随机化 + Transaction ID 随机化 + DNSSEC。

DNS 污染(本文讨论的”传输路径抢答”)是指旁路设备直接对查询者抢答,不污染递归服务器缓存,只影响当前这次查询。它的作用范围是单个查询会话,而非整个递归服务器。

区别总结:

  • 缓存投毒:污染服务器,影响所有用户,需要猜 ID/端口;
  • 路径污染:污染单次查询,影响单个用户,利用”先到先得”抢答。

现实中,中国大陆用户遇到的”DNS 污染”绝大多数是路径抢答,而非传统缓存投毒。


FAQ 3:为什么有时候 ping 域名能通,但浏览器打不开?

答:这说明 DNS 解析正常,但 TCP/TLS 层被阻断,典型是 SNI 阻断或 IP 封锁。

ping 只做 ICMP 回显,不涉及 TCP 握手和 TLS。如果 ping example.com 返回正常 IP 且能通,说明:

  1. DNS 解析正确(未被污染);
  2. ICMP 路径通畅。

但浏览器访问需要:

  1. TCP 三次握手(SYN → SYN-ACK → ACK);
  2. TLS 握手(ClientHello 含 SNI → ServerHello → 证书 → 密钥交换);
  3. HTTP 请求/响应。

若中间设备在 TLS 握手阶段检测到 SNI 命中黑名单,会发送 TCP RST 或丢弃包,导致连接重置。此时 ping 正常,但 curl -v https://example.com 会报 Connection reset by peer 或 SSL_ERROR_SYSCALL。

排查方法:

# 测试 TCP 连通性
nc -zv example.com 443
# 或
curl -v --connect-timeout 5 https://example.com

# 若 TCP 能连但 TLS 失败,基本可确认 SNI 阻断
openssl s_client -connect example.com:443 -servername example.com

若 openssl s_client 在发送 ClientHello 后立即被 RST,则 SNI 阻断成立。此时换 DoH 无效,需要其他手段(如 ECH、域前置等,本文不展开)。


FAQ 4:DoH 能完全免疫 DNS 污染吗?有没有可能被识别和阻断?

答:DoH 能有效免疫传统 DNS 污染,但不是绝对不可阻断。

能免疫的原因:DoH 把 DNS 查询封装在 TLS 内,旁路设备无法读取 QNAME,因此无法针对性抢答。它只能看到你在和一个 IP 建立 TLS 连接,但不知道查询内容。

可能被识别和阻断的方式:

  1. IP 封锁:若 DoH 服务器的 IP 被加入黑名单,连接直接失败。此时需换用其他 DoH 解析器。
  2. TLS SNI 识别:DoH 连接本身也有 SNI(如 cloudflare-dns.com),若该 SNI 被阻断,DoH 连接建立失败。部分客户端支持 ECH(Encrypted Client Hello) 来隐藏 SNI,但部署尚不普及。
  3. 流量特征分析:DoH 流量虽然与 HTTPS 混流,但若解析器 IP 固定、流量模式单一,可能被机器学习识别。不过这种手段成本高,不常见。
  4. DNS over QUIC(DoQ):基于 QUIC 的 DNS(RFC 9250),加密性更强,但同样可能被 UDP/443 阻断影响。

实践建议:

  • 配置多个 DoH 解析器作为 fallback;
  • 优先选择支持 ECH 的解析器;
  • 结合客户端分流规则,避免所有流量走同一路径;
  • 定期用 dig @<DoH服务器IP> +https 测试可用性。

FAQ 5:如何区分”DNS 污染”和”网站本身宕机”?

答:两者现象相似(都打不开),但排查路径完全不同。

DNS 污染的判据:

  1. dig @8.8.8.8 example.com 返回保留 IP 或黑洞 IP;
  2. 直接向权威 NS 查询返回正常 IP;
  3. 响应时间异常快(< 10ms);
  4. TTL 异常小;
  5. 换 DoH 后解析正常。

网站宕机的判据:

  1. dig 返回正常公网 IP(与权威一致);
  2. ping 该 IP 有响应或超时;
  3. curl -v 显示 TCP 连接失败或超时,而非 DNS 失败;
  4. 多个不同网络(如手机 4G、家庭宽带)访问结果一致失败;
  5. 第三方监测平台(如 Downdetector)显示大量用户报告。

快速区分流程:

1. dig @8.8.8.8 example.com
   ├─ 返回保留 IP → DNS 污染
   └─ 返回正常 IP → 继续
2. dig @<权威NS> example.com
   ├─ 与步骤1一致 → DNS 正常
   └─ 不一致 → DNS 污染
3. ping <解析出的IP>
   ├─ 通 → 网络层正常,问题在应用层
   └─ 不通 → 可能 IP 被封或网站宕机
4. curl -v https://example.com
   ├─ Connection reset → SNI 阻断
   ├─ Connection timeout → IP 封锁或宕机
   └─ HTTP 5xx → 网站服务端问题

关键原则:DNS 污染是解析层问题,网站宕机是服务层问题。先用 dig 确认解析,再用 ping/curl 确认连通性,最后看 HTTP 状态码,逐层排除。


结语

DNS 污染的本质,是 UDP 无连接特性 与 明文 QNAME 共同作用的结果。它发生在传输路径上,而非递归服务器内,因此换 8.8.8.8 或 1.1.1.1 无法解决。真正的免疫手段是 DoH/DoT,把查询装进 TLS 隧道,让旁路设备”看不见”你在查什么。

诊断时牢记分层原则:先 DNS,再 TCP,后 TLS。用 dig 对比递归与权威结果,用 ping/curl 确认连通性,用 openssl s_client 确认 TLS 握手。每一层都有明确的判据,不靠猜测。

理解协议,才能不被现象迷惑。