子域名挖掘前置基础 03:DNS 解析流程(详细版)
本篇定位:上一篇讲了 DNS 解析的简单版——只说"做了什么"。本篇是详细版,把每一步的输入、输出、参与者、缓存行为都展开,配 mermaid 流程图。读完这一篇,你应该能完整复述一个域名从输入到拿到 IP 的全过程。
阅读建议:先确保读懂了简单版(文档 02),再来读这一篇。本篇会反复提到"递归解析器"和"权威服务器"这些角色,如果还分不清,建议回去复习。
一、详细版整体流程图
下面这张图展示了一个完整的 DNS 解析流程,标注了每一步的输入、输出、参与者。
下面逐步展开,每一步都说清:谁在做、输入是什么、输出是什么、缓存行为是什么。
二、步骤 1:浏览器查本地缓存
2.1 这一步在做什么
用户在浏览器输入api.example.com,浏览器不会立刻去问 DNS 服务器——先查本地缓存,看这个域名是不是刚查过。
2.2 参与者
| 层级 | 说明 | 典型缓存时长 |
|---|---|---|
| 浏览器 DNS 缓存 | Chrome、Firefox 等浏览器自己的缓存 | 几分钟到几小时 |
| 操作系统 DNS 缓存 | 系统级缓存 | 取决于 OS 配置 |
| hosts 文件 | 本地静态映射文件 | 永久(除非手动改) |
2.3 输入与输出
输入: api.example.com 输出: ├─ 命中缓存 → 直接拿到 IP,流程结束(不走后续步骤) └─ 未命中 → 转入步骤 2(把请求交给操作系统)2.4 缓存行为
- 浏览器缓存按 TTL 老化
- 操作系统缓存(如 Windows 的 DNS Client 服务)也按 TTL 老化
- hosts 文件是静态的,优先级最高——如果 hosts 里有
api.example.com,永远命中
挖掘者关注:本地缓存会让你拿到"上次查过的旧结果"。这就是为什么你用
dig或nslookup查同一个域名,可能拿到不同结果——你的查询可能被本地缓存截胡了。
三、步骤 2:操作系统转给递归解析器
3.1 这一步在做什么
本地缓存没命中,操作系统把这个查询请求转给配置的递归解析器。
3.2 参与者
| 角色 | 说明 |
|---|---|
| 操作系统 | 根据配置决定把请求转给哪个递归解析器 |
| 递归解析器 | 通常由 DHCP 下发(家庭/办公网络)或手动配置(如 8.8.8.8) |
3.3 输入与输出
输入: api.example.com(来自浏览器) 输出: ├─ 递归解析器缓存命中 → 直接返回 IP,流程结束 └─ 递归解析器缓存未命中 → 转入步骤 3(递归解析器开始跑链路)3.4 缓存行为
- 递归解析器有自己的缓存(按 TTL)
- 如果之前有人通过这个解析器查过
api.example.com,缓存里就有,直接返回 - 缓存未命中时,递归解析器开始跑后面的链路
挖掘者关注:你用
subfinder这类工具做 DNS 查询时,默认走的就是递归解析器——拿到的是缓存数据。如果你想拿实时数据,要直接向权威服务器查。
四、步骤 3:递归解析器问根服务器
4.1 这一步在做什么
递归解析器本地缓存没命中,开始跑链路。第一站是根服务器。
4.2 参与者
| 角色 | 说明 |
|---|---|
| 递归解析器 | 跑腿员,替用户跑全程 |
| 根 DNS 服务器 | 全球 13 组(A-M),用 anycast 部署实际几百台 |
4.3 输入与输出
输入: api.example.com 输出: └─ 根服务器不直接给 IP 但告诉递归解析器: ".com 归 .com TLD 服务器管" 并返回 .com TLD 服务器的 NS 列表(如 a.gtld-servers.net)4.4 根服务器怎么知道要去哪问
根服务器内置了所有 TLD 的指针——这是它的核心数据。只要你查的域名有顶级域(.com、.cn、.org),根服务器就知道该去哪个 TLD 服务器。
4.5 缓存行为
- 递归解析器会把"
.com的 TLD 在哪"也缓存下来 - 下次查任何
.com域名,不用再问根,直接问 TLD
挖掘者关注:根服务器只做迭代应答——它不帮你跑全程,只指路。全球几十亿用户的查询都打到根,如果每个都帮跑全程,根早就瘫痪了。
五、步骤 4:递归解析器问 TLD 服务器
5.1 这一步在做什么
递归解析器拿到 TLD 服务器地址后,去问 TLD:“api.example.com在哪?”
5.2 参与者
| 角色 | 说明 |
|---|---|
| 递归解析器 | 继续跑腿 |
| .com TLD 服务器 | 管.com下所有二级域 |
5.3 输入与输出
输入: api.example.com 输出: └─ TLD 服务器不直接给 IP 但告诉递归解析器: "example.com 归 ns1.example.com 等 NS 管" 并返回 example.com 的权威 NS 列表5.4 TLD 服务器怎么知道权威 NS 是谁
TLD 服务器存着它管辖的所有二级域的"注册信息"——当你注册example.com时,注册商会把你的权威 NS 写到 TLD 的注册信息里。所以 TLD 知道example.com归哪些 NS 管。
5.5 缓存行为
- 递归解析器把"
example.com的权威 NS 是谁"缓存下来 - 后续查
www.example.com、api.example.com都不用再问 TLD
挖掘者关注:通过查 TLD,你能拿到目标域名的 NS 记录——这就是"找到权威 NS"的方法。子域名挖掘里,知道权威 NS 是谁,才能做针对性查询(直接向权威查,绕过缓存)。
六、步骤 5:递归解析器问权威服务器
6.1 这一步在做什么
递归解析器拿到权威 NS 地址后,终于去问权威:“api.example.com的 A 记录是什么?”
6.2 参与者
| 角色 | 说明 |
|---|---|
| 递归解析器 | 跑腿员到终点了 |
| example.com 的权威 NS | 存着 example.com 及其子域(未委派时)的最终记录 |
6.3 输入与输出
输入: api.example.com(查 A 记录) 输出: └─ 权威服务器返回: api.example.com 的 A 记录 = 1.2.3.4 (或返回 NXDOMAIN = 这个子域不存在) (或返回 CNAME = 这是个别名,再去查 CNAME 指向的域名)6.4 权威服务器怎么知道答案
权威 NS 存着example.com的区域文件(Zone File)。这个文件里写了:
example.com自己的 A 记录- 所有未委派子域的 A、CNAME、MX 等记录
- 已委派子域的 NS 指针(指向子域自己的权威 NS)
6.5 缓存行为
- 递归解析器把这个结果缓存,TTL 是由权威服务器在记录里指定的
- TTL 决定这个结果会在缓存里活多久
挖掘者关注:这是整个流程里唯一能拿到真实、最新数据的点。TTL(Time To Live,记录存活时间)决定了数据新鲜度——TTL 很短说明目标经常变更 IP(可能是 CDN 调度),TTL 很长说明相对稳定(可能是固定服务器)。这个值应该记录下来。
七、步骤 6:递归解析器缓存并返回
7.1 这一步在做什么
递归解析器拿到权威服务器的 IP 结果后,缓存一份,然后返回给用户的浏览器。
7.2 参与者
| 角色 | 说明 |
|---|---|
| 递归解析器 | 缓存 + 转发 |
| 浏览器 | 收到 IP,准备发起 HTTP 连接 |
7.3 输入与输出
输入: api.example.com 的 A 记录 = 1.2.3.4(来自权威服务器) 输出: ├─ 递归解析器缓存: api.example.com → 1.2.3.4,TTL=300秒 └─ 返回给浏览器: IP 是 1.2.3.47.4 缓存行为
- 递归解析器按 TTL 缓存结果
- 后续(在 TTL 内)再查
api.example.com,直接返回缓存,不再跑链路
挖掘者关注:这就是为什么"被动 DNS 数据"(Passive DNS,来自递归解析器缓存的历史数据)可能不准——你拿到的可能是 TTL 还没过期的旧 IP,而目标已经把 IP 改了。
八、步骤 7:浏览器发起 HTTP 连接
8.1 这一步在做什么
浏览器拿到 IP 后,开始发起 HTTP/HTTPS 连接。这一步已经超出 DNS 解析的范围,但为了流程完整,简单提一下。
8.2 后续动作
| 动作 | 说明 |
|---|---|
| 建立 TCP 连接 | 与 IP 的 80 或 443 端口三次握手 |
| TLS 握手(HTTPS) | 协商加密、验证证书、发送 SNI |
| 发送 HTTP 请求 | 请求行、请求头、请求体 |
| 接收响应 | 状态码、响应头、响应体 |
这一步后续会在"Web 与网络层"那篇文档里展开。
九、特殊情况:CNAME 链与委派
上面讲的是最简单的情况——权威服务器直接给 A 记录。但实际查询中会遇到两种特殊情况,需要多跑几趟。
9.1 CNAME 链:别名指向另一个域名
如果api.example.com不是 A 记录,而是 CNAME 记录(指向另一个域名),递归解析器要再去查那个域名的 IP。
查询: api.example.com 权威返回: CNAME = api.lb.amazonaws.com 递归解析器要继续查 api.lb.amazonaws.com 的 IP: → 问 .com TLD: amazonaws.com 的 NS 在哪 → 问 amazonaws.com 权威: api.lb.amazonaws.com 的 IP → 拿到 IP挖掘者关注:CNAME 链是架构线索金矿——它指向
*.cloudfront.net就知道用了 CloudFront CDN,指向*.elb.amazonaws.com就知道后端是 AWS 负载均衡。每条 CNAME 都是一条架构线索。
9.2 委派:子域有自己的权威服务器
如果api.example.com被委派了(有自己的权威 NS),主域权威服务器不会直接给 A 记录,而是给 NS 指针。
查询: api.example.com 主域权威返回: api.example.com 的 NS = ns1.apiteam.net 递归解析器要继续问 ns1.apiteam.net: → 查询 ns1.apiteam.net 的 IP(再去走一遍解析) → 问 ns1.apiteam.net: api.example.com 的 A 记录 → 拿到 IP挖掘者关注:委派意味着子域有独立的权威服务器。子域名挖掘里,发现一个子域有 NS 记录,就要把它当成新的"主域"重新挖——这是 Zone Delegation 的核心概念,下一篇会展开。
十、完整流程的输入输出汇总
把每一步的输入输出收拢成一张表,方便对照。
| 步骤 | 参与者 | 输入 | 输出 |
|---|---|---|---|
| 1 | 浏览器/操作系统 | 域名 api.example.com | 缓存命中则返回 IP,未命中转交 |
| 2 | 递归解析器 | 域名 api.example.com | 缓存命中则返回 IP,未命中跑链路 |
| 3 | 根服务器 | api.example.com | .com的 TLD 服务器地址 |
| 4 | TLD 服务器 | api.example.com | example.com的权威 NS 地址 |
| 5 | 权威服务器 | api.example.com | A 记录 IP=1.2.3.4 或 NXDOMAIN 或 CNAME |
| 6 | 递归解析器 | A 记录 IP=1.2.3.4 | 缓存并返回给浏览器 |
| 7 | 浏览器 | IP=1.2.3.4 | 发起 HTTP/HTTPS 连接 |
10.1 特殊情况下的额外步骤
| 场景 | 额外步骤 |
|---|---|
| CNAME 链 | 拿到 CNAME 后,对 CNAME 指向的域名再走一遍完整流程 |
| 委派 | 主域权威给 NS 指针后,向子域权威再查一次 |
| 多级 CNAME | A → B → C → IP,每跳都要查一次 |
十一、本篇小结
| 概念 | 一句话 |
|---|---|
| 完整解析流程 | 浏览器 → 本地缓存 → 递归解析器 → 根 → TLD → 权威 → 缓存 → 返回 |
| 每一步的输入 | 都是"要查的域名" |
| 每一步的输出 | 根/TLD 给"下一步去哪",权威给最终 IP |
| 缓存行为 | 递归解析器按 TTL 缓存,影响数据新鲜度 |
| 特殊情况 | CNAME 链要再查一遍,委派要向子域权威再查一次 |
读懂了这一篇,你就理解了 DNS 解析的完整机制。下一篇我们讲 DNS 里存的数据——记录类型、分级记录、树形结构与委派、通配符。
附:本篇关键术语速查
| 术语 | 简明解释 |
|---|---|
| 浏览器缓存 | 浏览器自己的 DNS 缓存 |
| 操作系统缓存 | 系统级 DNS 缓存 |
| hosts 文件 | 本地静态域名映射,优先级最高 |
| 递归解析器缓存 | 递归解析器按 TTL 缓存的结果 |
| NXDOMAIN | 域名不存在的应答 |
| CNAME 链 | 域名指向别名,别名再指向另一个域名 |
| 委派 | 子域有独立权威服务器,主域权威只给 NS 指针 |
| TTL | DNS 记录在缓存中的存活时间 |
| Zone File | 权威服务器存的区域文件,含该域所有记录 |
| 被动 DNS | 来自递归解析器缓存的历史 DNS 数据 |