子域名基础03_DNS解析流程_详细版

子域名挖掘前置基础 03:DNS 解析流程(详细版)

本篇定位 :上一篇讲了 DNS 解析的简单版------只说"做了什么"。本篇是详细版,把每一步的输入、输出、参与者、缓存行为都展开,配 mermaid 流程图。读完这一篇,你应该能完整复述一个域名从输入到拿到 IP 的全过程。

阅读建议:先确保读懂了简单版(文档 02),再来读这一篇。本篇会反复提到"递归解析器"和"权威服务器"这些角色,如果还分不清,建议回去复习。


一、详细版整体流程图

下面这张图展示了一个完整的 DNS 解析流程,标注了每一步的输入、输出、参与者。
#mermaid-svg-oOfmUNiNIAcYUTNQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oOfmUNiNIAcYUTNQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oOfmUNiNIAcYUTNQ .error-icon{fill:#552222;}#mermaid-svg-oOfmUNiNIAcYUTNQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oOfmUNiNIAcYUTNQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oOfmUNiNIAcYUTNQ .marker.cross{stroke:#333333;}#mermaid-svg-oOfmUNiNIAcYUTNQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oOfmUNiNIAcYUTNQ p{margin:0;}#mermaid-svg-oOfmUNiNIAcYUTNQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-oOfmUNiNIAcYUTNQ .cluster-label text{fill:#333;}#mermaid-svg-oOfmUNiNIAcYUTNQ .cluster-label span{color:#333;}#mermaid-svg-oOfmUNiNIAcYUTNQ .cluster-label span p{background-color:transparent;}#mermaid-svg-oOfmUNiNIAcYUTNQ .label text,#mermaid-svg-oOfmUNiNIAcYUTNQ span{fill:#333;color:#333;}#mermaid-svg-oOfmUNiNIAcYUTNQ .node rect,#mermaid-svg-oOfmUNiNIAcYUTNQ .node circle,#mermaid-svg-oOfmUNiNIAcYUTNQ .node ellipse,#mermaid-svg-oOfmUNiNIAcYUTNQ .node polygon,#mermaid-svg-oOfmUNiNIAcYUTNQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oOfmUNiNIAcYUTNQ .rough-node .label text,#mermaid-svg-oOfmUNiNIAcYUTNQ .node .label text,#mermaid-svg-oOfmUNiNIAcYUTNQ .image-shape .label,#mermaid-svg-oOfmUNiNIAcYUTNQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-oOfmUNiNIAcYUTNQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oOfmUNiNIAcYUTNQ .rough-node .label,#mermaid-svg-oOfmUNiNIAcYUTNQ .node .label,#mermaid-svg-oOfmUNiNIAcYUTNQ .image-shape .label,#mermaid-svg-oOfmUNiNIAcYUTNQ .icon-shape .label{text-align:center;}#mermaid-svg-oOfmUNiNIAcYUTNQ .node.clickable{cursor:pointer;}#mermaid-svg-oOfmUNiNIAcYUTNQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oOfmUNiNIAcYUTNQ .arrowheadPath{fill:#333333;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oOfmUNiNIAcYUTNQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oOfmUNiNIAcYUTNQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oOfmUNiNIAcYUTNQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oOfmUNiNIAcYUTNQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oOfmUNiNIAcYUTNQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oOfmUNiNIAcYUTNQ .cluster text{fill:#333;}#mermaid-svg-oOfmUNiNIAcYUTNQ .cluster span{color:#333;}#mermaid-svg-oOfmUNiNIAcYUTNQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oOfmUNiNIAcYUTNQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oOfmUNiNIAcYUTNQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-oOfmUNiNIAcYUTNQ .icon-shape,#mermaid-svg-oOfmUNiNIAcYUTNQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oOfmUNiNIAcYUTNQ .icon-shape p,#mermaid-svg-oOfmUNiNIAcYUTNQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oOfmUNiNIAcYUTNQ .icon-shape .label rect,#mermaid-svg-oOfmUNiNIAcYUTNQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oOfmUNiNIAcYUTNQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oOfmUNiNIAcYUTNQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oOfmUNiNIAcYUTNQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 步骤1

输入: 域名 api.example.com

输出: 查本地缓存
未命中
未命中
步骤2

输入: api.example.com

输出: 查解析器缓存
未命中
步骤3

输入: api.example.com

输出: .com 的 TLD 服务器地址
.com 归 TLD 管
步骤4

输入: api.example.com

输出: example.com 的权威 NS 地址
example.com 归权威 NS 管
步骤5

输入: api.example.com

输出: api 的 A 记录 IP=1.2.3.4
返回 IP
步骤6

输入: IP 1.2.3.4

输出: 缓存 + 返回给浏览器
步骤7

输入: IP 1.2.3.4

输出: 发起 HTTPS 连接
用户浏览器

输入: api.example.com
浏览器 DNS 缓存
操作系统 DNS 缓存

(含 hosts 文件)
递归解析器

(如 8.8.8.8 或 ISP DNS)
递归解析器缓存
步骤3: 问根服务器
根 DNS 服务器

(a.root-servers.net 等)
步骤4: 问 TLD 服务器
.com TLD 服务器

(a.gtld-servers.net 等)
步骤5: 问权威服务器
example.com 权威 NS

(ns1.example.com)
后续 HTTP/HTTPS 请求

下面逐步展开,每一步都说清:谁在做、输入是什么、输出是什么、缓存行为是什么。


二、步骤 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.4

7.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 数据
相关推荐
剑胆凌锋12 小时前
等级保护测评工程师的困境
网络·安全·web安全·网络安全·职场和发展
Bruce_Liuxiaowei1 天前
2026年10月第1周网络安全形势周报
安全·web安全
三8442 天前
Fastjson 漏洞学习笔记 · 03 · 经典利用链:TemplatesImpl 与 JdbcRowSetImpl
java·web安全·fastjson
猎头南楼4 天前
企业网络安全体系与AI安全检测实践:零信任、纵深防御与LLM安全
人工智能·安全·web安全
Xudde.4 天前
Me and My Girlfriend 靶机渗透测试(Vulnhub Writeup)
笔记·学习·安全·web安全
Frag0ut5 天前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
小小小小钰儿5 天前
1.5-Python网络编程
开发语言·网络·python·web安全·计算机·网络安全
hasty5 天前
01_新网络安全法下的软件漏洞治理
网络·安全·web安全
持敬chijing5 天前
CTFshow-WEB-新年好?解题思路
安全·web安全·网络安全·网络攻击模型