首页 / 内容指南 / 当前文章

DNS 的 UDP、TCP、EDNS(0)、UDP Payload Size、TC 位、IP 分片和 TCP 回退有什么区别?

发布于 2026-08-26 · Content Fleet 编辑部

DNS 的 UDP、TCP、EDNS(0)、UDP Payload Size、TC 位、IP 分片和 TCP 回退有什么区别?

七个概念快速对比

DNS 为什么同时支持 UDP 和 TCP

传统 DNS 查询通常优先使用 UDP,因为一次请求和一次响应不必先建立连接,时延和状态开销都较低。RFC 1035 规定 DNS 同时使用 UDP 与 TCP 的 53 端口,并为当时不带扩展的 UDP DNS 消息设置了 512 字节限制。超过这一限制的响应可以被截断,并设置 TC 位。

“DNS 的 UDP 最大只能是 512 字节”只描述了未使用 EDNS 的历史基线,不是现代 DNS 的绝对上限。DNSSEC、公钥材料、较大的 TXT RRset、服务发现记录以及包含多条附加记录的回答,都可能轻易超过 512 字节。

TCP 为 DNS 提供可靠的字节流。每条 DNS 消息前带一个两字节长度字段,接收方据此从 TCP 流中划分消息边界。现代完整 DNS 实现必须支持 TCP。TCP 不只是出现 TC 后的补救方式;客户端可以主动选择 TCP,服务器也应支持连接复用、多个查询流水化等行为。区域传送通常也使用 TCP,但普通查询改用 TCP 并不等于正在做区域传送。

EDNS(0) 到底扩展了什么

EDNS(0) 通过附加区中的 OPT 伪资源记录扩展 DNS。OPT 不是区域文件里的普通资源记录,不能像 A、AAAA 或 MX 那样被缓存。它为双方提供扩展 RCODE、EDNS 版本、标志位和可选项的承载位置。

EDNS 本身不是 UDP 或 TCP,也不提供加密。它既不隐藏查询名称,也不验证回答真伪。DNSSEC 常用的 DO 位位于 EDNS 标志字段,用来表示请求方希望获得 DNSSEC 相关记录;是否完成密码学验证、结果是 Secure 还是 Bogus,是解析器的另一套状态。

UDP Payload Size 表示什么

在查询里的 OPT 记录中,请求方会通告它愿意接收的 UDP DNS 报文大小。服务器应把这个数值、自己的发送上限及实际网络条件一起考虑,不能把通告值理解为“必须生成这么大的响应”。

该数值也不等于路径 MTU。路径中可能有隧道、VPN、PPPoE、IPv6 扩展头或其他额外开销;请求端接口能接收某个大小的数据报,也不代表路径上每一跳都能无分片承载它。把 EDNS 缓冲区盲目设成 4096,可能减少 DNS 层截断,却增加 IP 分片概率。

许多运营环境采用 1232 字节作为较保守的 UDP DNS 有效大小。这个值与 IPv6 最小 MTU 1280 字节扣除基本 IPv6 头和 UDP 头有关,目标是减少分片风险。它是常见运营选择,不是适用于所有链路的协议硬上限;实现、网络和策略可以选择不同上限。

TC 位表示什么

TC 是 DNS 报文头的 Truncated 标志。服务器无法在允许的消息大小内放入完整响应时,可以返回一个设置 TC 的截断响应。客户端看到 TC 后,不应把当前不完整内容当成最终完整答案,通常应通过 TCP 重试。

TC 只说明 DNS 响应被截断,不说明截断的唯一原因,也不等于网络超时。反过来,UDP 报文可能在分片、防火墙、NAT 或负载均衡器处被丢弃,客户端只看到超时,根本收不到可供检查的 TC 位。因此“没有 TC”不能证明大 UDP 响应传输正常。

IP 分片为什么容易造成 DNS 隐性故障

当 UDP 数据报超过可用路径 MTU时,IPv4 可能由发送端或中间设备分片;IPv6 中间路由器不执行分片,发送端需要依据路径 MTU 信息调整。任何一个分片丢失,接收端就无法重组完整 UDP 数据报。某些防火墙只正确识别首片的 UDP 端口,某些 NAT 对后续分片处理不一致,ICMP Packet Too Big 又可能被错误过滤,最终表现为间歇性 DNS 超时。

分片还扩大了资源消耗与安全攻击面。因此现代 DNS 运营建议尽量控制 UDP 响应大小,避免依赖 IP 分片,并保持 TCP 53 可达。仅放行 UDP 53 的访问控制策略是不完整的 DNS 策略。

