迁移域名服务器后,所有控制面板都可能显示操作成功,网站却依然无法访问。域名状态正常,新的权威 DNS 服务器返回了预期的 IP 地址,Web 服务器也没有任何变化,但会验证 DNSSEC 的递归解析器却返回 SERVFAIL。问题往往出在 DNSSEC 委派信息上:它仍然信任上一家 DNS 服务商使用的签名密钥。
在本文所调查的故障中,普通 DNS 查询失败,而跳过 DNSSEC 验证后,同样的查询可以成功。父区仍在公布旧的 DS 记录,新权威 DNS 区域最初却没有签名。为新区发布匹配的密钥并完成签名后,受测解析器恢复了经过验证的正常应答。这里的关键并不是应该关闭 DNSSEC,而是要认识到:迁移域名服务器与迁移 DNSSEC 信任链是两项独立的操作。
为什么 A 记录正确仍会返回 SERVFAIL
DNS 需要回答两个不同的问题。A 记录说明域名对应哪个 IPv4 地址;DNSSEC 则让验证型解析器判断该答案是否可信。地址信息正确,并不意味着 DNSSEC 信任链一定有效。
对于启用了签名的域名,信任链从受信任的父区出发,经由 DS(Delegation Signer,委派签名者)记录连接到子区的 DNSKEY。子区通过 RRSIG 记录为 DNS 数据提供签名。DS 记录包含用于标识获授权 DNSKEY 的摘要;它既不是 A 记录,也不是私钥的副本,更不是一般区域文件编辑器中的某个设置项。
更换权威域名服务器后,父区可能仍公布与旧签名密钥对应的 DS 记录。如果新区没有相匹配的 DNSKEY 和签名,验证型解析器就无法建立完整的信任链。它通常会将应答判定为不可信(bogus),返回 SERVFAIL,而不是提供一个未经验证的地址。
这与 HTTP 服务故障不同:请求可能根本没有到达 Web 服务器。它也不同于 TLS 证书过期:DNSSEC 验证的是 DNS 数据,而 HTTPS 保护的是之后浏览器与服务器之间的连接。
如何区分 DNSSEC 验证失败与 DNS 记录缺失
最有辨识度的测试,是对同一解析器、同一域名发起两次查询。先进行普通查询,查看响应状态,而不只是答案:
dig example.com A +noall +comments +answer
随后设置 DNSSEC 检查禁用位(CD),再次查询:
dig example.com A +cdflag +noall +comments +answer
在实际故障中,普通查询返回 SERVFAIL,设置 CD 位后则返回预期的 A 记录。这种对比强烈表明问题与 DNSSEC 验证有关,而不是 DNS 记录缺失或应用程序无响应。+cdflag 会请求支持该功能的递归解析器不要对本次请求执行常规 DNSSEC 验证。它仅用于诊断,不能修复访客浏览器的解析问题,也不能为访客关闭 DNSSEC。
不要仅凭 +short 没有输出就下结论。记录不存在和返回 SERVFAIL,在这种简略输出格式下都可能表现为空白。排查时保留 +comments,以便看到 status: SERVFAIL 或 status: NOERROR。
不过,CD 对比测试本身无法指出 DNSSEC 具体在哪个环节失败,只能说明下一步应该调查哪个方向。解析器也可能遇到暂时性的上游错误,因此必要时应重复测试,并检查父区的委派信息。
检查父区 DS 记录,而不只是 DNS 管理界面
先查询域名的 DS 记录:
dig example.com DS +noall +comments +answer
如果需要更完整地查看委派路径,可直接沿 DNS 层级追踪查询:
dig +trace example.com DS
具体应查询哪台权威父区 DNS 服务器,取决于顶级域名。关键是父区实际发布的 DS 记录集,而不只是 DNS 托管控制面板展示的摘要。转移域名注册商时可以不更换域名服务器,更换域名服务器时也可以不转移注册商;无论哪种情况,父区的 DS 都必须与当前生效的权威区域保持一致。
一条 DS 记录包含四个关键字段:密钥标签、算法、摘要类型和摘要。密钥标签方便排查,但仅凭标签相同,不能证明某个 DNSKEY 与 DS 匹配。摘要与算法信息也必须对应于权威区域实际提供的密钥。
本次案例中的决定性状态十分明确:父区仍在发布旧的 DNSSEC 信任信息,而新权威区域显示未启用签名。A 记录确实存在,绕过验证后也能够获取。修改应用程序配置,或反复编辑同一条 A 记录,都无法修复这种不匹配。
恢复失效 DNSSEC 委派的两种方法
有两种合理的恢复策略。它们都能解决信任链不匹配的问题,但实际运维后果不同。应当有意识地选择其中一种,而不是在两种方法之间随意反复切换。
方案一:删除过时的 DS,暂时以未签名方式运行
通过当前注册商或其支持的 DNSSEC 管理界面,请求从父区删除过时的 DS 记录。父区不再声明这是一个安全委派后,验证型解析器便能将未签名子区视为不受 DNSSEC 保护的区域(insecure),而不是验证失败的区域(bogus)。DNS 仍能正常工作,但该域名会暂时失去 DNSSEC 身份验证保护。
如果能够可靠地修改父区 DS 记录集,这通常是更简单的紧急处理方式。在旧 DS 从递归解析器缓存中到期之前,应保持现有签名配置稳定。控制面板显示 DS 已删除,并不足以证明操作生效;还应从外部验证父区记录,并考虑其 TTL。HTTPS 与 DNSSEC 设置相互独立。RFC 8078 也描述了这种暂时转为未签名状态的过程。
方案二:为新区签名并发布匹配的 DS
另一种方法是在新的权威 DNS 服务商处启用 DNSSEC,生成 DNSKEY 密钥材料,为区域签名,并在父区发布与之对应的 DS 记录。这样,验证型解析器便能沿着可信路径找到新的 DNSKEY,并验证 A 记录。
本次故障实际采用的就是这条恢复路径。DNS 管理界面报告已生成密钥、完成区域签名并发布新 DS。随后查询父区,发现新的 DS 与旧 DS 同时存在。验证型递归查询开始返回预期的 A 记录;之后的一次测试还返回了 NOERROR,并带有 ad 标志,表示该解析器将应答判定为已通过身份验证。
操作顺序很重要:只有当权威 DNS 服务已经提供对应的 DNSKEY 和有效签名时,发布 DS 才有意义。控制面板显示“已发布”,不能代替外部验证。缓存中的 DS、DNSKEY、RRSIG 和 NS 记录可能导致不同解析器在不同时间恢复。
为什么同时存在两条 DS 记录不一定会导致持续故障
一个容易令人意外的结果是:父区曾同时存在一条过时 DS 和一条新的有效 DS,DNSSEC 验证却已经成功。这并不矛盾。DS 记录集可以包含多条记录,密钥轮换时就经常如此。验证器不要求每条 DS 都对应一把当前可用的密钥;只要能够通过一条适用的 DS、对应的 DNSKEY 和有效签名建立一条可信的验证路径即可。RFC 6840 明确指出,验证器应接受单条有效的验证路径。
这并不意味着过时密钥应该永久保留。过时的 DS 会增加运维上的不确定性,在新的信任链得到验证后,最终仍应清理。但如果经过验证的查询已经成功,清理旧记录属于后续维护工作,不能以此为由再次冒险重置 DNSSEC。
这里有一个特别危险的控制面板陷阱:名为“紧急取消发布 DS”的操作,可能会删除全部 DS 记录,包括新发布且正在生效的那条。同样,如果父区还保留着 DS,就停止对子区签名,也可能立刻重现故障。这两种操作都不等同于只删除某一条过时的 DS。如果管理界面不支持定向删除单条记录,应通过注册商支持的方式进行精确修改,而不是一键全部重置。
如何安全地更换权威域名服务器
最安全的顺序取决于新旧 DNS 服务商能否协调密钥。对于需要暂时运行未签名区域的常规迁移,遵循以下步骤可以避免本次故障中的不匹配:
- 先准备目标区域。复制所需的 A、AAAA、CNAME、MX、TXT 以及其他相关记录。在更改委派之前,直接查询新的权威域名服务器进行测试。
- 检查父区的 DNSSEC 状态。确认是否存在 DS 记录,以及谁有权限修改。即使从未手动启用过 DNSSEC,也必须检查,因为有些 DNS 服务会自动配置签名。
- 旧的已签名区域仍正常运行时,先删除旧 DS。确认权威父区已完成修改,再等待之前缓存的 DS 数据过期。等待时间取决于实际观测到的 TTL,而不是某个通用的固定分钟数。
- 更改域名服务器委派。只要缓存中的 NS 委派信息仍可能指向旧服务,就应让原权威 DNS 服务继续可用。考虑父区 NS 的 TTL,并核查不同解析器实际使用的是哪些服务器。
- 决定是否重新启用 DNSSEC。如果新区准备继续保持未签名状态,就不要发布 DS。如果准备签名,应先确认新的 DNSKEY 和签名能够被正常提供,再发布匹配的 DS。同时还要考虑缓存中仍指向旧域名服务器的 NS 记录,协调切换,以免再次出现验证不匹配。
- 独立验证结果。检查父区 DS、权威 DNS 上的 DNSKEY、普通递归解析结果,以及验证型解析器是否返回已验证数据的标志。
如果必须保持 DNSSEC 保护不中断,更好的选择是明确协调密钥轮换,或采用多签名者(multi-signer)迁移。这要求新旧 DNS 服务商支持必要的密钥及签名协作;仅仅把旧 DS 摘要复制到新服务商处,并不等于完成密钥轮换。
迁移后的简要核查清单
完成任何涉及 DNSSEC 的变更后,既要检查 DNS 记录,也要确认解析器认可其验证结果:
dig example.com DS +noall +comments +answer
dig example.com DNSKEY +dnssec +noall +comments +answer
dig example.com A +dnssec +noall +comments +answer
dig example.com A +cdflag +noall +comments +answer
应使用会执行 DNSSEC 验证的递归解析器来检查应答是否经过身份验证。响应中出现 NOERROR 和预期的 A 记录,表示解析成功;如果还带有 ad 标志,则表示该解析器依据自身 DNSSEC 策略验证了应答。反过来,仅仅没有 ad 标志,并不能证明验证失败,因为不同解析器的功能、策略与查询标志可能不同。如果故障期间通过验证型解析器查询 DNSKEY 也失败,应直接查询当前权威 DNS 服务以继续排查。
不要在一个解析器首次返回成功后就停止检查。不同缓存可能暂时保存不同的委派信息和密钥。还应更新任何尚未关闭的运维支持工单:一旦新的有效 DS 已经发布,之前“删除所有 DS 记录”的指示就会变得危险。后续沟通应明确要求保留当前有效密钥,并在必要时仅删除过时记录。
这次故障的原因不是 Web 服务器地址错误,而是在更换 DNS 应答来源时,没有先让解析器用于判断可信性的信任信息与之保持一致。因此,每次切换域名服务器前,都应该先问一个问题:父区目前发布了哪些 DS 记录,目标区域的 DNSKEY 和签名能否满足这些记录所要求的验证关系?