摘要

  • RPZ 是可传输的触发条件和建议动作集合。AXFR、IXFR 与 TSIG 能证明从哪个发布者收到了哪个版本,却不能证明每个命中准确,也不能替每一类客户端授权后果。
  • 真正决定答案的是订阅方:区域顺序、动作覆盖、PASSTHRU 例外、客户端分组、DNSSEC 处理、TTL、启动行为和 EDE 都是本地配置。解析器运营者因此必须对改写结果负责。

设想一家跨国企业的递归 DNS 同时服务办公网、生产运维网和远程接入用户。外部 RPZ 新增一条响应地址规则;本地团队知道该地址段里还有一个必要的供应链入口,于是写了 PASSTHRU。问题在于,例外区域排在外部订阅源之后。更新传输完全正确,例外也确实存在,远程用户仍然收到合成的 NXDOMAIN。

这不是订阅源“被篡改”,而是控制面排序失败。验证成功说明策略对象的保管链没有断;它没有说明本地应该让哪一条规则获胜。一次正确传输和一次正确授权不是同一件事。

当前 BIND 9 文档把 Response Policy Zone 描述为开放、供应商中立的 DNS 防火墙规则格式:触发条件与动作编码在一个特别构造的 DNS 区域里,再借助标准区域传输分发。Unbound 与 PowerDNS Recursor 也实现了这种模式。它的优势正是策略可以像 DNS 数据一样快速流动。

文档地位必须单独说明。2018 年的 draft-vixie-dnsop-dns-rpz-00 是已经过期的个人 Internet-Draft,不是 RFC,也没有 IETF 标准程序中的正式地位。其 Datatracker 历史记载,该文档在 2020 年 7 月进入 dormant 状态。它可以解释各实现共同采用的格式,却不能被包装成现行 IETF 标准。

这份草案最重要的不是标签,而是生产者与订阅者的分工:区域传输把策略数据发布给订阅者;订阅者自己的递归服务器配置,才把这些数据提升为该服务器的控制面。外部发布者提交候选规则,本地运营者让规则获得执行力。

五类触发条件使这项权力远比“域名黑名单”复杂。RPZ 可以匹配查询客户端地址、QNAME、原本会出现在答案里的 IP、权威名称服务器的名字,以及权威服务器地址。它们发生在解析的不同阶段。QNAME 可以在结果地址出现前命中;RPZ-IP 要先看到原始答案;NSDNAME 与 NSIP 则可能把共享同一 DNS 托管设施的许多无关域名一起纳入。

六类动作也绝非同义词。NXDOMAIN 合成“名称不存在”;NODATA 表示名称存在但所求类型没有数据;DROP 什么都不发;TCP-only 让 UDP 响应截断并要求 TCP 重试;Local Data 可以返回本地 CNAME 或告警地址;PASSTHRU 让特定命中不再被后续策略改写。应用程序、缓存、用户与客服看到的故障形态因此完全不同。

顺序决定谁拥有最后一句话。BIND 配置参考说明,多条规则命中时,先选择 response-policy 中排得更早的区域,再在同一区域里比较 CLIENT-IP、QNAME、IP、NSDNAME、NSIP 以及名称或前缀的具体程度。Unbound 同样按配置顺序处理;PASSTHRU 本身算一次命中,所以前面的例外会停止后面的外部策略。

BIND 的实务建议由此具有治理含义:把内部 RPZ 放在外部订阅源之前,用本地 PASSTHRU 保护合作伙伴和关键资产。内部区域不是附注,而是保留本地决策权的第一优先层。若它排在供应商之后,组织实际上已经把优先权交了出去。

PowerDNS 又提醒我们,结果还受实现版本影响。其文档公开说明,RPZ 的评估顺序曾经改变;当前实现为了性能与隐私,不会机械照搬草案里所有理想化的优先比较。客户端地址、QNAME、名称服务器和响应地址会在不同解析阶段检查。同一组区域文件,在两种软件或两个版本上可能选出不同胜者。

