摘要

  • IQUERY 把普通 DNS 报文倒置:请求在答案区给出一条资源记录,在空的问题区留下位置,让服务器返回与该记录匹配的一个或多个所有者名字。
  • DNS 以名字和 zone 委派权威,而不是以任意 RDATA 值委派权威,因此回复最多表示“这台服务器知道的匹配项”;局部正确不能升级为全局完整。
  • 全库扫描、反向索引、特殊缓存语义、大回复与批量披露使这种不确定性变得昂贵;IN-ADDR.ARPA 下的 PTR 则把地址反查重新改造成普通的、可委派的名字查询。

一封没有问题、先有答案的报文

设想一个 DNS 请求:Question 区的计数为零,Answer 区却已经写着一条 A IN 10.1.0.52。所有者名字可以用最短的根标签占位,TTL 也没有意义。请求者不是问这个名字的地址,而是让服务器寻找所有拥有该地址记录的名字。

RFC 1035 把这种操作编码为 opcode 1。回复成功时,服务器把找到的 QNAME、QTYPE 与 QCLASS 三元组放进 Question 区,并把答案区里的记录调整为与第一个匹配项一致。一个回复可以有零个、一个或多个名字。

从报文语法看,它像把函数的箭头反过来。普通查询给名字、取资源;inverse query 给资源、取名字。DNS 的四个区段足够灵活,能够承载这种镜像结构。

但报文的对称没有带来系统的对称。名字能沿根、顶级域和后续委派找到负责它的权威服务器。一个地址、邮件交换器名称、硬件描述字符串或其他记录值,却没有一棵自动告诉解析器“谁负责此值”的树。IQUERY 在开始搜索之前,就已经要求客户端猜中搜索地点。

1983 年的规范已经承认缺口

RFC 882 在 DNS 初期便写明:domain system 按 domain name 组织,而不是按 host address 或其他资源类型组织,所以 inverse query 的完整性与唯一性都无法保证。想要保证结果,解析器必须找到一台已知拥有适当资料的服务器,或者询问相关 domain 里的全部服务器。

这不是“当年机器太慢”那么简单。它指出的是权威路由缺失。对普通名字查询,委派本身就是可查询的资料;客户端能够逐步靠近边界明确的权威。对资源值查询,没有等价的父级告诉客户端下一站,也没有一种统一的 NXDOMAIN 能够证明全网不存在这个值。

RFC 883 因而要求 inverse query 以环境为条件来处理。某个组织可以配置解析器去问一组已知服务器,在自己的资料范围内做管理或诊断。这种安排能产生有用结果,却没有把服务器变成全局目录。

这里必须分开“结果为真”与“结果完整”。服务器找到三个匹配名字时,那三个关联可能完全正确;第四个名字仍可能存在于它从未装载的 zone 中。服务器对所见资料的诚实,不会自动赋予它代表未见资料发言的权力。

真正的合同只有“服务器所知道的”

RFC 1035 对范围的表述极其克制:回复列出的是 which the name server knows,即该名字服务器所知道的匹配项。由于任何一台服务器都不知道整个 domain space,结果永远不能被假定为完整。因此规范把 IQUERY 限定为数据库管理与调试工具,并明确说它不适合作为地址到主机名的通用方法。

零结果只能说明这台服务器在可见资料中没有找到匹配。它不能说明 DNS 世界里没有匹配。一个结果不能证明唯一。许多结果也未必是全量,因为服务器可能只权威托管部分 zone、只缓存偶然经过的记录,或者只为某些 RR 类型建立反向索引。

普通 DNS 的负面答案之所以更强,是因为查询名字能定位一个权威 zone;在那个明示范围内,服务器可以对名字是否存在作出有边界的回答。IQUERY 要证明“不存在”,理论上必须排除每一个可能保存该值的 zone。查询没有告诉客户端这个全集在哪里。

