摘要

  • RFC 8767 允许递归解析器在权威刷新失败后使用符合条件的过期数据;零秒 TTL 不能进入这一回退路径,成功的权威 NoError 或 NXDomain 答复会终止旧状态。
  • 这项机制减少故障,但也把原本由权威 TTL 划出的新鲜度边界,转化为解析器控制的计时器、缓存与失败判断。
  • Stale Answer 诊断能够揭示解析器做了什么,却不能认证旧数据,更不能替代组织对受益者、成本、记录类型与退出条件的授权。

分析

先看一个无法靠“可用率”回答的问题。某服务已更换地址,旧记录按时过期,但递归解析器无法联系任何权威服务器。如果它返回 SERVFAIL,仍依赖该名称的用户会立刻失去服务。如果它返回旧地址,用户也许什么都察觉不到;但同一旧地址也可能已经回收、转让,或处在域名运营者有意取消的安全边界之外。

TTL 原本提供了一条清晰的操作线。RFC 1035 把它描述为记录可以缓存的时间,期满后应再次咨询信息来源并丢弃缓存。RFC 2181 又强调,TTL 是最长生存时间,而不是解析器必须保留数据的承诺。权威方公布 TTL,递归方通常在到期后停止复用。

RFC 8767 为异常情况重画了这条线:记录到期后若无法得到权威刷新,递归解析器可以把过期记录当作未过期数据使用。这个许可有前提。Serve-stale 不应变成“先永远发旧答案、再慢慢刷新”的常态;解析器需要最近做过善意的刷新尝试,并且在向客户端返回旧数据后继续解析,直到查询解析计时器结束。

零秒 TTL 仍然是硬边界。这样的记录只能用于当前事务,不能先缓存再成为 stale 候选。对于真正返回的过期记录,解析器必须赋予大于零的 TTL;RFC 8767 推荐 30 秒。这个短值既避开部分软件对零 TTL 的异常处理,也限制下游缓存马上反复查询。

标准把时间拆成四类,因为它们承担不同责任。客户端响应计时器决定用户等待多久后可以收到旧答案,示例值约为 1.8 秒。查询解析计时器限制递归方为获得当前答案投入的总时间。失败复查计时器限制重新敲打失联权威服务器的频率。最大 stale 计时器则决定记录过期后还能在缓存里保留多久,文档建议的操作区间是一至三天。

这些值不需要全球一致。RFC 8767 明确把 serve-stale 视为递归解析器的本地操作,允许实现和部署自行选择。结果是:两个都符合标准的解析器,面对同一个名称、同一次故障,完全可能一个返回旧答案,另一个返回失败。这不是协议错误,而是不同治理决定在数据平面上的表现。

权威答复的含义也必须分清。带 AA 位的权威 NoError 或 NXDomain 会刷新数据,旧状态应被替换。其他响应码通常没有声明该名称现在存在什么,因此应当作为刷新失败处理,保留先前缓存。SERVFAIL 并不证明旧地址依然正确;它只证明解析器没拿到有用的新答案。

RFC 9520 规定的“缓存解析失败”容易与 serve-stale 混淆。失败缓存至少保留一秒、最长五分钟,作用是让相同问题在有效期内不再产生新的上游查询。它保存的是一次无法解析的结果。Serve-stale 使用的则是已经过期的答案数据。前者控制重试风暴,后者决定客户端看到旧数据还是错误。两者若合并成一个指标,组织既看不见负载控制,也看不见新鲜度例外。

RFC 8914 提供了可观察性语言:扩展 DNS 错误代码 3 表示 Stale Answer,代码 19 表示 Stale NXDOMAIN Answer。但 EDE 只是诊断。除非 DNS 事务本身受到保护,否则这些信息没有认证;标准也要求它不得改变 DNS 协议处理。它能说明解析器选择了旧数据,却不能证明旧数据安全,更不能说明用户同意承担风险。

不同记录的代价并不相同。旧 A 或 AAAA 地址可能让未改变的服务继续可用,也可能把流量送回已撤销的端点。RFC 8767 还提醒:过期签名可能导致 DNSSEC 验证失败;过期 NSEC 或 NSEC3 状态可能延迟新发布的 TLSA 或 DS 记录。攻击者如果能阻断权威可达性,也可能借此延长旧缓存存在的窗口。

这些是标准明确描述的风险,不是对某一家解析器的事故指控。本事实包没有证明任何具名运营者的设置、采用率、故障收益或安全损失。它能证明的是决策结构:谁控制计时器,哪一种权威答复结束例外,哪些诊断能暴露选择,以及旧状态最多能持续多久。

来源