TCP 回退何时发生

最清晰的路径是:客户端发送带 EDNS 的 UDP 查询,服务器发现完整答案超出可发送范围,返回 TC=1,客户端随后用 TCP 重发查询并取得完整结果。

实际实现还可能在 UDP 多次超时、怀疑路径不支持较大 EDNS 报文、收到协议错误或执行自身重试策略时,降低通告大小、禁用某些 EDNS 能力、换用其他服务器或切换 TCP。具体顺序取决于解析器实现。超时不是 DNS RCODE,不能把它直接解释成 SERVFAIL、REFUSED 或 TC。

TCP 也可以从一开始就使用。RFC 7766 强调 TCP 是 DNS 的有效传输选择,而非仅限于回退。长连接可减少重复握手;流水化允许一个连接上存在多个未完成查询;响应可能与请求顺序不同,客户端应结合 DNS ID 和 Question 匹配响应。

DNSSEC 为什么更容易暴露传输问题

启用 DO 位后,回答可能带 DNSKEY、RRSIG、NSEC 或 NSEC3 等记录,消息体显著增大。同一名称在不请求 DNSSEC 数据时可以通过 UDP 正常返回,请求 DNSSEC 后却可能触发 TC、分片或 TCP。

这不等于 DNSSEC 验证失败。必须区分两类问题:一类是报文未能完整传输,表现为超时、TC 或 TCP 连接失败;另一类是签名链验证失败,验证器通常把结果判为 Bogus,并可能向客户端返回 SERVFAIL。先确认传输完整,再判断密码学验证状态。

EDNS 不兼容会有什么表现

老旧 DNS 代理、中间盒或错误实现可能丢弃带 OPT 的查询,错误返回 FORMERR,或不正确处理 EDNS 版本。支持良好的客户端可能执行兼容性重试,但兼容性机制不能替代修复网络设备。

EDNS 版本协商也不同于缓冲区大小。服务器不支持请求的更高 EDNS 版本时,可以通过扩展响应码表示 BADVERS;这并非说明域名不存在。诊断时应记录查询是否带 OPT、EDNS 版本、通告大小、响应码和 TC,而不是只看最终应用错误。

如何用 dig 分层验证

先比较不带 EDNS、带保守缓冲区和强制 TCP 的结果:

dig example.com A +noedns
dig example.com A +bufsize=1232
dig example.com A +tcp

检查 DNSSEC 数据时可增加 DO 位:

dig example.com DNSKEY +dnssec +bufsize=1232
dig example.com DNSKEY +dnssec +tcp

输出中的 MSG SIZE 是实际 DNS 消息大小,不等于整个 IP 包大小。flags 中出现 tc 表示截断。+tcp 成功而 UDP 查询超时,说明应继续检查 UDP 大响应、分片和中间网络;它不能单独证明权威服务器配置正确。

抓包时至少核对以下信息:查询和响应的五元组、OPT 是否存在、通告的 UDP Payload Size、实际响应长度、TC 位、是否产生 IPv4/IPv6 分片、是否出现 ICMP Packet Too Big,以及随后是否建立 TCP 53 连接。

权威 DNS 与递归解析器分别检查什么

权威侧应确认服务器按客户端 EDNS 通告和本地上限生成响应,过大时能正确设置 TC,并在 TCP 53 上提供同一查询的完整回答。还应确认负载均衡、防火墙和 DDoS 防护没有只转发 UDP。

递归侧应确认出站 UDP 与 TCP 53 均可达,能对 TC 正确重试,TCP 连接与并发限制不会过低,并避免向下游返回自己未完整取得的数据。若递归解析器向客户端通告的能力与其真实网络条件不一致,也可能把上游问题放大。

客户端侧则要区分本机 Stub Resolver、企业转发器和最终递归解析器。操作系统工具显示的超时可能发生在任意一段,不能仅凭客户端日志断定权威 DNS 丢包。

一套可执行的故障定位顺序

1. 用同一查询分别测试默认 UDP、+bufsize=1232+tcp

2. 记录回答大小、TC、RCODE、OPT 和 EDNS 版本,不只记录“解析失败”。

3. 在客户端、递归出口和权威入口能控制的位置同步抓包,定位报文在哪一段消失。

4. 检查 UDP 响应是否分片、ICMP Packet Too Big 是否返回、路径中是否存在隧道或较小 MTU。

5. 验证防火墙、NAT、四层负载均衡和安全设备同时允许 UDP 53 与 TCP 53。

