摘要

  • RFC 8767 允许递归解析器在认真尝试权威刷新却失败后,临时返回已经过期的缓存;这是一项由解析器授予的连续性例外,不是区域发布者延长了数据的新鲜度。
  • 可核验的例外必须分别保存原始 TTL、过期年龄、最大陈旧期限、对客户端重新给出的 TTL、DNSSEC 当前状态、刷新失败类型、解析器群组和恢复证据。

安全团队刚刚撤掉一个受损服务的地址。旧记录的 TTL 已经走完,权威区域里也不再包含它。可是仍有用户得到旧地址。原因不是所有权威节点都没有更新,而是这些用户使用的递归解析器此刻无法联系权威服务器,于是选择返回内存中已经过期的副本。

这只是一个用于划清边界的场景,不对应真实事故,也不代表某个产品的默认配置。它说明了 Serve Stale 的两面:旧回答可以让业务继续,也可以让发布者试图结束的状态继续。

RFC 8767 给递归解析器保留了这种选择。正常情况下,TTL 到期意味着必须重新向信息来源求证;如果权威刷新无法完成,解析器可以在一定条件下把旧记录当作尚未过期来使用。但“当作”不等于“重新变新”。

TTL 结束之后,决定权换了主体

TTL 尚未到期时,缓存复用记录依据的是区域发布者给出的常规时间范围。TTL 到期后,发布者的这一项常规授权已经结束。此后若继续使用数据,依据变成递归解析器运营者的本地连续性策略。

因此,同一份回答前后属于两种不同的权力关系。前一段时间由发布者的 TTL 支撑;后一段时间由解析器对可用性的判断支撑。若审计材料只写“缓存仍有效”,就把两种判断压成了一种,也把责任藏了起来。

这里至少有两个上限。普通缓存 TTL 上限可以截短收到的异常大 TTL;RFC 8767 建议以天到周为量级,并提到七天。最大陈旧计时器从原始 TTL 到期处开始,决定过期副本还能保留多久作为候选。规范讨论一到三天能够覆盖许多中断,但强调该值应可配置,并未把它定成全球统一规则。

因此,一条完备记录需要保存:缓存写入时间、收到的原始 TTL、计算出的到期时刻、当前过期年龄、最大陈旧截止时刻,以及此次返回给下游的 TTL。只看到“TTL 30”很容易产生错觉:那三十秒通常是陈旧回答对下游的短暂缓冲,不代表发布者三十秒前重新确认了内容。

四个时钟不能合成一个开关

RFC 8767 刻意没有规定唯一算法。示例方法列出四个计时器,因为它们回答的是四个不同问题。

客户端响应计时器决定,为了不让请求方超时,解析器最多等待多久才考虑旧回答;示例建议 1.8 秒。查询解析计时器限制一次完整迭代解析可消耗的总时间,常见讨论范围是十到三十秒。失败复查计时器防止对已经失败的上游不停重试,示例建议三十秒。最大陈旧计时器则给过期副本设下绝对寿命。

如果控制台只剩“Serve Stale 已开启”,运营者就无法看见真正的取舍。客户端等待越短,体验越平滑,但仅仅较慢的权威也可能被旧数据取代。复查间隔越长,故障期的上游压力越小,恢复却越晚被发现。最大陈旧窗口越长,越能跨过大事故,也越可能把废弃地址、旧委托或旧否定状态留在系统里。

解析器在返回旧数据前,应当最近做过一次善意而真实的刷新尝试。它不能把机制变成“先答旧的、以后再问”的日常捷径。即使客户端等待计时器先结束、旧回答已经发出,后台解析仍应继续到查询解析计时器结束。陈旧回答是恢复过程中的一次有界动作,不是恢复工作的终点。

“刷新失败”不是一个足够精确的原因

RFC 8767 规定,带 AA 的权威 NOERROR 或 NXDOMAIN 会刷新数据。后者尤其重要:如果发布者确实删除了一个名称,解析器不能因为旧的正面回答更“可用”,就拒绝接受新的权威不存在结论。解析器通常没有通用办法判断某次删除是运营意图还是发布错误。

超时、网络不可达、SERVFAIL、REFUSED、畸形报文、DNSSEC 验证失败和跛脚委托也不能混成“权威挂了”。它们指向不同的控制面和处理者。RFC 2308 还限制了服务器失败或不可达指示的缓存时间,不能超过五分钟。

所以,刷新证据至少要列出每一个被访问的权威端点、目标地址、传输方式、时间、RCODE、AA 位、DNSSEC 结果、网络错误和是否重新获取委托。原始问题的 RD、CD、DO 状态、缓存键、回答属于正面、NODATA 还是 NXDOMAIN,也必须保留。

两个解析器面对同一个查询,可以因为缓存历史、上游路径和本地策略不同而给出不同答案。聚合指标若只显示“解析成功”,就会掩盖某个用户群组正在使用新记录,另一个群组仍被旧记录支配。

新的短 TTL 不是重新授权

当解析器返回过期记录时,RFC 8767 要求应答中的 TTL 大于零,并建议三十秒。零 TTL 在一些实现中存在兼容问题;过短的 TTL 又可能让下游不断重试,放大事故流量。短小的正 TTL 是节流手段。

它不会把记录的真实年龄归零。下游转发解析器收到这份回答后,也许只看得到三十秒,却看不到上游缓存已经过期多久。要重建事实,必须知道是哪台递归解析器发出陈旧回答、它何时写入缓存、上次何时向哪些权威刷新,以及失败到什么程度。

RFC 8914 定义的扩展 DNS 错误提供了额外线索:代码 3 表示 Stale Answer,代码 19 表示 Stale NXDOMAIN Answer,代码 22 表示 No Reachable Authority。它们甚至可以和 NOERROR 同时出现,为客户端和日志补充原因。

但 EDE 不改变 RCODE 的处理规则,也不强迫中间转发者完整传递。没有受保护的事务或通道时,它本身也未经认证。看到代码 3,只能证明发送者把这次回答描述为陈旧,不能独立证明缓存年龄、计时器或刷新尝试都符合其说法。

DNSSEC 有自己的截止时间

一个 RRset 写入缓存时通过验证,不代表过期后仍然通过。RRSIG 的生效与失效时间独立于 TTL,也独立于最大陈旧窗口。数据留得越久,签名跨过有效期的概率越高。

AD 位必须反映当前验证语义,不能因为“当初验证成功”就继续设置。证据需要保留 RRSIG 时间、验证时刻、信任锚状态以及 CD/DO 条件。更重要的是,即便旧地址的签名在密码学上仍有效,它也可能指向发布者已经失去控制或不再信任的基础设施。签名真实性和端点当前安全性不是同一个结论。

否定回答的风险也不同。过期 NXDOMAIN 会让新建名称继续不可见;旧 NSEC/NSEC3 证明可能推迟新的 DS 或 TLSA 生效。RFC 8198 的积极否定缓存,是利用仍在缓存规则内的已验证否定材料合成回答;Serve Stale 增加的是下一层问题:材料按常规已经过期,刷新又失败时,是否还允许继续使用。

来源