XversePro 知识库 · 网络
从本机到根、顶级域再到权威服务器,一次域名查询的完整路径和缓存规则。
结论:本机只问一次,跑腿的是递归解析器。递归解析器从根服务器问起,根和顶级域只告诉它下一步该问谁,最终答案来自域名的权威服务器。
每条答案都带 TTL,在 TTL 到期前再查同一个名字,解析器直接从缓存里给结果,一个外部请求都不发。
一次解析涉及四类角色。浏览器和操作系统里的那部分叫存根解析器(stub resolver),它自己不会逐级查询,只把问题交给一台递归解析器。RFC 9499 对这两个词的定义就是这样分工的。
递归解析器一般由运营商、公司网络或公共 DNS 服务提供。它替你跑完整条链路:先问根服务器,再问顶级域服务器(比如管 .com 的那一批),最后问 example.com 自己的权威服务器。权威服务器是真正保存这个域名记录的机器。
查询默认走 UDP 53 端口,这一点在 RFC 1035 第 4.2 节写明。下图是缓存全空时的完整顺序。
根服务器并不知道 www.example.com 的地址。它只知道 .com 归谁管,于是回一个转介(referral):一组 NS 记录,意思是这个问题你去问这几台服务器。RFC 9499 把转介定义为服务器表示自己不能完整作答,同时给出下一个可以问的地方。
转介里还可以附带这些服务器的 IP 地址,叫胶水记录(glue)。没有胶水,解析器拿到的只是 ns1.example.com 这样的名字,要先解析它才能继续,而它本身又在 example.com 下面,会卡住。
根服务器常被说成 13 台。IANA 的根服务器页面说得更准确:根区里配置的是 13 个命名的服务方(a 到 m.root-servers.net),背后是分布在很多国家的数百台服务器。
| 步骤 | 问谁 | 对方知道什么 | 回什么 |
|---|---|---|---|
| ②③ | 根服务器 | 各顶级域由哪些服务器负责 | .com 的 NS 记录和胶水 |
| ④⑤ | .com 顶级域服务器 | .com 下每个域名的 NS | example.com 的 NS 记录和胶水 |
| ⑥⑦ | example.com 权威服务器 | 这个域的全部记录 | www 的 A 记录,带 TTL |
表 1 三次询问各自拿到的内容。对应图 1 的编号。
每条资源记录都有 TTL 字段,RFC 1035 第 3.2.1 节规定它是一个 32 位整数,单位是秒,表示这条记录可以缓存多久。TTL 为 0 表示只能用于本次查询,不能缓存。
解析器在 RFC 1034 第 5.3.3 节的算法里,第一步就是查本地缓存。缓存里没有答案时,它也不一定从根问起:它会先找离目标最近的、仍然有效的 NS 记录。比如 .com 的 NS 还在缓存里,就直接从 .com 问起。
查不到的结果也会缓存。域名不存在(NXDOMAIN)或者该名字下没有这种类型的记录(NODATA)时,RFC 2308 规定否定答案的缓存时间取 SOA 记录的 MINIMUM 字段和 SOA 自身 TTL 中较小的那个。
早期规定走 UDP 的 DNS 报文最多 512 字节。RFC 1035 第 4.2.1 节说,超出的部分会被截断,并在报文头里置上 TC 位(truncated,表示被截断了)。客户端看到 TC 位,就改用 TCP 重新问一遍。
后来的 RFC 6891 定义了 EDNS(0) 扩展,客户端可以在请求里声明自己能收多大的 UDP 报文,这样较大的答案不必每次都退回 TCP。
要让对方替你递归查询,请求头里要置上 RD 位。RD 是 Recursion Desired 的缩写,意思是希望对方递归。它的定义在 RFC 1035 第 4.1.1 节,对方可以拒绝递归,RFC 1034 第 5.3.1 节提到过这一点。
| 情况 | 解析器怎么做 | 依据 |
|---|---|---|
| 答案不超过 512 字节 | UDP 一问一答 | RFC 1035 §4.2.1 |
| 答案更大,双方支持 EDNS(0) | 按声明的缓冲区大小走 UDP | RFC 6891 |
| 收到 TC 位 | 改用 TCP 重新查询 | RFC 1035 §4.2.1 |
| 答案是 CNAME 别名 | 缓存 CNAME,换成目标名继续查 | RFC 1034 §5.3.3 |
表 2 几种常见分支的处理方式。