本文介绍的一部分排查技巧侧重于 BIND 9 DNS 服务器及其工具,但一般原则适用于所有实现中的 DNSSEC。
便于测试的正常域名与异常域名
准备已知能够通过或不能通过 DNSSEC 验证的域名,有助于测试不同工具,并确认失败不是由所有域名共有的问题引起的。不能保证以下域名永远保持这种状态,但它们可以作为起点。
-
以下域名应无法通过 DNSSEC 验证:
-
sigfail.ippacket.stream
-
以下域名应能够通过 DNSSEC 验证:
-
sigok.ippacket.stream
日志
默认情况下,BIND 9 服务器会记录某些 DNSSEC 验证失败,因此应首先检查 journal 日志。
例如,向一个启用验证的解析器查询 www.dnssec-failed.org 的 IP 地址,查询会失败:
$
dig @127.0.0.1 -t A www.dnssec-failed.org
; <<>> DiG 9.20.11-Ubuntu <<>> @127.0.0.1 -t A www.dnssec-failed.org ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 26260 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 1232 ; COOKIE: 6339d7228b8587f401000000671bc2eb2fe25bdf099ef1af (good) ;; QUESTION SECTION: ;www.dnssec-failed.org. IN A ;; Query time: 460 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP) ;; WHEN: Fri Oct 25 16:10:19 UTC 2024 ;; MSG SIZE rcvd: 78
这个失败信息非常笼统:只有 SERVFAIL,并未给出 IP 地址,IN A 为空。BIND 9 日志则提供了更详细的信息:
$
journalctl -u named.service -f
(...) named[286]: validating dnssec-failed.org/DNSKEY: no valid signature found (DS) named[286]: no valid RRSIG resolving 'dnssec-failed.org/DNSKEY/IN': 68.87.85.132#53 named[286]: validating dnssec-failed.org/DNSKEY: no valid signature found (DS) named[286]: no valid RRSIG resolving 'dnssec-failed.org/DNSKEY/IN': 68.87.68.244#53 named[286]: validating dnssec-failed.org/DNSKEY: no valid signature found (DS) named[286]: no valid RRSIG resolving 'dnssec-failed.org/DNSKEY/IN': 68.87.76.228#53 named[286]: validating dnssec-failed.org/DNSKEY: no valid signature found (DS) named[286]: no valid RRSIG resolving 'dnssec-failed.org/DNSKEY/IN': 68.87.72.244#53 named[286]: validating dnssec-failed.org/DNSKEY: no valid signature found (DS) named[286]: no valid RRSIG resolving 'dnssec-failed.org/DNSKEY/IN': 69.252.250.103#53 named[286]: broken trust chain resolving 'www.dnssec-failed.org/A/IN': 68.87.72.244#53
客户端工具:dig
dig 是用途最广泛的 DNS 排查工具之一,通常用于询问 DNS 名称服务器、查找并显示域名信息。它的功能很丰富,可以直接控制查询中的大多数 DNS 标志,并显示详细响应供检查。
进行 DNSSEC 故障排查时,以下功能尤其有用:
-
+dnssec:设置 DNSSEC OK 位,要求服务器返回 RRSIG 记录。OPT 伪节中会显示do标志。 -
+cd:设置 checking disabled(禁用检查)标志,允许解析器返回未经验证的答案。 -
响应中的
ad(authenticated data,已验证数据)标志,表示解析器已验证答案。 -
@<IP>:指定要向哪台服务器发送查询。
例如,向本机 systemd-resolved DNS 存根解析器(运行在 127.0.0.53)查询 isc.org 的 A 记录,并请求 DNSSEC 数据:
注意
如果需要,可以临时启用 DNSSEC,或将上游服务器改为 Cloudflare 的 1.1.1.1——例如当前上游无法正确处理 DNSSEC 时。测试结束后,使用 resolvectl revert eth0 恢复默认设置。
$
resolvectl dnssec eth0 true
$
resolvectl dns eth0 1.1.1.1
$
dig @127.0.0.53 -t A +dnssec +multiline isc.org
; <<>> DiG 9.20.11-Ubuntu <<>> @127.0.0.53 -t A +dnssec +multiline isc.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23376
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 65494
;; QUESTION SECTION:
;isc.org. IN A
;; ANSWER SECTION:
isc.org. 299 IN A 151.101.2.217
isc.org. 299 IN A 151.101.66.217
isc.org. 299 IN A 151.101.130.217
isc.org. 299 IN A 151.101.194.217
isc.org. 299 IN RRSIG A 13 2 300 (
20260130043603 20260116034316 27566 isc.org.
kp+MQSlXw7xOqU072l4g3/Fq815ucOv5rN77kxizdxnL
EMwYbgtcvI+AgDIwhm9qgLhc2GO6pUUF+puJCokxNA== )
;; Query time: 26 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Thu Jan 22 13:56:58 UTC 2026
;; MSG SIZE rcvd: 203
查看响应中的几个关键部分:
-
ad标志表明答案已通过验证。 -
状态为
NOERROR,答案部分包含 5 条记录。 -
RRSIG 记录随 A 资源记录一起返回,符合
+dnssec参数的要求;OPT PSEUDOSECTION 中的 do 标志也确认了这一点。
再对已知无法通过 DNSSEC 验证的域名执行相同查询:
$
dig @127.0.0.53 -t A +dnssec +multiline dnssec-failed.org
; <<>> DiG 9.20.11-Ubuntu <<>> @127.0.0.53 -t A +dnssec +multiline dnssec-failed.org ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 2028 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 65494 ; EDE: 9 (DNSKEY Missing): (no SEP matching the DS found for dnssec-failed.org.) ;; QUESTION SECTION: ;dnssec-failed.org. IN A ;; Query time: 219 msec ;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP) ;; WHEN: Thu Jan 22 13:57:33 UTC 2026 ;; MSG SIZE rcvd: 103
这次的结果不同:
-
没有
ad标志。 -
状态为通用的
SERVFAIL,答案数量为 0。 -
journalctl中记录了失败原因:
$
journalctl -u systemd-resolved.service -f
(...) systemd-resolved[9203]: [🡕] DNSSEC validation failed for question dnssec-failed.org IN A: no-signature
可以使用 +cd,要求运行在 @127.0.0.53 的本地 systemd-resolved 存根解析器不执行 DNSSEC 验证。响应随之发生变化:
$
dig @127.0.0.53 -t A +dnssec +cd +multiline dnssec-failed.org
; <<>> DiG 9.20.11-Ubuntu <<>> @127.0.0.53 -t A +dnssec +cd +multiline dnssec-failed.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32064
;; flags: qr rd ra cd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 65494
; EDE: 9 (DNSKEY Missing): (no SEP matching the DS found for dnssec-failed.org.)
;; QUESTION SECTION:
;dnssec-failed.org. IN A
;; ANSWER SECTION:
dnssec-failed.org. 299 IN A 96.99.227.255
dnssec-failed.org. 299 IN RRSIG A 5 2 300 (
20260204145120 20260118144620 44973 dnssec-failed.org.
U8NkuyOJBdX6vA/f+o4DclA0x5YrCVOpMCGyCnXqaTTv
8+QhDuwRGsAhXYtAZTx4k6q7B2NbqPFsavHKbbsEY46J
SLpA1MIYydHTnUPHnu+foH4Dq/QctoXbUejMySdyZwPp
MU5hm5IkwN8LgKjoE0YL89mr4ueu01DtESG6P+I= )
;; Query time: 119 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Thu Jan 22 13:58:49 UTC 2026
;; MSG SIZE rcvd: 296
这次虽然得到了一些答案,但要注意:
-
没有
ad标志,因此答案未经验证。 -
状态为
NOERROR,答案部分包含 2 条记录。 -
cd标志表明 checking disabled:解析器按照请求跳过了验证。
以上任何一种情况中,dig 本身都不执行 DNSSEC 验证,只展示解析器返回的结果;使用 +cd 时,甚至完全没有进行验证。如果需要自行验证,应使用其他工具。
客户端工具:delv
delv 与 dig 很相似,可以执行相同的 DNS 查询,但有一个关键区别:它也可以验证 DNSSEC。因此发生验证错误时,它可以报告更详细的原因,而不只是返回通用的 SERVFAIL 错误。
应使用 +cd,将验证工作交给 delv。否则,解析器可能直接返回 SERVFAIL,使 delv 无法取得需要验证的记录。
$
delv @127.0.0.53 -t A +dnssec +multiline dnssec-failed.org
;; resolution failed: SERVFAIL
加上 +cd 后,delv 自行验证,并报告具体的失败原因:
$
delv @127.0.0.53 -t A +dnssec +cd +multiline dnssec-failed.org
;; validating dnssec-failed.org/DNSKEY: no valid signature found (DS) ;; no valid RRSIG resolving 'dnssec-failed.org/DNSKEY/IN': 127.0.0.1#53 ;; broken trust chain resolving 'dnssec-failed.org/A/IN': 127.0.0.1#53 ;; resolution failed: broken trust chain
delv 的 -i 选项会禁用它自身的验证;+cd 则禁用解析器的验证。将两者结合使用时,得到的答案未经验证:
$
delv @127.0.0.53 -i -t A +dnssec +cd +multiline dnssec-failed.org
; answer not validated dnssec-failed.org. 100 IN A 96.99.227.255
对于正常的域名,delv 会报告答案已通过验证:
$
delv @127.0.0.53 -t A +multiline +cd isc.org
; fully validated
isc.org. 299 IN A 151.101.2.217
isc.org. 299 IN A 151.101.66.217
isc.org. 299 IN A 151.101.130.217
isc.org. 299 IN A 151.101.194.217
isc.org. 299 IN RRSIG A 13 2 300 (
20250908112301 20250825104017 27566 isc.org.
9oclTno0Ub2NmUEXdyLv0zqwPBbbUVmT3RX4aP4BQQ+h
4g839JXuCKHufXSPkWh/GJe/MveP83dDvJkrMmEIzg== )
由于这里使用了 +cd,验证由 delv 完成。如果解析器能够成功验证,不使用该选项也会得到相同结果。
客户端工具:resolvectl
resolvectl 可以与本机的 systemd-resolved 存根解析器交互,也可用于 DNSSEC 故障排查。为了得到可靠的测试结果,可以重置缓存及服务器功能状态。
注意
如果需要,可临时启用 DNSSEC,或将上游服务器改为 Cloudflare 的 1.1.1.1,例如当前上游无法正确处理 DNSSEC 时。测试完成后,用 resolvectl revert eth0 恢复默认设置。
清空缓存、重置服务器功能状态,然后确认已启用 DNSSEC:
$
sudo resolvectl flush-caches
$
sudo resolvectl reset-server-features
$
sudo resolvectl dnssec eth0 yes
$
sudo resolvectl dns eth0 1.1.1.1
$
resolvectl dnssec
Global: no Link 44 (eth0): yes
查询支持 DNSSEC 的域名。通过 Data is authenticated 和 Data from 字段,确认数据已通过验证且来自网络:
$
resolvectl query --type=MX isc.org
isc.org IN MX 5 mx.pao1.isc.org -- link: eth0 isc.org IN MX 10 mx.ams1.isc.org -- link: eth0 -- Information acquired via protocol DNS in 3.0ms. -- Data is authenticated: yes; Data was acquired via local or encrypted transport: no -- Data from: network
系统时间不正确
与所有涉及密码学的机制一样,准确的时间至关重要。简而言之,数字签名和密钥都有失效时间。
例如,下面的 RRSIG 记录包含其有效时间范围:
noble.example.internal. 86400 IN RRSIG A 13 3 86400 (
20241106131533 20241023195023 48112 example.internal.
5fL4apIwCD9kt4XbzzlLxMXY3mj8Li1WZu3qzlcBpERp
lXPgLODbRrWyp7L81xEFnfhecKtEYv+6Y0Xa5iVRug== )
其中的有效期为:
-
有效期截至:20241106131533(2024-11-06 13:15:33 UTC)。
-
有效期始于:20241023195023(2024-10-23 19:50:23 UTC)。
如果系统时钟不在这个范围内,验证就会失败。例如,把时间设置在有效期之前,delv 会报告签名尚未生效:
$
date
Tue Oct 10 10:10:19 UTC 2000
$
delv @10.10.17.229 -a example.internal.key +root=example.internal +multiline noble.example.internal
;; validating example.internal/DNSKEY: verify failed due to bad signature (keyid=48112): RRSIG validity period has not begun ;; validating example.internal/DNSKEY: no valid signature found (DS) ;; no valid RRSIG resolving 'example.internal/DNSKEY/IN': 10.10.17.229#53 ;; broken trust chain resolving 'noble.example.internal/A/IN': 10.10.17.229#53 ;; resolution failed: broken trust chain
其他进行验证的解析器也会记录类似错误。
如果系统时钟不正确,BIND 9 会明显地记录根区的验证失败:
named[3593]: managed-keys-zone: DNSKEY set for zone '.' could not be verified with current keys named[3593]: validating ./DNSKEY: verify failed due to bad signature (keyid=20326): RRSIG validity period has not begun named[3593]: validating ./DNSKEY: no valid signature found (DS) named[3593]: broken trust chain resolving './NS/IN': 199.7.83.42#53 named[3593]: resolver priming query complete: broken trust chain
第三方 Web 诊断工具
以下公开工具也能辅助诊断 DNSSEC:
-
DNSViz 以图形展示信任链,并标明发生中断的位置。
-
DNSSEC Debugger 以表格展示信任链,并标明发生中断的位置。
延伸阅读
来源:Ubuntu Server 官方文档 · Canonical。
著作权归原作者及来源机构所有。











暂无评论内容