摘要

  • draft-ietf-dnsop-structured-dns-error-27 已进入 RFC Editor Queue,拟把过滤说明以 I-JSON 放入 Extended DNS Error 的 EXTRA-TEXT;它尚未获得 RFC 编号,最终代码点也仍待分配。
  • 经过认证的 DoT、DoH 或 DoQ 连接保护的是客户端到所选解析器这一跳。它不能独自证明上游策略作者、法律或合同授权、分类准确性和正确补救。显示、信任、申诉与应用处置仍是不同权限。

格式越清楚,越要问是谁在说话

开篇是为分析而构造的运行场景,并非真实事故。结构化错误的价值很直接:用户不再只看到莫名其妙的 NXDOMAIN、空答案或证书异常,而能知道过滤发生、原因属于哪一类、应向哪里提出误判申诉。问题在于,可读性会制造一种心理捷径。字段排列得越整齐,接收者越容易把语法完整误当成事实和授权完整。

当前 IETF Datatracker 显示,题为 Structured Error Data for Filtered DNS 的第 27 版草案日期为 2026 年 7 月 30 日,页面最后更新于 8 月 19 日,IESG 状态为 RFC Ed Queue,RFC Editor 仍等待分配编辑。它拟成为 Proposed Standard,但还不是正式 RFC。正文中的 TBA1、TBD1 和未来 RFC 编号占位符也提醒运营者:不能提前假定代码点、客户端支持或部署行为已经统一。

RFC 8914 已允许解析器用 Extended DNS Error 表示 Blocked、Filtered、Censored、Forged Answer 等情况,但原有额外文本主要服务人工诊断,不适合作为稳定的自动处理输入。新草案让客户端在查询中发送一个长度为零的 SDE EDNS 选项,表示自己能够理解 EDE EXTRA-TEXT 中的 I-JSON 对象。

对象可以包含五类信息:c 是误判申诉的联系 URI;j 是自然语言理由;s 是由 IANA 登记的子错误整数;o 是所称机构名称;l 是语言。共同格式解决了“怎样携带”的问题,却没有在字段里附带一份组织授权书。联系入口可以真实也可以恶意,机构名可以准确也可以冒充,子错误可以符合登记语义却被用于错误对象。

请求结构化说明不等于同意过滤

客户端发送 SDE 选项,只是在表达对结构格式的支持。该选项本身不携带策略内容,也不代表用户同意过滤、接受某个分类机构,或授权软件自动联系、绕过、阻断。草案甚至明确允许本地策略决定不发送这一选项。

服务端实施过滤时,仍可返回空答案、NXDOMAIN,或者较不理想的伪造地址。若查询携带 SDE,且返回的是过滤相关 EDE,服务端通常应附带结构化细节。草案进一步区分 Network Operator Policy 和 DNS Operator Policy,并提出一个尚未分配数值的 Blocked by Upstream DNS Server,用于本地转发器说明过滤来自上游解析器。

这组区分非常有用,因为它至少避免把所有封锁都归给最后一跳解析器。但协议分类不是权力来源。Network Operator Policy 没有说明谁批准策略、它是否适用于当前设备、是否来自雇佣合同、家长配置、司法命令或安全供应商,也没有证明规则仍在有效期内。DNS Operator Policy 同样只是“由解析器运营方决定”的线上语义,不会自动使这一决定对所有用户合法、准确或不可申诉。

s 字段也需要同样克制。登记整数比任意文字更适合程序处理,但 IANA 登记证明的是代码含义,而不是一次具体判断。收到“恶意软件”类子错误,不能由此推出域名当前确有恶意载荷、情报源没有过期,或者业务系统必须永久封锁。受控词汇是一种互操作证据,不是事实裁判。

加密和认证只覆盖能够覆盖的那一跳

草案要求,未加密 DNS 响应中的结构化额外文本不得驱动客户端行动,因为路径攻击者可以修改它。即使连接已加密,若解析器身份没有验证,客户端也必须忽略 c、j、o 这些能影响用户行为的自由字段;只可酌情处理登记式的 s 值。

严格认证的 DoT、DoH 或 DoQ 更可靠。它能证明客户端连接到预期解析器,查询和响应没有在该连接中被旁路篡改。这个结论不可被贬低,也不可被扩张。它回答“谁控制最后一跳端点”和“字节是否在这一跳保持完整”,没有回答“上游最初是谁作出分类”“中间转发器是否逐字保留说明”“机构字段对应哪一个可问责主体”。

