DNSSEC 介绍:DNS 签名、信任链与验证实践
AI 参与说明(Agent:Codex):本文由 Codex 根据 IETF RFC 与 ISC BIND 9 官方文档辅助撰写、核对概念并验证查询示例,资料整理于 2026-09-09。运行记录:模型
gpt-6-astra,reasoning effortultra,执行入口 Codex Desktop,提供方openai,CLI 版本0.153.4(不代表桌面 App 版本)。
当 DNS 告诉你“这个域名对应某个 IP 地址”时,怎样确认这份数据没有被伪造?DNSSEC 为 DNS 数据增加可验证的数字签名。理解它的关键,是分清“数据可信”“传输保密”和“网站可信”这三个问题。
阅读前先认识这些词
中文名称用于词义对照;后文固定使用左栏名称。
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| DNSSEC | 域名系统安全扩展 | 英文全称 DNS Security Extensions;为 DNS 数据提供来源认证和完整性校验的一组协议 |
| zone | 区域 | DNS 中统一管理的一段命名空间;委派出去的子区作为独立 zone 管理 |
| authoritative server | 权威服务器 | 对某个 zone 的 DNS 数据给出正式回答的服务器 |
| recursive resolver | 递归解析器 | 替客户端查询 DNS、缓存结果并返回答案的服务 |
| validating resolver | 验证解析器 | 能根据 DNSSEC 规则判断数据可信状态的解析器 |
| RRset | 资源记录集 | 名称、类型和类别相同的一组 DNS 记录 |
| trust anchor | 信任锚 | 通过可信方式预先取得、作为验证起点的公钥或摘要 |
| chain of trust | 信任链 | 从已信任的起点逐级认证后续 DNS 数据的关系 |
DNSSEC 解决什么问题
DNSSEC lets a validating resolver authenticate signed DNS data through a chain of trust. It does not encrypt DNS queries or responses. 这是对 RFC 4033 §3–4 所述能力与边界的概括。
假设客户端查询 www.example.com。传统 DNS 的答案可能来自递归查询,也可能直接来自缓存;如果攻击者成功把伪造地址塞进响应或缓存,客户端就可能得到错误结果。DNSSEC 让验证方进一步检查:这组数据是否由对应 zone 的可信密钥签署,签名是否匹配,是否仍在有效期内。
它主要提供三项能力:
- 来源认证:确认数据可追溯到被授权为该 zone 签名的密钥。
- 完整性校验:发现签名覆盖的数据遭到修改。
- 可验证的不存在证明:对“名称不存在”或“没有这种类型的记录”提供可检查的证据。
因此,DNSSEC 能让验证方拒绝无法通过认证的伪造答案,但不会让攻击者失去发包、丢包或阻断服务的能力。RFC 9364 将使用 DNSSEC 为 DNS 数据提供来源认证列为 Best Current Practice;这不等于所有域名或所有客户端都已经启用它。RFC 9364 §1.1
三个容易越界的理解
DNSSEC 不保证保密。 域名和记录仍可能以明文传输,签名与公钥也可以公开查询。
DNSSEC 不保证网站内容安全。 合法控制域名的一方可以签署一个指向恶意网站的地址;如果 DNS 管理账户或签名密钥被攻破,错误配置也可能获得有效签名。签名认证的是 DNS 数据来源,不是域名持有者的信誉。
DNSSEC 不保证每次返回最新数据,也不保证可用性。 缓存仍然存在;在协议允许的缓存与签名有效窗口内,旧的有效数据可能继续被接受。签名失效、配置错误或网络故障都可能导致解析失败。RFC 4033 §4、§12
签名对象是 RRset
DNSSEC signs RRsets, not entire DNS messages. A response can contain both signed data and protocol information that is not covered by those signatures. RFC 4034 §3、RFC 4035 §2
下面是教学用记录,域名与地址均用于示例,不是部署配置:
www.example.com. 300 IN A 192.0.2.10
www.example.com. 300 IN A 192.0.2.11
两条记录的名称都是 www.example.com.,类型都是 A,类别都是 IN,属于同一个 RRset。签名覆盖这组数据;任意修改其中一个 IP,就不能继续通过原签名的验证。同名的 AAAA 记录属于另一个 RRset,需要另行签名。
DNSSEC 增加了哪些记录
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| RRSIG | 资源记录集签名 | 保存某个 RRset 的数字签名以及算法、有效期等信息 |
| DNSKEY | DNS 公钥 | 在 zone 中公布验证签名所需的公钥;不含私钥 |
| DS | 委派签名者记录 | 在父区保存子区某个 DNSKEY 的摘要等信息,连接两级信任关系 |
| NSEC | 下一安全记录 | 用有序名称范围和类型信息,证明某些名称或记录不存在 |
| NSEC3 | 哈希化的不存在证明记录 | 使用名称的哈希值构造不存在证明的另一种机制 |
查询 A 记录时,返回的 RRSIG A 是对这个 A RRset 的签名;查询 DNSKEY 时,RRSIG DNSKEY 则覆盖 DNSKEY RRset。RRSIG 还带有签名生效时间、到期时间和帮助定位公钥的 key tag。RFC 4034 §2–3
DS 不是把子区的全部公钥复制到父区。它包含 key tag、签名算法编号、摘要算法编号及摘要;摘要计算涉及 DNSKEY 的名称和记录数据。DS 发布在父区,把它当成普通记录加到自己的子区里,不能建立这条父子信任关系。key tag 只是匹配线索,也不能代替摘要和签名校验。RFC 4034 §5
NSEC 与 NSEC3 解决一个容易忽略的问题:攻击者不仅可能伪造 IP,还可能谎称“没有这个名称”。它们配合签名,让验证方检查否定答案。NSEC3 使用哈希并不等于加密 zone,也不保证名称无法被猜出;不要把秘密放进 DNS,指望 NSEC3 隐藏它。RFC 5155 §1、§12
公钥本身怎样获得信任
只拿到 DNSKEY 和一份“验证成功”的签名还不够:攻击者也可以生成自己的密钥,再为伪造数据签名。验证方需要知道,为什么应该信任这把公钥。
在公共 DNS 的常见部署中,validating resolver 预先持有根区的 trust anchor,再通过各级 DS 和签名向下认证。下面假设 .com 与 example.com 都正确签名并建立了 DS 关系;这是一张信任依赖图,不表示每次查询都必须重新访问全部服务器。
flowchart TD
A["预先信任根区 trust anchor"] --> B["认证根区 DNSKEY RRset"]
B --> C["验证根区发布的 com. DS RRset"]
C --> D["匹配公钥并认证 com. DNSKEY RRset"]
D --> E["验证 com. 发布的 example.com. DS RRset"]
E --> F["匹配公钥并认证 example.com. DNSKEY RRset"]
F --> G["验证 www.example.com. 的 A RRset 与 RRSIG"]
G --> H["得到经过认证的 A RRset"]
每下降一级,先利用已经认证的父区公钥验证子区 DS,再找到摘要匹配的子区 DNSKEY,并用它验证子区 DNSKEY RRset 的相应签名。完成后,才能信任该 RRset 中符合协议条件的公钥,用于验证子区其他数据。RFC 4035 §5.2–5.3
这里有两个边界:
- 委派边界不等于每个点号。 如果
www.example.com只是example.comzone 中的记录,它不需要再有一条 DS;只有另行委派成子区时才涉及新的父子关系。 - 根区不是唯一可能的起点。 私有 DNS 或特定部署可以配置其他 trust anchor;从哪里开始信任,属于验证方的配置和策略。RFC 4033 §2
KSK 与 ZSK 必须分成两把密钥吗
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| KSK | 密钥签名密钥 | 在常见分工中主要签署 DNSKEY RRset,并与父区 DS 配合 |
| ZSK | 区域签名密钥 | 在常见分工中主要签署 zone 的其他 RRset |
| CSK | 合并签名密钥 | 用同一把密钥承担上述两种签名职责 |
分开 KSK 与 ZSK,可以把频繁的普通数据签名密钥轮换,与需要父区配合的变更分开管理;使用 CSK 则能减少密钥角色。它们是运维分工,不是“协议强制每个 zone 恰好两把密钥”。无论采用哪种方式,都必须保持签名、DNSKEY、DS 与缓存生命周期协调。RFC 6781 §3.1、§4
验证结果不只有成功与失败
DNSSEC validation distinguishes Secure, Insecure, Bogus, and Indeterminate data. An unsigned delegation is not automatically a validation failure. RFC 4033 §5
| 状态 | 含义 | 应怎样理解 |
|---|---|---|
| Secure | 从适用的 trust anchor 建立了信任关系,相关验证通过 | 数据已获得 DNSSEC 认证;也可能是经过认证的否定答案 |
| Insecure | 能确定某处不存在继续验证所需的安全委派,或由明确策略确定无需继续验证 | 通常可按未获得 DNSSEC 保护的数据处理;不表示已发现伪造 |
| Bogus | 本应能够验证,却无法建立必要证据 | 例如 DS 与 DNSKEY 不匹配、缺失所需签名或签名过期 |
| Indeterminate | 缺少适用的信任起点或足够信息,无法确定是否应验证 | 不能简单当成 Secure,也不等于一个固定的 DNS 响应码 |
表格中的状态是验证语义;NOERROR、NXDOMAIN、SERVFAIL 则是 DNS 响应码,两者不是一一对应关系。例如,一个有效的不存在证明也可以是 Secure。
对普通、未要求跳过验证的客户端请求,验证方发现 Bogus 时通常返回 SERVFAIL,不会把答案当作已认证数据交给客户端。但 SERVFAIL 也可能来自网络故障、服务器异常等原因,不能只看这个词就认定 DNSSEC 出错。RFC 4035 §5.5
“查不到 DS”也不能孤立地证明 Insecure:在已认证的父区中,验证方需要认证 DS 不存在的证据。另一个边界是算法支持:若经过认证的 DS RRset 中没有任何验证方支持的签名与摘要算法路径,协议要求按未签名情形处理,不能笼统写成 Bogus。RFC 4035 §5.2、RFC 6840 §5.2
DNSSEC、DoH、DoT 和 HTTPS 各管哪一段
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| DoH | 通过 HTTPS 传输 DNS | 使用 HTTPS 承载 DNS 查询和响应 |
| DoT | 通过 TLS 传输 DNS | 使用专门的 TLS 连接承载 DNS 查询和响应 |
| HTTPS | 安全超文本传输协议 | 使用 TLS 保护 HTTP 通信,并按证书规则认证对端 |
| 机制 | 主要保护对象 | 仍不能据此推断什么 |
|---|---|---|
| DNSSEC | DNS 数据的来源与完整性 | 查询内容已加密、网站没有恶意内容 |
| DoH / DoT | 客户端到所连接 DNS 服务之间的传输 | 该 DNS 服务已执行 DNSSEC 验证,或后续所有 DNS 链路都加密 |
| HTTPS | 客户端与网站之间的 HTTP 通信 | 域名解析本身已通过 DNSSEC 验证 |
DoH 和 DoT 把 DNS 放进受保护的传输通道;DNSSEC 认证的是数据,两者可以组合使用。DoH / DoT 服务仍能看到发给它的查询,因此也不等于对解析服务本身隐藏查询。RFC 8484 §9、RFC 7858 §1、RFC 8446 §1
普通应用常把验证委托给 recursive resolver。如果客户端依据上游返回的认证标记做判断,就必须信任该服务及到它的通信通道;攻击者能够改写这段响应时,仅有一个标记不足以建立信任。另一条路径是在本地执行 DNSSEC 验证,但需要本地验证软件和有效的 trust anchor。RFC 4035 §4.9.3
用 dig 观察签名与验证结果
以下命令用于 macOS / Linux shell,需要已安装 dig,并能访问公共 DNS 服务的 53 端口。参数根据 ISC BIND 9 官方手册核对;2026-09-09 实测使用 macOS 的 DiG 9.10.6。这个版本号只是复现记录,不是安装版本推荐。示例只查询公开域名,不修改 DNS 配置。
先分清 DO、AD 和 CD
| 英文术语 | 中文名称 | 简要解释 |
|---|---|---|
| DO | DNSSEC 可接受位 | 表示客户端可以接收 DNSSEC 相关记录 |
| AD | 已认证数据位 | 响应方声明答案等相关数据符合其认证条件 |
| CD | 禁用检查位 | 请求上游不要因 DNSSEC 验证失败而扣留数据 |
dig +dnssec requests DNSSEC records by setting the DO bit; it does not perform local DNSSEC validation. ISC dig 手册
+adflag 在请求中表明客户端关心 AD,但不会强迫一个未启用验证的服务执行验证。观察响应中的 ad,才是在读取上游报告的认证状态;没有 ad 也不能直接推出“域名没开启 DNSSEC”。RFC 6840 §5.7–5.8
1. 查询一个正常签名的域名
dig @1.1.1.1 cloudflare.com A +dnssec +adflag
本次实测的关键结果如下,省略事务 ID、计数和具体记录;它不是完整响应:
status: NOERROR
flags: qr rd ra ad
ANSWER: A 记录,以及 RRSIG A
RRSIG A 表示收到签名材料,响应中的 ad 表示上游报告认证通过。上面的普通 DNS 查询没有加密;它展示协议行为,不能证明本机到 1.1.1.1 的通道可信。
2. 分别查看 DNSKEY 与 DS
dig @1.1.1.1 cloudflare.com DNSKEY +dnssec
dig @1.1.1.1 cloudflare.com DS +dnssec
本次两个响应均包含 ad。前者返回 DNSKEY 与 RRSIG DNSKEY;后者返回 DS 与 RRSIG DS。虽然都向同一个 recursive resolver 查询,DS 的权威来源仍是父区 .com。
实测 DS 的数据字段为:
2371 13 2 32996839A6D808AFE3EB4A795A0E6A7A39A76FC52FF228B22B76F6D63826F2B9
依次是 key tag、签名算法编号、摘要算法编号与摘要。对应响应中,RRSIG DS 的签署者为 com.,RRSIG DNSKEY 的签署者为 cloudflare.com.,可以直观看到两级职责。密钥、摘要、地址和 TTL 都可能变化,复现时应检查结构与验证结果,不要求数值永远相同。
3. 对比故意失败的域名
ISC DNSSEC Guide 使用 dnssec-failed.org 演示验证故障。先正常查询,再对同一服务设置 CD:ISC DNSSEC Guide
dig @1.1.1.1 dnssec-failed.org A +dnssec
dig @1.1.1.1 dnssec-failed.org A +dnssec +cdflag
| 查询 | 2026-09-09 实测结果 |
|---|---|
| 正常查询 | SERVFAIL,没有 A 答案 |
加 +cdflag | NOERROR,返回 A 与 RRSIG,响应含 cd,没有 ad |
同一域名在允许跳过验证后返回数据,是定位验证问题的重要线索。+cdflag 没有修复签名;它只是让查询拿到原本因验证失败而没有返回的数据,不能把这份答案当成 Secure。
这些测试依赖外部域名和解析服务的当时状态。若环境阻断 53 端口、经过透明代理或公共服务不可达,应先确认网络路径;超时本身不能证明 DNSSEC 失败。
域名持有者怎样启用、停用和迁移
DNSSEC 通常涉及三种职责:DNS 托管方负责签署 zone 并提供记录;父区负责发布 DS,通常经注册商提交;访问者使用的 validating resolver 负责验证。同一服务商可以承担多个职责,但只在托管端打开开关,不代表公共 chain of trust 已经建立。
启用:先让签名可用,再建立 DS 关系
通常先由 DNS 托管方生成密钥、发布 DNSKEY 并持续提供有效签名,确认所有 authoritative server 已就绪,再通过注册商或父区支持的方式发布 DS。随后检查父区 DS、子区 DNSKEY 和实际验证结果,留出发布、复制及正负缓存更新所需的时间。RFC 6781 §4.3
如果 DNS 托管与注册商分属不同服务,常见操作是把托管方提供的 DS 信息提交给注册商;某些环境支持自动协调,不能假定每个注册商都需要手填,也不能假定开关总能自动完成 DS 发布。
停用:先处理父区 DS,再停止签名
Remove the parent DS records and wait for the relevant cached DS records to expire before disabling DNSSEC signing in the child zone. RFC 8078 §4
如果父区仍有 DS,而子区先删掉 DNSKEY 或停止提供有效签名,验证方仍会要求认证,却拿不到必要证据,域名就可能成为 Bogus。
这里的等待要依据父区发布进度和原 DS 的 TTL;不能套用固定“等几分钟”,也不能只清除自己电脑的缓存。上述顺序针对通过父区 DS 获得信任的常见部署;显式配置了该 zone trust anchor 的私有环境,还需协调这些验证方。
迁移:把密钥与缓存纳入切换计划
更换 DNS 托管商时,直接修改 NS,再立即关闭旧服务,可能让验证方拿着旧 DS 去检查新公钥。迁移需要协调新旧密钥、DNSKEY、DS、NS 和各类缓存,给仍在使用旧委派的客户端保留有效服务。
支持协作的服务可以通过密钥轮换或多提供方方案保持验证连续;无法协调时,也可能先正确撤销 DS、经过未签名阶段再在新服务启用。后一条路径会产生明确的 DNSSEC 保护空窗,不能称为全程安全的无缝迁移。RFC 6781 §4.3.5、RFC 8078 §5
遇到 SERVFAIL 时先检查什么
| 现象 | 优先检查 | 原因 |
|---|---|---|
| 刚换 DNS 托管商后失败 | 父区 DS 与新服务 DNSKEY 是否匹配 | 旧 DS 可能仍指向旧密钥 |
| 平时正常,某天突然失败 | RRSIG 有效期、自动续签任务、验证方时钟 | 到期或尚未生效的签名不能正常通过时间检查 |
| 部分网络失败,部分正常 | 是否使用不同验证策略、不同缓存或不同 authoritative server | 未验证的服务可能仍返回数据;不能据此判断验证服务“更差” |
| 设置 CD 后恢复返回数据 | DS、DNSKEY、RRSIG 及上游错误详情 | 进一步确定是哪里无法建立验证证据 |
| DNSSEC 响应容易超时 | UDP 大响应、分片、EDNS 与 TCP/53 可达性 | 签名和密钥会增大响应,网络设备可能阻断传输 |
DNSSEC 运维除了“开启”之外,还需要持续观察验证成功率、签名续期、密钥轮换与父区 DS。故障时应找出具体断点;长期关闭验证会失去原本希望获得的数据认证能力。ISC DNSSEC Guide:Troubleshooting、RFC 4035 §3
参考资料
- RFC 9364:DNS Security Extensions (DNSSEC):标准体系与 Best Current Practice 定位。
- RFC 4033、RFC 4034、RFC 4035:能力边界、资源记录、协议及验证规则。
- RFC 6840:Clarifications and Implementation Notes:核心规范的重要澄清,包括算法支持与 AD 行为。
- RFC 6781:DNSSEC Operational Practices、RFC 8078:密钥管理、父区协调及停用顺序。
- ISC BIND 9 DNSSEC Guide 与 dig 手册:观察验证结果与排查故障。