所以,搜索列表的证据强度不只取决于里面的行是否真实,还取决于搜索全集如何定义、谁控制全集、遗漏的分片是否能够被发现。缺少这些条件时,一张看起来完整的表仍然只是一处视图。

反向查询在数据库旁边造出第二个数据库

DNS 服务器天然按 owner name 组织数据,因为绝大多数请求从 QNAME 开始。若要快速回答任意记录值对应哪些名字,服务器需要另一条按 RDATA 内容组织的访问路径。

RFC 883 描述了按 zone 建立 inversion table 的做法。zone 更新时,相关倒排结构也要更新。RFC 1035 给出的选择同样直接:要么遍历数据库,要么维护一个以主数据库值为 key 的独立数据库。前者把成本放到每次请求,后者把内存和同步成本变成持续负担。

“匹配值”本身也不是统一操作。资源记录有类型语义:地址是定长字节,某些 RDATA 内含 domain name,另一些包含 character-string。RFC 1035 建议在可能时进行大小写无关比较,同时承认服务器可能保存自己无法识别为文本的数据。倒排并非简单地给每个字节串建一个通用哈希表。

更不对称的是激励。远端请求者发送一个很小的值,服务器承担扫描、索引查找、组装结果和传输的成本。请求者无需证明此次搜索服务于 zone 的运维目的,也没有天然上限约束结果规模。

当这种功能默认开放时,保存权威数据的设备还被迫提供一个额外的分析服务。发布单条 DNS 记录与承诺对所有记录做任意值检索,是两种不同的服务义务。

普通缓存无法补足范围

DNS 的可扩展性很大程度来自带 TTL 的复用答案。IQUERY 的结果却无法安全地套用同一缓存逻辑。RFC 1035 明确提醒,inverse query 返回的 RR 不能用普通回答的机制缓存。

例如,多宿主主机可能有多个同类型地址记录。按其中一个地址得到名字后,如果缓存把这次命中当作该名字的完整地址集合,就会制造错误印象。由值筛出的一个关系,与以名字为 key 取得的完整 RRset 不是同一个证据对象。

缓存还会丢失搜索范围。某个服务器在某一时刻的本地匹配,被重新索引到普通问题下之后,后来使用者很容易忘记它来自哪个 corpus、是否包含 cache、是否扫描了所有 zone。复制次数增加了,权威边界却没有扩大。

这正是 IQUERY 与普通 DNS 架构最深的分离。正常查询把 lookup key、委派、权威、cache key 和 TTL 都围绕名字对齐。IQUERY 借用了报文格式,却拆开了这些对齐关系。任何优化都必须携带一句容易被系统遗忘的限定:仅限某台服务器当时知道的内容。

PTR 没有搜索世界,而是命名反向键

地址反查后来依靠的不是更大的全局扫描,而是一层明确的名字结构。RFC 1034 描述 IN-ADDR.ARPA:IPv4 地址的 octet 以相反顺序写进一个特殊 domain,PTR 记录再从这个 owner name 指向另一个 domain name。

解析器面对 10.1.0.52 时,可以构造 reverse tree 下的名字,再发起普通 DNS 查询。树的不同部分可以继续委派;解析器能够找到权威服务器;返回的 RRset 具有普通 TTL;在明确 zone 内的负面回答也有可解释范围。

这个“多绕一步”不是浪费,而是修复。PTR 不保证每个地址都有记录,不保证一个地址只有一个名字,也不认证主机、组织或使用者。它提供的进步更窄:把反向关系放在一个 DNS 已经知道如何定位权威的 owner name 下。

IQUERY 让系统从任意值发现未知索引;PTR 要求负责 reverse space 的参与者在可预测名字处发布明确记录。搜索变成读取,模糊的全球问题变成有委派边界的局部声明。

对诚实客户端无力,对滥用者却足够有用