订阅方甚至可以把发布者给出的动作全部替换。BIND 支持对整个策略区域强制使用 NXDOMAIN、NODATA、DROP、TCP-only、PASSTHRU 或本地 CNAME。Unbound 能保留外部触发器,却把命中统一导向自己的页面。PowerDNS 可选择 Custom、Drop、NXDOMAIN、NODATA、Truncate 或 NoAction。此时对外答案显然是订阅方的设计,而非发布者原样转述。

测试模式也不能只看名称。Unbound 的 disabled 能记录命中而不执行,并继续检查下一个策略区域;PASSTHRU 则是有效命中,会阻止后续区域。BIND 的 DISABLED 有自己的优先语义。把“禁用”误当成“例外”,或把某一产品的行为类推到另一个产品,可能让试运行悄悄落入生产后果。

DNSSEC 划出更加明确的边界。RPZ 草案把策略生成的结果称为递归服务器故意给出的非权威真值;这是技术描述,不是道德判断。BIND 默认在客户端请求 DNSSEC 且原区域存在相关签名时避免 RPZ 改写。开启 break-dnssec yes 后可以照样改写,但产品文档直接说明:改写结果无法验证。

RFC 4035规定,本应建立信任链却无法验证的数据属于 Bogus,原因可能是攻击、配置错误或数据损坏;它也提醒,递归服务器返回的内容高度依赖本地策略。DNSSEC 能认证权威 RRset,不会替本地合成的 NXDOMAIN 签名。TSIG 认证 RPZ 的传输关系,同样不会认证对客户端作出的“不存在”断言。

缓存会把一次本地决定延长。RFC 2308定义了否定缓存:NXDOMAIN 与 NODATA 都能按 TTL 保存,但复用范围不同。BIND 从策略记录取得改写 TTL,并用本地 max-policy-ttl 设置上限;PowerDNS 也暴露合成 TTL、最大 TTL 与缓存清理控制。发布者撤下条目,不代表每个递归缓存和下游缓存立即恢复。

因此至少有四只时钟:生产者何时撤回,订阅方何时收到 IXFR,解析器何时重载或清缓存,客户端何时不再复用否定答案。只记录 feed serial,会漏掉真正决定恢复时间的后三层。

诊断可以让权力来源更透明。RFC 8914把 EDE 15 定义为运营者内部安全策略导致的 Blocked,16 是外部要求导致的 Censored,17 是客户端主动请求的 Filtered,18 可描述未获授权客户端的 Prohibited。BIND 与 PowerDNS 可在 RPZ 命中时添加 EDE。内部判断、外部命令和用户选择不应被统一伪装成“安全系统自动拦截”。

EDE 仍只是诊断信息。RFC 明确要求它不能改变 DNS 协议处理;它可能未经认证、被中间设备省略,也可能泄露名单信息。可审计证据必须把 EDE 与订阅源版本、本地策略名、胜出触发器、动作、客户端组和 TTL 连起来。

新威胁的加入速度很重要,错误条目的撤回速度同样重要。过期草案明确提出,生产者应降低过时或错误策略的撤回延迟。PowerDNS 可以保存最近一次成功接收的 RPZ,并在启动时先加载再取 IXFR;BIND 可选择在区域准备好前返回 SERVFAIL,也可能在部分区域加载失败时用已加载的区域回答。每一种连续性方案都需要本地定义最大年龄、部分加载规则和回滚负责人。

Heng Lu 关于运行代码优先、最小初始规范与本地化未来决策和现实层次的论述在这里提供了清晰方法:共同格式只承担传递候选策略的最小职责;本地配置决定未来;用户真正收到的答案才是运行事实。任何一层都不能借另一层的有效性扩大自己的权威。

完整证据链应当从发布者和序列号开始,经过传输认证、本地准入、实际顺序、动作覆盖、胜出规则、TTL 与 EDE,最后用代表性客户端探测结果,并与未经过策略路径的权威解析对照。只有这样,组织才能回答“谁改变了答案”。“订阅源完好”只是链条的开端。