6. 查看 TCP 是否完成握手、DNS 长度前缀是否正确、服务器是否在返回回答前过早关闭连接。

7. 对 DNSSEC 查询额外检查 DO 位和响应中的签名记录,把传输失败与验证失败分开。

8. 修复后重复多种回答大小和 IPv4/IPv6 测试,避免只验证一个恰好很小的 A 记录。

常见配置错误

  • 把 EDNS 缓冲区设得越大越好,忽略路径 MTU 与分片风险。
  • 防火墙只允许 UDP 53,导致所有 TC 后重试失败。
  • 看到 UDP 超时就认定服务器返回了 TC,实际上响应可能在途中丢失。
  • 把 1232 当成不可变化的协议上限,而非降低分片风险的运营值。
  • 把 OPT 当成可以写进区域和缓存的普通记录。
  • 将 EDNS、DoH、DoT 混为一谈;EDNS 不提供传输加密。
  • +tcp 成功就断言 DNSSEC 正常,未继续验证签名链。
  • 只测小型 A 记录,没有测试 DNSKEY、TXT 或其他大 RRset。

FAQ

1. DNS 是否默认只使用 UDP?

不是。普通查询常优先使用 UDP,但完整 DNS 实现必须支持 TCP。客户端可以在 TC 后重试 TCP,也可以主动从 TCP 开始查询。

2. 不带 EDNS 的 UDP DNS 是否永远只能返回 512 字节?

512 字节是传统 DNS 的 UDP 消息基线。服务器面对更大答案通常返回截断响应并设置 TC,客户端再用 TCP获取完整回答。带 EDNS 后可以通告更大的 UDP 接收能力。

3. EDNS 的 UDP Payload Size 是路径 MTU 吗?

不是。它是请求方声明愿意接收的 UDP DNS 消息大小,不保证中间路径无分片可承载该大小,也不要求服务器一定返回同样大的消息。

4. 为什么常见配置是 1232 字节?

1232 与 IPv6 最小 MTU 扣除基本 IPv6 和 UDP 头后的空间相符,常被用来降低分片概率。隧道、扩展头和具体网络仍可能改变可用空间,所以它不是所有场景的绝对上限。

5. 响应没有 TC,为什么仍然超时?

服务器可能发送了未截断但发生 IP 分片的响应,其中一个分片被中间设备丢弃;也可能整个响应被防火墙过滤。客户端没有收到 DNS 报文,自然看不到 TC。

6. TCP 回退失败最先检查什么?

先检查 TCP 53 是否在客户端、递归器、权威服务器及中间防火墙、NAT、负载均衡器上全程放行,再检查连接限制、超时和服务器 TCP 处理能力。

7. EDNS(0) 是否会加密 DNS 查询?

不会。EDNS 扩展 DNS 报文能力和选项,但不提供保密性。加密传输需要 DoT、DoH、DoQ 等机制。

8. DNSSEC 查询超时就表示签名错误吗?

不表示。DNSSEC 数据往往更大,可能先触发传输、分片或 TCP 可达性问题。只有取得完整响应后,才能可靠判断签名链是否有效。

结论

UDP 负责低开销传输,TCP 负责可靠承载完整 DNS 消息;EDNS(0) 扩展能力通告,UDP Payload Size 只描述接收意愿;TC 明确表示响应被截断,IP 分片则可能在没有任何 DNS 错误码的情况下造成丢包。稳定的 DNS 基础设施应控制 UDP 响应规模、减少分片依赖、完整开放 TCP 53,并把传输故障与 DNSSEC 验证故障分开诊断。

参考来源

1. IETF RFC 1035, Domain Names - Implementation and Specification: https://www.rfc-editor.org/rfc/rfc1035.html

2. IETF RFC 6891, Extension Mechanisms for DNS (EDNS(0)): https://www.rfc-editor.org/rfc/rfc6891.html

3. IETF RFC 7766, DNS Transport over TCP - Implementation Requirements: https://www.rfc-editor.org/rfc/rfc7766.html

4. IETF RFC 9210, DNS Transport over TCP - Operational Requirements: https://www.rfc-editor.org/rfc/rfc9210.html

5. IETF RFC 9715, IP Fragmentation Avoidance in DNS over UDP: https://www.rfc-editor.org/rfc/rfc9715.html

6. IETF RFC 8900, IP Fragmentation Considered Fragile: https://www.rfc-editor.org/rfc/rfc8900.html

7. IETF RFC 5625, DNS Proxy Implementation Guidelines: https://www.rfc-editor.org/rfc/rfc5625.html