到了 2002 年,RFC 3425 记录的实践已经支持正式淘汰:IQUERY 没有得到普遍实现,旧实现中也经常被运维者关闭。原因包括少有人使用的代码存在缺陷、数据库负担以及批量暴露 zone 名称的风险。

某些记录值可以匹配极大集合。若询问“哪些 domain 委派给某家大型 ISP 的 nameserver”,回复可能包含数万组三元组并达到 megabyte 规模。小请求触发大计算与大回复,使资源消耗和拒绝服务成为现实考虑。

inverse MX 查询则能把共享邮件设施背后的大量名字一次性聚合出来。每条记录单独公开,不等于 zone 运营者承诺提供任意维度的批量目录。IQUERY 改变了收集成本,也改变了服务器承担的风险。

这个结构对正常用户与攻击者产生了反常的不对称。正常用户需要完整性,却得不到;攻击者往往只需要让服务器花费 CPU、内存、带宽,或者披露一批本地匹配,因此并不在意结果是否覆盖全球。

永久退休比重新利用更诚实

RFC 3425 没有把 opcode 1 当作空闲号码重新分配。它把 IQUERY 标为 obsolete,完全取代 RFC 1035 的相关章节,要求名字服务器收到请求时应返回 Not Implemented,并要求永久保留这个退休状态。

这是一种兼容性纪律。旧号码若承载新含义,尚存的旧软件可能按旧语义解释新报文。永久退休保留历史可读性,也结束“服务器应该提供此服务”的预期。

标准文件还指出,没有已知客户端依赖 IQUERY 提供有意义的公共服务,而 IN-ADDR.ARPA 下的 PTR 已经长期承担常见地址反查。淘汰并非只因语法不优雅,而是因为缺少可保留的真实依赖,同时已有更符合 DNS 权威结构的办法。

DNSSEC 又让证明难题更清楚。RFC 3425 指出,若不即时数字签名,保护 IQUERY 回复极其困难。按名字预签的 zone 能认证明确 RRset 和名字结构内的否定证明;任意值搜索不仅要认证列出的匹配,还暗示搜索全集中没有遗漏,而 IQUERY 从未定义那个全球全集。

服务器是证人,不是整个名字空间

一台 DNS 服务器可以真正参与协议,可以权威托管 zone,可以保存准确记录,也可以拥有有用 cache。它因此能成为特定范围内的证人。它不会因为能够搜索自己的副本,就成为所有拥有相同记录值之名字的委托人。

Lu Heng 的笔记反复区分参与与授权,也区分管理一份数据库和支配数据库所描述对象的权力。在协议层,IQUERY 展示了同样的边界:拥有可搜索资料,授权的是对这份资料作说明;它不授权服务器代表缺席资料作全局结论。

修复办法不是建立一座更大的中央搜索塔。DNS 保留了较小的共同层:名字、委派、RR 类型、TTL 与明确发布的反向记录。不同参与者在有界 zone 内作出声明,解析器沿同一套可验证规则找到它们,无需授予某一台服务器全知地位。

证据边界

五份 RFC 能证明 IQUERY 的报文、规范限制、PTR 替代路径与正式淘汰决定。它们不能给出现今 opcode 1 流量比例,不能列出所有历史实现,也不能证明私人网络中绝无诊断程序仍发送此类报文。

NOTIMP 是规范期望,不是“服务器从未解析请求”的证据。超时可能来自丢包、防火墙或进程故障。收到回复也只证明响应端作出了局部处理,不证明它看见整个 DNS。

PTR 同样不能被抬升为身份凭证。正向与反向记录可能不一致,可以缺失,也可以由多个名字共享。本文讨论的是如何找到对一项声明负责的权威边界,而不是保证所有边界内的内容都正确。

IQUERY 的根本问题,是它提供了提问方向,却没有提供权威方向。一个 opcode bit 足以让报文倒转,却不足以让分布式委派随之倒转。DNS 在停止承诺这道诱人的问题,并让反向关系回到名字树中之后,反而更可靠。

来源