EDNS0 是什么?它为什么能让 DNS 支持更大的 UDP 响应和扩展能力?
简化版
EDNS0 是 DNS 的扩展机制,用来在不改变 DNS 基本报文格式的前提下,扩展 UDP 响应大小、携带额外选项和能力信息。
传统 DNS UDP 响应大小常被认为受 512 字节限制,EDNS0 允许客户端声明自己能接收更大的 UDP payload,比如 1232 或 4096 字节。DNSSEC、大量记录、IPv6 等场景都可能需要更大响应。
但 UDP 响应过大可能导致 IP 分片和丢包,所以现代实践会谨慎设置大小。
详细版
EDNS0 通过 OPT 伪记录表达扩展信息:
;; OPT PSEUDOSECTION:
; EDNS: version: 0, udp: 1232
这不是普通 DNS 资源记录,而是协议扩展字段。
它可以告诉服务端:
- 客户端支持 EDNS version 0。
- 客户端可接收的 UDP 响应大小。
- 是否支持 DNSSEC 相关标志。
- 可携带 ECS 等扩展选项。
如果响应仍然太大,服务端可以设置 TC 标志,让客户端改用 TCP 查询。
完整版教学
1. 先说明传统 DNS 的限制
DNS 最早设计时响应通常很小。
传统 UDP DNS 响应常按 512 字节限制处理。
但现代 DNS 变复杂了。
例如:
- DNSSEC 会带签名记录。
- IPv6 带来 AAAA 记录。
- 一个域名可能有多个 A/AAAA。
- TXT 记录可能较长。
EDNS0 的作用是给 DNS 老协议加扩展能力,尤其是更大的 UDP 响应能力。
2. EDNS0 如何工作
EDNS0 不是新增一个独立协议。
它通过 DNS 报文里的 OPT 伪资源记录表达能力。
示例输出:
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
这里 udp: 1232 表示客户端声明自己能接收的 UDP payload 大小。
服务端看到后,可以返回超过传统 512 字节的响应。
3. 为什么需要更大的 UDP 响应
DNSSEC 是典型原因。
DNSSEC 响应除了普通记录,还可能包含 RRSIG、DNSKEY、DS 等记录。
响应很容易超过 512 字节。
如果没有 EDNS0,就会频繁退回 TCP,增加延迟和资源开销。
EDNS0 让更多查询可以仍然用 UDP 完成。
4. UDP 大包的风险
UDP 响应不是越大越好。
如果响应超过路径 MTU,可能发生 IP 分片。
分片带来问题:
- 任一分片丢失,整个响应失败。
- 某些网络设备丢弃分片。
- 分片可能增加安全风险。
- 放大攻击中大响应会放大流量。
因此很多实现会选择较保守的 UDP payload 大小。
5. EDNS0 和 TCP 回退
如果 DNS 响应仍然放不下,服务端可以设置 TC 标志。
TC=1
客户端看到响应被截断,就应该使用 TCP 重新查询。
| 场景 | 处理方式 |
|---|---|
| 小响应 | 普通 UDP 返回 |
| 中等响应 | EDNS0 扩大 UDP payload |
| 响应仍过大 | TC=1,客户端 TCP 重查 |
| 网络丢弃大 UDP | 客户端可能降级或重试 |
所以 EDNS0 不是替代 TCP,而是减少不必要的 TCP 回退。
6. EDNS Client Subnet 也是扩展之一
EDNS0 还可以携带选项。
常见扩展之一是 ECS,EDNS Client Subnet。
它允许递归 DNS 向权威 DNS 暴露部分客户端网段,帮助 CDN 做更准确调度。
但 ECS 会带来隐私和缓存碎片化问题。
这说明 EDNS0 是扩展框架,不只是“大 UDP”。
7. 常见误区与追问
- 误区:EDNS0 是新的 DNS 服务器类型。 它是 DNS 协议扩展机制,不是服务器角色。
- 误区:UDP 响应越大越好。 大 UDP 可能分片、丢包,也会增加放大攻击风险。
- 误区:有 EDNS0 就不会用 TCP。 响应过大或被截断时仍需要 TCP 回退。
- 追问:为什么 DNSSEC 需要 EDNS0? DNSSEC 响应包含签名和密钥记录,体积常超过 512 字节。
- 追问:OPT 是普通业务记录吗? 不是,它是协议层伪记录,用于传递扩展能力。
- 追问:ECS 有什么副作用? 可能泄露客户端网段,并降低缓存命中率。
8. 加强记忆
EDNS0 记成“DNS 的扩展插槽”。
最常见用途是告诉服务端:我能接收比 512 字节更大的 UDP 响应。