摘要

  • RFC 5001 于 2007 年 8 月定义 DNS 的 NSID 选项。解析器在 EDNS 查询中放入空的 NSID 请求,愿意回应的服务器就在同一个答复中写入标识字节。
  • NSID 只管当前一跳。客户端问递归解析器,得到的就是递归解析器自报的标识;上游权威服务器需要另一次查询和记录。标识内容是由运营者决定的不透明字节串。
  • L-Root 在 2014 年发布的运营文档记载,它把响应节点的完整主机名放进 NSID。IANA DNS 参数登记表记录选项编号 3。

第二次查询可能问错了证人

假设一名用户发现解析结果异常,截下答复报错。值班人员对着同一 IP 再查,显示一切正常,于是准备把工单关掉。这种调查把服务地址当成了一台固定机器。anycast 恰恰允许多台机器宣布同一个地址;路由为每次查询选择接收方。负载均衡也会在一个地址背后安排不同进程。两次结果不同,可能是数据刚被修正,也可能是第二次根本没碰到出错节点。单看 IP,无法区分。

2006 年的 anycast 运营建议已把节点识别列为故障诊断需要。工程师可以随后另发一个询问机器名字的请求,但路线随时会变。后来的名字只能说明后来谁回答,不会自动归到先前那份坏答复。眼前最整齐的复现实验,可能恰好绕过了唯一出错的副本。

RFC 5001把识别请求放回原始 DNS 往返。它指出 anycast、负载均衡等部署让多个名称服务器共享 IP,而 DNS 查询并没有保留会话来绑定后续请求。若要确认某份特定答复的响应者,身份信息就应由发出这份答复的服务器随包交付。这个时间关系是设计的核心:错误数据与自报节点出现在同一份证据里。

空白请求换回一个标记

解析器在 EDNS 的 OPT 伪记录里发送空的 NSID 选项。请求不得塞入 NSID 数据。IANA 为它分配了选项代码 3。理解这一请求且愿意回应的名称服务器,在答复的 OPT 中放入标识字节。服务器必须忽略查询里违规附带的 NSID 数据,也不能向未请求 NSID 的解析器主动返回标记。解析器可以把查询、答复、字节值和时间一起归档。

规范没有要求标识写成可读的主机名。它可以是机器真实名称、维护地址、稳定的随机值、动态生成的代号、签名数据或加密数据。标准规定了询问方式与字段位置,运营者决定公开多少内部信息。一个容易读懂的主机名能让外部报障直达节点;一个稳定代号能区分副本,隐藏管理地址;不断变化的代号则会限制外界跨时间追踪,也提高内部核对工单的难度。

这一选择有代价。若服务用共同地址隐藏具体部署,却在每个 NSID 答复中公开所有节点的维护 IP,隐藏就成了摆设。若完全不提供标识,客户只能把同一个 IP 的矛盾截图交给运营者。RFC 5001 的安全讨论说明,NSID 是通道上的信号,DNSSEC 对 DNS 数据的保护不会自动保护它的真实性。有争议的标记需要通道保护或运营日志佐证。

L-Root 选择把机器名字写出来

2014 年,L-Root 的运营者在一份原始运营记录中描述其 anycast 节点识别办法。它为 NSID 返回响应节点的完整主机名。文档还展示 dig 输出:字段先以十六进制字节出现,解读后是 ytz01.l.root-servers.org 这样的节点名字。规范允许不透明字节,L-Root 在自己的服务里选择了可公开理解的含义。

文档同时列出 HOSTNAME.BIND、ID.SERVER 等单独查询。它们能够告诉调查者“现在”是哪台节点回应这次询问。若路由在坏答复与补问之间改变,那台节点可能毫无关系。带 NSID 的原始查询使错误答复与响应节点标记同包出现,调查报告能直接附上这一对,而不是把两个不同时间的问答拼成一张虚构的合影。

这份 2014 年文档证明当时 L-Root 采用的做法,不提供今天所有根服务器的普查。调查某个具体故障,还应留下原始查询、答复、NSID 字节、来源、传输方式与时刻,再由运营者的节点清单把标记对应到实体机器或进程。一个名字是索引,日志和配置才告诉人们机器当时做了什么。

递归解析器只能替自己报名

NSID 的语义止于当前一跳。浏览器背后的终端若向递归解析器请求 NSID,问到的是这台递归解析器。它可能在上游另向权威服务器发起 NSID 请求,但那是另一个 DNS 往返。递归解析器给终端的标记,不会因此变成权威服务器的身份证。RFC 5001 也禁止服务器向没有提出请求的客户端擅自添加 NSID。

要知道递归解析器上游接触了哪台权威节点,就看它的上游查询抓包或日志。单个下游答复没有沿途服务器名单。这个边界也挡住了一种轻率归责:客户端看到某个标记,就把上游故障算到该标记代表的机器头上。该标记指向响应当前查询的一跳;路由、上游来源、数据差异原因都各有独立证据。

一个地址不能替所有机器作证

2007 年的改动没有替换用户熟悉的 DNS 地址,只在答复里给具体响应者留了一个可选位置。IANA 维护选项编号,服务运营者决定标识含义,解析器决定是否询问和保存。分工很小,解决的是同一 IP 背后“究竟谁说的”这一调查缝隙。

服务器也可以沉默。NSID 增加的字节可能让较大的 DNS 答复触及截断边界,因此规范让返回标记始终可选。一份没有 NSID 的抓包,只能说明这次未返回身份;运营者仍须从别的记录找节点。共同地址仍是接入服务的门,不能充当每台机器的自白。

L-Root 当年提供可读名字,其他运营者可以只给内部可解的代号。两种选择的诊断价值都来自同一件事:标记贴在出问题的那份答复上。重试会换答案,甚至换服务器;原来的包不会替后来那台机器背锅。