摘要
- 传统 DNS 的
SERVFAIL、REFUSED等 RCODE 有意保持紧凑,却把签名错误、权威服务器不可达、缓存故障、策略拦截等不同原因压成相同结果。RFC 8914 用 EDNS 选项 15 增加INFO-CODE与可选EXTRA-TEXT,让原因能够随响应返回。 - EDE 可以伴随
SERVFAIL、NXDOMAIN、REFUSED,也可以伴随NOERROR;一份响应还能带多个 EDE。无论诊断写得多具体,应用仍必须按原 RCODE 处理,不能让附加说明夺走结果码的权限。 - 诊断信息也有自己的传递风险:转发器可选择丢弃或重写,报文过大时 EDE 应先于答案数据被舍弃,自由文本可能泄露内部策略,而未受保护的 EDE 可以被伪造。
想象值班工程师连续收到两条告警。两次查询的首部都写着 SERVFAIL。第一条来自一个正在加载区域的服务器;过几十秒重试可能恢复。第二条来自验证解析器,它已经取得数据,却发现预期存在的 DNSSEC 信任链无法成立。若为了“恢复”而换到不验证的解析器,客户端可能拿到地址,但安全条件已经被悄悄取消。
在线路上,这两次失败使用同一个结果。对修复者而言,它们却指向不同控制面。前者属于服务状态,后者可能属于签名、父区 DS、密钥、时钟、数据缺失或传输损坏。DNS 很早就能表达“没有可交付结果”,却长期不能把“为什么”以统一方式带回。
结果码越稳定,原因就越容易被压扁
RFC 1035 定义了 DNS 响应首部与经典 RCODE。紧凑结果码使不同实现能够先达成一致:请求格式错误、服务器失败、名称不存在、不支持操作、拒绝查询,各自都有稳定含义。客户端不必知道服务器内部有多少缓存、上游或验证步骤。
这种稳定以信息损失为代价。SERVFAIL 不能说明权威服务器全部不可达,还是签名已过期;REFUSED 不能说明服务器并非权威、客户端不在许可范围,还是某项过滤政策阻止了回答。同一种表面失败可能适合立即重试、换权威服务器、联系区域运营者,或停止向更弱的解析器回退。
问题不在 RCODE 太“粗糙”。它承担的是互操作结果,而不是事故报告。若把每一种内部故障都提升为新的基本结果码,旧客户端、缓存与转发器就要理解不断增长的控制语法。真正缺少的是一条从属于结果、但可以扩展的诊断通道。
EDNS 把说明放在答案旁边
RFC 6891 通过 OPT 伪资源记录为 DNS 建立扩展空间。OPT 出现在报文里,却不是区域中的普通数据。它可以承载能力和选项,而不把诊断元数据冒充为某个名称的权威记录。
2020 年发布的 RFC 8914 把 EDNS 选项编号 15 分给 Extended DNS Error。选项负载先放一个 16 位 INFO-CODE,余下部分可以是一段 UTF-8 EXTRA-TEXT。
数字与文字承担不同职责。INFO-CODE 指向 IANA 注册表,适合稳定分类。EXTRA-TEXT 可以补充具体密钥、上游或政策背景,但只供人阅读,不是可自动解析的新协议。它可以为空,也不能假定以空字符结尾;边界必须从 EDNS 长度字段取得。
只要请求带有 OPT,EDE 就可出现在各种响应中:SERVFAIL、NXDOMAIN、REFUSED,甚至 NOERROR。发送者还可以放入多个 EDE;接收者必须容忍,但不必全部采取行动。
最关键的规则是,EDE 不改变 RCODE 的处理。带 DNSSEC Bogus 的 SERVFAIL 仍是失败;带 Stale Answer 的 NOERROR 仍提供了一个答案,但其时间来源不能被抹掉。诊断告诉读者如何理解形成过程,不替结果重新投票。
Bogus 不是“已证明遭攻击”
DNSSEC 最能说明这层区分的价值。RFC 4035 把验证状态分得比 RCODE 细。Bogus 表示解析器认为本应能建立信任链,却因签名验证失败或应有数据缺失而无法建立。原因可能是攻击,也可能是配置错误或数据损坏。
Indeterminate 则表示解析器无法判断 RRset 是否应当签名,因为必要的 DNSSEC 记录无法取得。这不是同一种失败。一个状态说明预期证明没有成立,另一个说明连适用证明的条件都无法确定。
RFC 8914 为两者分别登记诊断码,还区分不支持的 DNSKEY 算法、不支持的 DS 摘要类型、签名过期、签名尚未生效、DNSKEY 缺失、RRSIG 缺失、Zone Key 位未设置、NSEC 证据缺失等情形。
这些编号缩短排障路径,却没有分配责任。一个 DNSSEC Bogus 可能需要区域运营者更新签名,也可能需要父区、注册商、时钟服务、软件实现或网络路径介入。诊断证明的是解析器声称到达的状态,不是对某个机构的裁决。
成功响应也可以承认数据已经过期
解析器有时无法及时从权威服务器取得新数据,却仍持有刚刚超过 TTL 的缓存副本。RFC 8767 规定了在受限条件下使用陈旧数据提高韧性的做法。EDE 代码 3 表示陈旧的正答案,代码 19 表示陈旧的 NXDOMAIN。
因此 NOERROR 与 EDE 可以同时出现。RCODE 说明这份响应属于什么结果,EDE 说明它在什么条件下产生。缓存记录不会因为继续服务就重新变新;客户端也不能把连续性选择误读成权威服务器刚刚确认过数据。
代码 4 Forged Answer 进一步显示结果与原因可以分离:策略改变了答案,但仍返回某个答案时使用它。若策略导致不能回答,则 15、16、17 分别表达解析器运营者的内部拦截、外部实体施加的审查要求、客户端自己请求的过滤。18 Prohibited 可以附在因客户端无权查询而返回的拒绝上。
这些词让控制来源更可见,但并不验证背后的法律文件、黑名单质量或客户意图。谁发出代码、通过哪条链路、是否经过认证,仍必须另行保存。
缓存的不只是答案,还有失败
若每个客户端都迫使递归解析器重新执行一条已经失败的查询链,故障本身就可能放大负载。RFC 9520 把解析失败的缓存处理写得更明确,并限制其时间。
EDE 代码 13 Cached Error 可以告诉客户端:这次 SERVFAIL 来自缓存,而不是刚刚完成的一轮独立解析。它不是权威区域数据,也不证明原始故障仍然存在;它只揭示当前结果的局部来源。
这会改变合适的测试。立即对同一解析器重复请求可能只命中同一失败缓存。换一个受控的验证视角、等待缓存期限,或直接测试权威路径,才可能产生新证据。没有这层来源信息,大量重试看起来像很多次相互印证的失败,实际可能只是一份缓存状态被重复读取。
转发链会模糊“谁在解释”
终端通常只向本地递归解析器查询。本地解析器可能再把请求交给企业转发器或公共上游。客户端最后看见的 EDE 因而未必由眼前的服务器首次生成。
RFC 8914 把转发决定留给实现。转发器可以不传 EDE,可以原样表达其含义,也可以构造新的 EDE。若继续传递,它应在 EXTRA-TEXT 中说明来源,因为 EDNS 选项从线路上看像是由最后一个转发器发出。
一份响应允许多个 EDE,使不同层次不必硬挤成一个原因。例如上游发生 DNSSEC 验证问题,本地又从失败缓存作答,出口还应用了客户过滤政策。保留多个代码可以提高可见性,但客户端仍要判断各层来源,不能把一个数字当成完整因果链。
自由文本能补足归属,却很脆弱。它没有稳定机器语法,也不自动获得认证。若转发器只保留编号、不保留来源,诊断还在,证言人却丢了。
报文拥挤时,说明先让位
DNS 响应仍受请求方声明的 UDP 负载上限约束。过长的 EXTRA-TEXT 可能把报文推过边界。RFC 8914 要求服务器在这种情况下先舍弃 EDE,再舍弃其他数据,并在丢弃 EDE 时设置截断位。
这项优先级直接说明 EDE 的地位:它有用,但答案和验证证据更重要。线路上没有 EDE,不代表发送者不知道原因。它可能被大小限制、转发政策或不支持该选项的实现消除。
运维记录因此要覆盖生成、转发、重写、舍弃与截断,而不能只看客户端收到的最后报文。文本越长不等于问责越强;冗长说明反而可能迫使 TCP 回退,或在拥挤时成为第一件消失的内容。
具体的说明仍可能是伪造的
“签名过期”听起来比 SERVFAIL 更可信,“外部要求拦截”也像一份正式理由。但详细不等于真实。
RFC 8914 明确指出,除非 DNS 事务受到认证或安全传输保护,EDE 本身不受认证。能在路径中插入诊断的攻击者,往往也能改写 RCODE 或普通地址记录。因此 EDE 只能用于诊断,绝不能改变 DNS 协议处理。
文本还会泄密。它可能暴露账户编号、内部上游、策略名称,或让观察者知道某个名称在黑名单上。可审计并不意味着把所有内部状态公开。合适的说明只需帮助选择下一项测试和负责控制面,不应携带与查询者无关的私人信息。
IANA DNS 参数注册表 记录选项 15 与不断扩展的 INFO-CODE。注册表证明编号和规范引用得到协调,不证明部署比例、正确发送、忠实转发、传输保护、用户界面显示或现实中的故障频率。
EDE 的历史价值并非让 DNS 错误变得“更强”,而是让错误可以更诚实地说明自己的来源,同时把权力留在原有结果码。答案负责结果,诊断负责上下文。两者不合并,才使更快排障不必以降低验证标准为代价。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