EDE 是逐跳信息。最后一台解析器可以自己生成说明,也可以转发、删减或重新组织上游信息。草案把是否传递 JSON、怎样传递,留给实现和运营策略。于是完全可能出现这样的证据链:客户端到本地解析器的 TLS 认证完美,上游到本地解析器却没有同等级保护;或者上游只给出一个代码,本地解析器自行写入理由和联系字段。

这不是 TLS 失败,而是来源链边界。需要更强审计的机构,应在 DNS 包之外保留解析器配置、上游身份、转发模式、策略版本、分类数据源、生成时间和纠错记录。只有这些运行证据结合起来,才能回答谁在何时以何种权限说了什么。

旧式转发器还会放大风险。一个不理解 EDE 的代理可能照样转发攻击者注入的 EXTRA-TEXT。草案建议只处理明确配置的 DNS 服务所发 EDE,或借助 RFC 9606 的解析器信息。信任关系来自配置和验证,不来自 JSON 花括号。

联系字段既是救济入口,也是诱导入口

结构化联系信息本来是为了让用户报告误判。恶意解析器却可以把它变成二次攻击:诱导用户联系攻击者、泄露个人信息,或安装所谓“修复工具”。自然语言理由也能利用紧急感和机构语气影响判断。

因此,客户端安全策略必须掌握显示权。只有解析器在管理配置或内置信任列表中具有足够信誉时,才应考虑显示联系字段。j 的自由说明不得用于自动改变安全执行或 DNS 协议行为。o 只能以纯文本呈现,不得转成可点击内容;若它不能与可信登记机构名称匹配,也无法通过合理启发式验证,就不得向用户展示。

草案刻意没有规定机构信任列表如何建立和更新。这个留白不是疏忽。IETF 的全球格式登记无法替每一家企业、学校、家庭、ISP 和公共机构决定谁有权对特定用户实施策略。真正承担误封、隐私、业务中断和申诉成本的一方,必须维护这张映射,并说明更新、撤销和例外机制。

客户端也不得因错误文本中的 URI 自动发起连接。限制联系方案可以减少静默上报、反射和诱捕,但不能保证人工交互安全。稳健界面应优先展示已经验证的解析器身份、受控错误说明和本地预置申诉渠道,把未验证的自由文字放在次要、受限位置。

TTL 到期只是重新询问的机会

域名分类和信誉会变化。草案允许过滤答案使用较短 TTL,例如十秒,以便更快吸收更新;更新较少时也可用三十到六十秒减少负载。短 TTL 改善了重新查询机会,却不证明整个链条已经纠正。

至少有五只时钟需要分别观测:DNS 缓存到期、分类源刷新、策略批准或撤销、申诉处理,以及客户端实际看到新答案的时间。上游列表一小时才更新、本地转发器自行重写说明或申诉队列耗时数日时,十秒 TTL 不会让错误自动消失。

纠错证据应包含查询名称和类型、所选解析器、EDE 与子错误、可见的上游来源、正负缓存 TTL、分类版本、申诉收件时间、决定人和首次成功恢复时间。只看到一次不同响应,不能等同于证明所有缓存、网络和设备已经收敛。

隐私同样不能被“透明度”口号覆盖。错误字段可能暴露过滤机构、内部策略和用户试图访问的域名。草案要求,未经用户知情,客户端不得把这些内容记录或传给第三方。如果监控系统把每条结构化错误自动送往远端分析平台,加密 DNS 在路径上保护的隐私可能在遥测端被重新泄露。

说明是一份证据,不是最终命令

验证解析器并安全解析字段后,应用仍有多种选择:显示有限说明、仅本地记录、指向独立配置的支持台、TTL 后重试、在许可范围内更换解析器、暂停当前动作,或保存证据等待人工复核。受管企业、家庭网络、公共 Wi-Fi 和安全关键设备承受的误报与漏报成本并不相同。

共同层应保持狭窄:规定请求能力、字段语义、登记值、解析顺序、传输要求和安全禁区。它不应把解析器陈述变成法律裁判,更不应悄悄替应用作出不可逆决定。政策作者、数据供应者、运营者、用户与监管主体可以共享证据,却不因此合并为同一权限。

真正的透明,不是让封锁拥有一张更漂亮的说明卡,而是让责任链能够被追问:谁选择了解析器,谁采用了策略,谁提供分类,谁可以纠正,谁决定最终后果。结构化 DNS 错误做得最好时,会使这些边界更容易观察;做得最差时,只会给一项未经验证的决定增加机器可读的权威感。

Sources