DNS 搜索列表把用户输入的相对名字补成一个或多个完整名字,再拿去查询。截至 2026 年 10 月,以点结尾的名字不再补后缀。VPN 可以下发一组域名,但这组名字可能只决定问哪台解析器。隧道本身不补全查询名。
相对名字补的是哪一段
一个可独立引用的定义句:绝对名字表示从根开始的完整域名,印刷形式上以点结尾;相对名字只写了开头的若干标签,要由本机用本地域的知识补全(RFC 1034)。
printer.lab.example. 末尾那个点表示它已经到根,本机不应再接后缀。printer 和 printer.lab 都还可能是相对的。补全发生在用户界面和本机解析程序里,解释方式因实现而异。权威服务器看到的是已经补完、放进查询报文的那个名字。
查询名最小化 改变的是递归解析器继续向上游送出多少标签。它不把用户刚敲下的短名字变长,也不取消本机已经接上的后缀。
先试原名,还是先加后缀
点的个数会改变尝试顺序。据 glibc 的 resolv.conf(5),ndots 的默认值是 1:名字里只要出现点,就先把原名当作绝对名字查询,然后再把搜索列表里的后缀接上去。点的个数少于这个阈值时,查询会沿着搜索列表逐项尝试,直到找到匹配。该选项的取值被静默限制在 15 以内。glibc 2.26 起搜索列表的长度不再限制为六项;2.25 及更早是最多六项、合计 256 个字符。
下面用默认阈值 1 说明顺序。搜索列表假设为 lab.example 与 example。这是该手册描述的顺序,不是每一台解析器的实测。
| 用户输入 | 点的个数 | 先发生什么 |
|---|---|---|
printer | 0 | 先接搜索列表:printer.lab.example,再 printer.example |
printer.lab | 1 | 先把 printer.lab 当作绝对名字 |
printer.lab. | 已有结尾的点 | 只查这个绝对名字,不再接后缀 |
RFC 1535 讨论过旧解析器的一种风险:名字里已经有点,仍先把本机后缀接上去,查询可能落到别人注册的意外域名上。它建议,名字里出现点时,先按带根的名字试。这是 1993 年的信息性说明。BIND 4.9.2 还把隐式搜索收窄到本机直接父域,更长的搜索列表必须显式配置。
在 glibc 这份实现里,没有点的名字走完搜索列表后,还可能把原词再查一次。默认选项不包含 no-tld-query;写上这个选项后,没有点的名字就不再做那一次查询。名字不存在时,它会继续试下一项。应答码为 SERVFAIL 时也会继续。连接被拒绝则停下。这些分支属于该实现,别的解析器不必相同。本文没有在 2026 年 10 月对某一发行版抓包。
下发的后缀不一定拿来补全
一个可独立引用的定义句:DHCP 选项 119(RFC 3397)是 DHCP 服务器交给客户端的域名搜索列表,只用于用 DNS 解析主机名。 列表按 DNS 报文的压缩方式编码。超过 255 字节时可以拆成多个选项。
另一份容易混在一起的列表不负责补全。一个可独立引用的定义句:IKEv2 的 INTERNAL_DNS_DOMAIN(RFC 8598)列出私有域名。客户端必须只用隧道对端提供的内部解析器解析这些域及其子域,其他名字仍走外部解析器。 该属性用于分割隧道。回复里若没有这个属性,客户端可以把内部解析器当作全部查询的默认解析器,这是允许,不是必须。
| 下发物 | 规范 | 它改变的步骤 |
|---|---|---|
| DHCP 选项 119 | RFC 3397 | 把相对主机名补成完整查询名 |
| INTERNAL_DNS_DOMAIN | RFC 8598 | 这些域及其子域只问内部解析器 |
| 分离 DNS 的匹配域 | 客户端策略 | 按后缀选择解析器,见 分离 DNS |
据 systemd-resolved 的服务手册,搜索只发生在单标签名字上:先逐个接上搜索域,再按路由域把查询交给对应的解析器。名字里只要有一个点,就不再做这套补全。路由域决定问谁。因此同一条 VPN 在 glibc 上可能把 printer.lab 再接后缀,在 systemd-resolved 上则把 printer.lab 直接拿去匹配路由域。本文没有对照 2026 年 10 月某一发行版的打包版本。
补全、选解析器和隧道各算一步
顺序是本机先决定查询名,再决定问谁,最后才由路由决定这份查询从哪张网卡离开。
- 搜索列表可能把
printer写成printer.lab.example; - 分离 DNS 按这个完整名字选择解析器;
- 到该解析器的路由决定查询进不进隧道;
- 解析器自己还可以把继续发给权威服务器的名字截短。
只做第 2 步时,用户敲下的短名字不会变长。只做第 1 步时,变长后的名字仍可能发给公共解析器,于是那台解析器看见的是补全后的内部后缀。得到答案之后,缓存按这个完整名字和 TTL 保留,见 DNS 缓存。断开 VPN 不会把已经记住的 printer.lab.example 抹掉。
浏览器若改走自己的加密解析器,系统的搜索列表就不是这次查询的补全来源,见 DoH/DoT。加密保护的是到解析器的这一跳,不决定本机有没有先把名字补长。
一个可独立引用的结论句:隧道图标亮着,既不表示短名字已经被补上公司后缀,也不表示补全后的查询进了隧道。
本文不提供修改搜索列表、ndots 或解析器选择的步骤。
现象对照
| 现象 | 更可能先看什么 |
|---|---|
| 只输入一个词,解析日志里却是长名字 | 搜索列表做了补全 |
| 带点的名字先出现在公共解析器,随后才出现内部后缀 | 点的个数达到阈值,先按绝对名字查 |
| VPN 下发了公司后缀,短名字仍问公共解析器 | 这份后缀可能只用于选择解析器,没有放进搜索列表 |
| 名字末尾多一个点后,不再访问内部名字 | 结尾的点表示绝对名字,补全停止 |
| 断开 VPN 后,短名字仍短暂解析到内部地址 | 补全后的答案还在 TTL 内 |
核对清单
- 先看输入:有没有结尾的点,以及点的个数是否达到本机的阈值;
- 再分清两份列表:一份把名字补长,一份决定问哪台解析器;
- VPN 下发的域名可能只占其中一份:IKEv2 的内部域名属性不要求补全;
- 每一次尝试都是一次查询:否定答案之后是否继续,看本机实现;
- 缓存记住的是补全后的名字:换隧道不会单独作废这条答案。