当客户端电脑访问google.com时,DNS发生哪些行为
客户端访问 https://google.com → 浏览器需要把 google.com 转换成 IP
为例,从浏览器缓存 → OS 缓存 → 本地 DNS → 递归 DNS → Root → .com TLD → Google 权威 DNS → 返回客户端完整走一遍。
先给你一个总览:
┌──────────────────────────────┐
│ 客户端 Client │
│ │
访问 google.com ──→ │ ① 浏览器 DNS Cache │
│ ② OS / System DNS Cache │
│ ③ hosts 文件 │
└──────────────┬───────────────┘
│ 没命中
▼
Local DNS / Stub Resolver
│
│ DNS Query
▼
┌──────────────────────────────┐
│ Recursive DNS Server │
│ 递归 DNS / DNS Resolver │
└──────────────┬───────────────┘
│
┌──────────────▼───────────────┐
│ Root DNS │
│ 根 DNS │
│ │
│ "我不知道 google.com │
│ 但 .com 的 DNS 在这里" │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ .com TLD DNS │
│ 顶级域 DNS │
│ │
│ "google.com 的权威 DNS │
│ 在这里" │
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ Google Authoritative DNS │
│ 权威 DNS │
│ │
│ google.com → IP │
└──────────────┬───────────────┘
│
▼
Recursive DNS Cache
│
▼
Client
│
▼
Google IP Address
│
▼
TCP/QUIC
│
▼
Google Server
下面把这个过程拆开。
一、首先要明确:到底是谁在问 DNS?
这是很多人第一次学 DNS 时最容易混淆的地方。
假设你在浏览器输入:
浏览器需要知道:
google.com
↓
142.250.x.x
但浏览器通常不会自己一路去问 Root、TLD、权威 DNS。
实际上通常是:
Browser
↓
OS Resolver / Stub Resolver
↓
Local DNS / Configured DNS
↓
Recursive Resolver
↓
Root / TLD / Authoritative
所以这里有一个非常重要的角色划分:
Client
负责:
“我需要知道 google.com 的 IP。”
Recursive DNS
负责:
“你不用管后面怎么查,我替你把答案找到。”
Root / TLD / Authoritative
负责:
“我只告诉你下一步应该问谁。”
二、第一阶段:浏览器自己的 DNS Cache
用户输入:
google.com
浏览器首先可能检查自己的 DNS 缓存。
例如:
Browser DNS Cache
google.com
↓
142.250.72.14
TTL remaining = 120s
如果还没有过期:
google.com
↓
Browser Cache
↓
142.250.72.14
那么整个 DNS 查询到这里就结束了。
不会访问 OS,也不会访问 Local DNS。
这就是第一层缓存。
三、如果浏览器没有缓存怎么办?
假设:
Browser Cache
google.com
↓
MISS
浏览器就会把域名解析交给操作系统。
例如 Linux:
Application
↓
glibc / resolver
↓
/etc/resolv.conf
Windows 则由 Windows DNS Client 等组件处理。
四、第二阶段:OS/System DNS Cache
操作系统本身通常也会存在 DNS 缓存。
例如:
OS DNS Cache
google.com
↓
142.250.72.14
如果命中:
Browser
↓
OS DNS Cache HIT
↓
142.250.72.14
结束。
如果:
OS Cache MISS
继续。
五、hosts 文件
这里还有一个非常重要的环节:
hosts
Linux:
/etc/hosts
Windows:
C:\Windows\System32\drivers\etc\hosts
例如:
142.250.72.14 google.com
那么系统可能直接得到:
google.com
↓
hosts
↓
142.250.72.14
根本不需要 DNS 查询。
所以严格来说:
Browser Cache
↓
OS Resolver
↓
hosts / local mechanisms
↓
DNS Server
具体先后顺序会因 OS、浏览器和 resolver 实现而不同。
六、终于到了 Local DNS
假设:
Browser Cache MISS
OS Cache MISS
hosts MISS
那么客户端需要真正发送 DNS Query。
通常客户端不会直接问 Root。
它会问一个配置好的 DNS Server。
比如:
192.168.1.1
或者:
8.8.8.8
或者:
1.1.1.1
或者公司内部 DNS:
10.10.10.53
这里要区分一个非常重要的概念:
Local DNS ≠ Root DNS
比如家庭网络:
PC
↓
192.168.1.1
↓
ISP DNS
这里的:
192.168.1.1
可能只是你的路由器。
它可能自己有 DNS Cache,也可能把请求转发给 ISP DNS。
而企业网络可能:
Client
↓
10.10.10.53
↓
Corporate DNS
所以我们可以把:
Local DNS
理解成:
客户端配置的、离客户端比较近的 DNS 服务。
它可能同时也是 Recursive Resolver,也可能只是一个 Forwarder。
七、真正的核心:Recursive DNS Server
假设客户端发:
DNS Query:
QNAME = google.com
QTYPE = A
意思是:
“请告诉我 google.com 的 IPv4 地址。”
例如:
Client
|
| UDP/53
| google.com A?
↓
Recursive DNS
注意:
客户端通常只需要问 Recursive DNS
客户端并不知道:
Root Server 是谁
.com TLD 是谁
google.com Authoritative DNS 是谁
这些工作全部由 Recursive Resolver 完成。
八、Recursive DNS 首先检查自己的 Cache
这是整个 DNS 性能非常关键的地方。
Recursive DNS 收到:
google.com A?
先查自己的缓存。
例如:
Recursive DNS Cache
google.com A
↓
142.250.72.14
TTL = 180s
如果命中:
Client
↓
Recursive DNS
↓
Cache HIT
↓
142.250.72.14
直接返回。
整个过程甚至:
Client → Recursive DNS
一次来回就结束。
九、如果 Recursive DNS 也没有缓存呢?
现在进入 DNS 真正的:
递归 + 迭代
假设 Recursive DNS:
google.com A
↓
CACHE MISS
那么 Recursive Resolver 就开始替客户端寻找答案。
注意这里非常重要:
Client → Recursive DNS 是“递归查询”。
而:
Recursive DNS → Root → TLD → Authoritative 是“迭代查询”。
这是 DNS 最重要的概念之一。
十、什么叫 Recursive Query?
客户端:
Client
|
| google.com A ?
↓
Recursive Resolver
客户端实际上是在说:
“你帮我把最终答案找出来。”
所以 Recursive Resolver 要负责完成整个查询链。
客户端不需要知道后面的事情。
十一、Recursive DNS 去问 Root
Recursive DNS 首先需要知道:
.com 在哪里?
于是它向 Root DNS 发:
google.com A?
注意:
Root 并不会告诉它:
google.com = 142.250.72.14
Root 不负责 google.com 的最终解析。
Root 只负责顶级域。
它会告诉 Recursive DNS:
我不知道 google.com
但是:
.com
的 TLD DNS 在这里。
大致可以理解成:
Recursive Resolver
|
| google.com A?
↓
Root
|
| .com NS = ...
↓
Recursive Resolver
十二、Root DNS 到底是什么?
DNS 根区域:
.
注意最后这个点。
完整域名其实是:
google.com.
↑
root
所以:
google
↓
com
↓
.
域名实际上是一个树。
.
Root Zone
|
+------------+------------+
| | |
com org net
|
google
|
www
Root 负责知道:
.com
.net
.org
.cn
.jp
...
这些 TLD 到底由哪些 DNS 服务器负责。
十三、Root 返回什么?
例如逻辑上:
google.com A?
Root:
Answer:
没有 google.com 的 A
Authority:
.com NS ...
Additional:
.com nameserver IPs
这叫:
Referral
也就是:
“我不知道答案,但我告诉你下一步去哪里问。”
所以 Root 的作用可以理解成:
Root
↓
告诉你 .com 去哪里问
十四、Recursive Resolver 接着问 .com TLD
现在 Recursive Resolver 获得:
.com TLD DNS
于是:
Recursive Resolver
|
| google.com A?
↓
.com TLD
TLD DNS 也不会直接告诉你:
142.250.x.x
因为它通常也不知道 Google 的具体 A 记录。
它只知道:
google.com 这个域是谁负责的?
于是它返回:
google.com NS
例如逻辑上:
google.com
↓
ns1.google.com
ns2.google.com
...
真实环境中的 Google DNS 委派和具体服务器可能随时变化,这里只讨论机制。
十五、于是进入 Authoritative DNS
Recursive Resolver 现在知道:
google.com 的权威 DNS 在这里
于是:
Recursive Resolver
|
| google.com A?
↓
Google Authoritative DNS
这次问题终于问到了真正负责:
google.com
这个 Zone 的 DNS Server。
十六、什么叫 Authoritative DNS?
这是另一个核心概念。
假设 Google 有一个 DNS Zone:
google.com
里面可能存在:
google.com A
www.google.com A
mail.google.com MX
google.com MX
...
权威 DNS 保存这些 DNS 数据。
所以:
Root
负责:
.com 在哪里?
TLD
负责:
google.com 在哪里?
Authoritative DNS
负责:
google.com 到底是什么?
www.google.com 到底是什么?
十七、Authoritative DNS 返回最终答案
Recursive Resolver:
Q:
google.com A?
Authoritative DNS:
A:
google.com
↓
142.250.x.x
于是:
Authoritative
↓
142.250.x.x
↓
Recursive Resolver
这才是最终答案。
十八、Recursive Resolver 为什么还要缓存?
因为刚刚辛辛苦苦查了一遍:
Root
↓
.com
↓
Authoritative
↓
google.com
如果下一个用户又问:
google.com
难道再查一遍?
当然不需要。
Recursive DNS 会缓存:
google.com A
↓
142.250.x.x
TTL = 300
所以:
User A
↓
Recursive DNS
↓
Root
↓
TLD
↓
Authoritative
第一次很慢。
但是:
User B
↓
Recursive DNS
↓
Cache HIT
非常快。
这就是 DNS Cache 的核心价值。
十九、TTL 到底在哪里发挥作用?
假设权威 DNS 返回:
google.com A
142.250.x.x
TTL = 300
意思并不是:
这个 IP 300 秒以后就失效。
而是:
递归 DNS 可以把这个 DNS 答案缓存最多 300 秒。
例如:
00:00
查询权威 DNS
TTL = 300
00:01
Cache TTL = 240
00:02
Cache TTL = 180
...
00:05
TTL = 0
Cache Expired
然后 Recursive Resolver 需要重新查询。
二十、最终返回 Client
Recursive Resolver 得到:
google.com A
142.250.x.x
然后返回给客户端:
Recursive DNS
|
| google.com A = 142.250.x.x
↓
Client
客户端再把这个结果放入自己的缓存体系。
于是:
Client DNS Cache
google.com
↓
142.250.x.x
TTL remaining = ...
浏览器也可能缓存。
二十一、整个 DNS 流程串起来
现在把全部流程连起来:
User enters google.com
|
↓
┌────────────────┐
│ Browser Cache │
└───────┬────────┘
│ MISS
↓
┌────────────────┐
│ OS DNS Cache │
└───────┬────────┘
│ MISS
↓
┌────────────────┐
│ hosts / local │
└───────┬────────┘
│ MISS
↓
┌────────────────┐
│ Local DNS │
│ / Stub / │
│ Forwarder │
└───────┬────────┘
│
↓
┌────────────────┐
│ Recursive DNS │
│ Cache? │
└───────┬────────┘
│ MISS
↓
┌────────────────┐
│ Root DNS │
│ "." │
└───────┬────────┘
│
│ Referral:
│ ".com → TLD"
↓
┌────────────────┐
│ .com TLD DNS │
└───────┬────────┘
│
│ Referral:
│ "google.com
│ → NS"
↓
┌────────────────────┐
│ Google Authoritative│
│ DNS │
└─────────┬──────────┘
│
│ A = IP
↓
Recursive DNS
│
│ Cache
↓
Client
│
↓
Google IP
│
↓
TCP / TLS / QUIC
│
↓
Google Server
二十二、这里最容易混淆的:递归 vs 迭代
我建议你把这个概念单独记下来。
Client → Recursive DNS
属于:
Recursive Query
客户端说:
“帮我找到最终答案。”
Recursive DNS → Root
属于:
Iterative Query
Recursive DNS 问:
“google.com 在哪里?”
Root 回:
“我不知道,但是 .com 在这里。”
Recursive DNS → TLD
继续:
“google.com 在哪里?”
TLD 回:
“我不知道具体 IP,但是 Google 的权威 DNS 在这里。”
Recursive DNS → Authoritative
最后:
“google.com A 是什么?”
Authoritative:
“这是最终答案。”
所以:
Recursive
Client ───────────────────→ Resolver
"给我最终答案"
Iterative
Resolver ──→ Root
"google.com?"
Root ───────→
".com 在那里"
Resolver ──→ .com TLD
"google.com?"
TLD ────────→
"Google Authoritative 在那里"
Resolver ──→ Authoritative
"google.com A?"
Authoritative
─────→
"142.250.x.x"
二十三、为什么客户端不直接问 Root?
这是一个非常好的问题。
理论上客户端当然可以:
Client
↓
Root
但实际上普通客户端通常不会这么做。
原因是:
- Root 不提供最终解析服务
Root 主要负责:
delegation
它告诉你:
.com 在哪里
而不是:
google.com = xxx
2. 效率非常差
如果每个客户端都自己:
Client
↓
Root
↓
TLD
↓
Authoritative
整个互联网会产生巨大的 DNS 查询量。
- Cache 可以大幅降低查询量
Recursive Resolver:
Millions of Clients
|
↓
Recursive Resolver
|
↓
Cache
大量用户共享一个 DNS Cache。
二十四、真正的 DNS 架构其实是这样的
你可以把互联网 DNS 想象成一个巨大的分层数据库:
Root
.
|
+------------+------------+
| | |
.com .org .cn
|
google.com
|
Authoritative
|
DNS Records
每一层只负责自己的区域。
二十五、一个非常关键的概念:Delegation
Root 不需要知道:
google.com
的所有记录。
它只需要知道:
.com
由谁管理。
所以:
Root
↓
.com NS
然后 .com 又不需要知道:
www.google.com
的 IP。
它只需要知道:
google.com
由谁管理。
于是:
Root
↓
.com
↓
google.com
↓
Authoritative DNS
这就是:
DNS Delegation
二十六、如果访问的是 www.google.com 呢?
流程稍微更有意思。
假设:
www.google.com
那么 DNS 树:
www
|
google
|
com
|
.
查询:
www.google.com A?
Recursive Resolver:
Root
↓
.com TLD
↓
google.com Authoritative
↓
www.google.com
↓
A / CNAME
这里可能出现:
www.google.com
↓
CNAME
↓
某个 canonical name
↓
A
↓
IP
所以 DNS 查询不一定一次就得到 A。
可能还需要继续解析 CNAME。
二十七、AAAA 又是什么?
如果客户端支持 IPv6,它可能同时查询:
google.com A
google.com AAAA
其中:
A
↓
IPv4
而:
AAAA
↓
IPv6
例如:
google.com
|
+── A ────→ IPv4
|
└── AAAA ─→ IPv6
实际客户端如何查询、是否并行查询,以及最终选哪个地址,会受到操作系统、浏览器和网络栈策略影响。
二十八、DNS 查询的网络层面
传统 DNS:
Client
|
| UDP 53
↓
DNS Server
一般使用:
UDP/53
但在一些情况下会使用:
TCP/53
例如 DNS 响应较大、需要可靠传输或特定协议场景。
现代加密 DNS 还包括:
DoT
DNS over TLS
TCP 853
以及:
DoH
DNS over HTTPS
TCP 443
所以你看到:
google.com
真正发生的网络行为可能是:
Application
↓
OS Resolver
↓
DoH / DoT / UDP DNS
↓
Recursive Resolver
二十九、还有一个非常容易搞错的地方:Local DNS 和 Recursive DNS
比如:
PC
↓
192.168.1.1
↓
8.8.8.8
那么:
192.168.1.1
可能是:
Local DNS Forwarder
而:
8.8.8.8
才是真正的:
Recursive Resolver
于是:
Client
↓
Local DNS / Router
↓
Recursive DNS
↓
Root
↓
TLD
↓
Authoritative
但也有可能:
Client
↓
Local DNS
↓
Root/TLD/Auth
因为 Local DNS 本身就是 Recursive Resolver。
所以:
Local DNS 是“位置/角色上的称呼”,Recursive DNS 是“功能上的称呼”。
这是理解 DNS 架构非常重要的一点。
三十、最终形成一个完整的“角色地图”
组件 做什么
Browser Cache 浏览器缓存 DNS 结果
OS Cache 操作系统缓存 DNS 结果
hosts 本机静态域名映射
Local DNS 客户端附近的 DNS 服务/转发器
Recursive Resolver 代客户端完成完整 DNS 查询
Root DNS 告诉你 TLD 在哪里
TLD DNS 告诉你某个域的 Authoritative 在哪里
Authoritative DNS 保存并回答该 Zone 的权威记录
DNS Cache 根据 TTL 缓存结果
Client 最终获得 IP 并连接目标服务器
三十一、最重要的一张图
如果你要真正把 DNS 学懂,我建议脑子里始终保持下面这张图:
DNS Hierarchy
│
▼
Root "."
│
"Who handles .com?"
│
▼
.com TLD DNS
│
"Who handles google.com?"
│
▼
Google Authoritative DNS
│
"google.com A = X"
│
▼
Recursive Resolver
│
Cache
│
▼
Local DNS
│
▼
Client
│
▼
IP Address
│
▼
TCP/QUIC + TLS
│
▼
Google
而整个过程中最核心的逻辑其实就两句话:
客户端对 Recursive DNS 发起递归请求:帮我找到 google.com。
Recursive DNS 对 DNS 层级结构进行迭代查询:Root → TLD → Authoritative,最终拿到答案并缓存,再返回客户端。
下一步继续深入,我们专题直接进入 “DNS 报文级别”:
拿一次 google.com A 查询,把 Client → Local DNS → Recursive → Root → TLD → Authoritative 每一跳的 源 IP、目的 IP、UDP 53、Transaction ID、Flags、Question、Answer、Authority、Additional、Referral、Glue、TTL 全部拆开。这样就从“理解 DNS”进入到“能抓包分析 DNS”。
我们进入 DNS 抓包级别。这一层非常关键:前面讲的是“DNS 在做什么”,现在我们开始看每一个 DNS Packet 到底长什么样、每一跳在问什么、为什么返回 Referral、Glue、TTL,以及 Recursive Resolver 是怎么一步一步走完整棵 DNS 树的。
- 先建立一个抓包视角
假设客户端:
Client IP = 192.168.1.100
本地 DNS:
Local DNS = 192.168.1.1
Recursive DNS:
Recursive Resolver = 8.8.8.8
目标:
google.com
我们假设缓存全部 MISS。
整个过程可以抽象成:
Client
192.168.1.100
|
| ① DNS Query
| google.com A?
↓
Local DNS
192.168.1.1
|
| ② Forward
↓
Recursive Resolver
8.8.8.8
|
| ③ google.com A?
↓
Root
|
| ④ Referral → .com
↓
.com TLD
|
| ⑤ Referral → google.com NS
↓
Google Authoritative DNS
|
| ⑥ Answer → IP
↓
Recursive Resolver
|
| ⑦ Answer + Cache
↓
Local DNS
|
| ⑧ Answer
↓
Client
注意:
①~② 和 ⑦~⑧ 是“客户端侧的 DNS 请求/响应”。
而:
③~⑥ 是 Recursive Resolver 自己在 DNS 层级中进行的迭代查询。
- 第一包:Client → Local DNS
客户端发:
google.com A?
通常类似:
Source IP = 192.168.1.100
Destination IP = 192.168.1.1
Source Port = 53124
Destination = 53
Protocol = UDP
DNS Payload:
Transaction ID = 0x3a7c
Flags = 0x0100
Question:
QNAME = google.com
QTYPE = A
QCLASS = IN
这里已经出现了几个非常重要的字段。
- DNS Header
DNS Header 通常是 12 bytes:
+---------------------+
| Transaction ID |
+---------------------+
| Flags |
+---------------------+
| QDCOUNT |
+---------------------+
| ANCOUNT |
+---------------------+
| NSCOUNT |
+---------------------+
| ARCOUNT |
+---------------------+
也就是:
Transaction ID
Flags
Question Count
Answer Count
Authority Count
Additional Count
4. Transaction ID 是干什么的?
假设:
Transaction ID = 0x3a7c
Client 发:
0x3a7c
google.com A?
DNS Server 返回:
0x3a7c
google.com A = ...
客户端通过 Transaction ID 知道:
这个 Response 是对应我刚才发出的哪个 Query。
类似于:
Request ID = 12345
Response ID = 12345
所以抓包的时候经常可以看到:
Query:
ID = 0x3a7c
Response:
ID = 0x3a7c
5. Flags 是 DNS 最值得学习的字段之一
例如 Query:
Flags = 0x0100
其中:
QR = 0
表示:
Query
如果:
QR = 1
表示:
Response
RD:Recursion Desired
Client 发给 Recursive DNS 时通常:
RD = 1
意思:
我希望你帮我递归解析。
也就是:
Client
|
| RD=1
↓
Recursive Resolver
"Please recurse for me."
6. Response 里面最重要的 Flags
假设 Recursive DNS 返回:
Flags:
QR = 1
AA = 0
RA = 1
分别是:
QR = 1
这是 Response。
RA = 1
表示:
Recursive service available
也就是:
“我可以帮你做递归查询。”
而:
AA = 0
表示:
这个服务器不是 google.com 这个 Zone 的权威服务器。
这个非常重要。
- AA:Authoritative Answer
假设你直接问 Google Authoritative DNS:
google.com A?
它回答:
AA = 1
表示:
这个答案来自我所负责的权威 Zone。
所以:
Recursive Resolver
AA = 0
Authoritative DNS
AA = 1
这就是抓包时判断“谁是真正权威回答者”的重要线索。
- Question Section
刚才的 Query:
Question:
QNAME:
google.com
QTYPE:
A
QCLASS:
IN
这里:
QNAME
google.com
QTYPE
A
表示:
IPv4 地址。
QCLASS
IN
Internet。
- Recursive Resolver 收到 Query
现在:
Client
↓
192.168.1.1
↓
Recursive DNS
假设 Recursive Resolver 的 cache 是:
google.com A
↓
MISS
它开始自己查。
- 第二阶段:Recursive → Root
这里非常重要。
Recursive DNS 不再把:
RD = 1
带给 Root。
它是在进行迭代查询。
逻辑上:
Recursive Resolver
|
| google.com A?
↓
Root
Query 里面通常:
RD = 0
意思:
“Root,你不用帮我递归,你告诉我下一步去哪里。”
- Root 为什么能回答?
Root 不知道:
google.com = IP
但是它知道:
.com
由谁负责。
所以 Root 返回:
Answer:
可能为空
Authority:
.com NS ...
这就是:
Referral
12. Referral 是 DNS 的核心机制
假设 Root 返回:
Authority Section:
com. NS a.gtld-servers.net.
com. NS b.gtld-servers.net.
com. NS c.gtld-servers.net.
...
意思:
.com 这个 Zone 的权威 DNS 是这些服务器。
所以:
Root
↓
".com 你去问这些服务器"
而不是:
Root
↓
"google.com = 142.250.x.x"
13. 为什么还需要 Additional Section?
这里进入一个非常关键的概念:
Glue Record
假设 Root 告诉你:
.com NS = a.gtld-servers.net
那么 Recursive Resolver 下一步要连接:
a.gtld-servers.net
但问题来了:
a.gtld-servers.net 自己的 IP 是多少?
如果必须再次解析:
a.gtld-servers.net
就可能陷入:
我要找 .com
↓
问 Root
↓
Root 告诉我 a.gtld-servers.net
↓
可是我要先解析 a.gtld-servers.net
↓
又要问 .net
...
所以 DNS 在 Referral 里面通常会提供必要的:
Additional Section
例如:
a.gtld-servers.net A x.x.x.x
a.gtld-servers.net AAAA yyyy::...
这些用于帮助 Recursive Resolver 找到下一跳 DNS Server。
这就是:
Glue
14. 所以一次 Root Response 可能长这样
逻辑结构:
DNS Response
│
├── Answer
│ └── empty
│
├── Authority
│ ├── com. NS a.gtld-servers.net
│ ├── com. NS b.gtld-servers.net
│ └── ...
│
└── Additional
├── a.gtld-servers.net A x.x.x.x
├── b.gtld-servers.net A x.x.x.x
└── ...
抓包的时候看到:
Answer: 0
Authority: N
Additional: N
并不意味着 DNS 出错。
这可能正是一个正常的 Referral。
- Recursive 接着问 .com
现在 Recursive Resolver 已经知道:
.com TLD DNS
于是:
Recursive
|
| google.com A?
↓
.com TLD
同样:
RD = 0
因为这是迭代查询。
- .com TLD 会告诉它什么?
.com TLD 不负责:
google.com A
它负责的是:
google.com
这个域的 Delegation。
所以它返回:
Authority:
google.com NS ns1...
google.com NS ns2...
...
逻辑:
.com TLD
↓
"google.com 的权威 DNS 在这里"
17. 又会出现 Glue
如果:
google.com NS = ns1.google.com
那么:
ns1.google.com
本身又属于:
google.com
这就出现了典型的“胶水”需求。
TLD 可以提供必要的:
Additional
帮助 Recursive Resolver 找到:
ns1.google.com
的 IP。
这就是为什么抓包里:
Authority
Additional
经常一起出现。
- 现在终于找到 Authoritative DNS
Recursive Resolver:
知道了:
google.com
↓
Authoritative DNS
于是:
Recursive
|
| google.com A?
↓
Authoritative DNS
19. 这一次和前面不一样
现在服务器真正拥有:
google.com
这个 Zone 的权威数据。
所以返回:
Answer:
google.com. A 142.250.x.x
并且:
AA = 1
也就是:
Authoritative Answer。
- TTL 出现了
例如:
google.com. 300 IN A 142.250.x.x
这里:
300
就是:
TTL = 300 seconds
意思:
Recursive Resolver 可以把这个答案缓存 300 秒。
- Recursive Resolver 收到答案以后干什么?
它不会马上忘掉。
它会建立:
Cache:
google.com
|
+--- A
|
+--- 142.250.x.x
|
+--- TTL = 300
于是未来:
User A
User B
User C
User D
User E
...
全部可能共享这个缓存。
- 然后 Recursive DNS 返回客户端
最终:
Authoritative
↓
Recursive
↓
Local DNS
↓
Client
Response:
Transaction ID = 0x3a7c
Flags:
QR = 1
AA = 0
RA = 1
Answer:
google.com.
300
IN
A
142.250.x.x
客户端收到。
- 客户端最终拿到什么?
最终客户端只关心:
google.com
↓
142.250.x.x
至于后面发生了:
Root
↓
TLD
↓
Authoritative
客户端甚至可能完全不知道。
这是 Recursive Resolver 帮它完成的。
- DNS 完成以后,才开始真正访问 Google
这是另一个非常重要的认知:
DNS 不是访问 Google 本身。
DNS 只是:
Name Resolution
完成:
google.com
↓
IP
然后才进入:
IP
↓
TCP / QUIC
↓
TLS
↓
HTTP
例如 HTTPS:
Browser
|
| DNS
↓
142.250.x.x
|
| TCP 443
↓
TLS
|
| HTTPS
↓
Google
HTTP/3 则可能:
DNS
↓
IP
↓
QUIC / UDP 443
↓
TLS 1.3
↓
HTTP/3
25. 现在我们把抓包过程完整串起来
假设 Wireshark 中看到的是:
① Client → Local DNS
192.168.1.100:53124
↓
192.168.1.1:53
Standard query
google.com A
RD=1
② Local DNS → Recursive
192.168.1.1
↓
8.8.8.8
google.com A
RD=1
③ Recursive → Root
8.8.8.8
↓
Root DNS
google.com A
RD=0
Root:
Answer = 0
Authority:
.com NS ...
Additional:
glue
④ Recursive → .com TLD
8.8.8.8
↓
.com TLD
google.com A
RD=0
TLD:
Answer = 0
Authority:
google.com NS ...
Additional:
glue
⑤ Recursive → Authoritative
8.8.8.8
↓
Google Authoritative DNS
google.com A
RD=0
Authoritative:
Answer:
google.com A 142.250.x.x
TTL 300
AA=1
⑥ Recursive → Local DNS
google.com
↓
142.250.x.x
⑦ Local DNS → Client
google.com
↓
142.250.x.x
⑧ Client → Google
142.250.x.x:443
DNS 阶段结束。
- 一个特别重要的细节:并不是每次都会看到 Root → TLD → Auth
现实中绝大多数 DNS 查询并不会完整走这一遍。
因为 Cache。
比如第一次:
Client
↓
Recursive
↓
Root
↓
TLD
↓
Auth
但是第二个用户:
Client
↓
Recursive
↓
CACHE HIT
直接:
google.com
↓
142.250.x.x
27. 更进一步:甚至 Referral 也会缓存
Recursive Resolver 不仅缓存:
google.com A
它还可能缓存 DNS 层级中的 Delegation 信息。
例如:
.com NS
google.com NS
因此即使:
google.com A
缓存失效了,Recursive Resolver 也可能已经知道:
google.com
↓
Authoritative NS
这样就不需要重新从 Root 开始。
所以现实世界里的 DNS Resolver 并不是每次:
Root → TLD → Auth
完整走一遍。
- 这就是为什么 DNS 解析通常很快
第一次:
Client
↓
Local DNS
↓
Recursive
↓
Root
↓
TLD
↓
Authoritative
可能几十到几百毫秒。
但之后:
Client
↓
Recursive Cache
可能只需要几毫秒甚至更低。
- 最后给你一个“抓包分析口诀”
以后你打开 Wireshark 看到 DNS,不要被一堆字段吓到。
按照这几个问题依次看:
第一问:谁在问谁?
Source IP
Destination IP
第二问:Query 还是 Response?
看:
QR
第三问:要不要递归?
看:
RD
第四问:是不是权威回答?
看:
AA
第五问:这个 Response 到底给了什么?
依次看:
Answer
Authority
Additional
第六问:如果 Answer 是空的,是不是 Referral?
看:
Authority
有没有:
NS
第七问:下一跳 DNS 的 IP 从哪里来?
看:
Additional
有没有:
A
AAAA
也就是 Glue。
第八问:答案能缓存多久?
看:
TTL
30. 你现在应该建立的完整脑图
┌──────────────┐
│ Browser │
│ DNS Cache │
└──────┬───────┘
│ MISS
▼
┌──────────────┐
│ OS Resolver │
│ Cache │
└──────┬───────┘
│ MISS
▼
┌──────────────┐
│ hosts │
└──────┬───────┘
│ MISS
▼
┌──────────────┐
│ Local DNS │
└──────┬───────┘
│
▼
┌───────────────────┐
│ Recursive Resolver │
│ │
│ Cache │
└────────┬──────────┘
│ MISS
▼
┌─────────┐
│ Root │
│ . │
└────┬────┘
│
Referral
│
▼
┌─────────┐
│ .com │
│ TLD │
└────┬────┘
│
Referral
│
▼
┌─────────────────┐
│ Authoritative │
│ google.com │
└────────┬────────┘
│
Answer
│
A / AAAA
│
▼
┌─────────────────┐
│ Recursive Cache │
└────────┬────────┘
│
▼
Client
│
▼
Google IP
│
▼
TCP/QUIC 443
│
▼
HTTPS
下一层我建议直接做一个“真实 Wireshark DNS 报文解剖”。 我们可以拿一个典型的 google.com A 查询,逐字段看 Ethernet → IP → UDP → DNS Header → Question → Answer → Authority → Additional,然后再专门讲 Referral / Glue / CNAME / TTL / DNSSEC(尤其是 RRSIG、DNSKEY、DS)。这一层搞明白以后,你基本就具备看真实 DNS 故障抓包的能力了。
我们这一节直接进入 “Wireshark 逐包解剖 DNS”。
下面我会故意把一次完整的 google.com A 查询做成一份虚拟但符合真实 DNS 报文结构的抓包,然后像看 Wireshark 一样逐层拆:
Ethernet → IP → UDP → DNS Header → Question → Answer → Authority → Additional
同时把 Referral、Glue、TTL、CNAME、EDNS、DNSSEC 串起来。
Wireshark 本身也把 dns.id、dns.flags.*、dns.qry.name、dns.resp.ttl、A/AAAA/NS/RRSIG/DNSKEY/DS 等字段作为 DNS 协议字段进行解析。
- 先看一张“真实抓包思维图”
我们假设:
Client
192.168.1.100
↓
Local DNS
192.168.1.1
↓
Recursive Resolver
8.8.8.8
↓
Root
↓
.com TLD
↓
google.com Authoritative
但在 Wireshark 中,你可能只在客户端机器上看到:
Client
|
| DNS Query
↓
192.168.1.1
|
| DNS Response
↓
Client
你通常看不到 Recursive → Root → TLD → Authoritative。
因为那些 DNS Packet 是在 Recursive Resolver 和它上游之间传输的。
这点特别重要。
- 第一层:Ethernet
假设客户端发 DNS:
Ethernet II
Destination MAC:
aa:bb:cc:dd:ee:ff
Source MAC:
11:22:33:44:55:66
Type:
IPv4
然后进入 IP 层。
所以 Wireshark 左边你会看到:
Frame
└── Ethernet II
└── Internet Protocol Version 4
└── User Datagram Protocol
└── Domain Name System
这就是典型的:
Ethernet
↓
IP
↓
UDP
↓
DNS
3. 第二层:IP
例如:
Internet Protocol Version 4
Source:
192.168.1.100
Destination:
192.168.1.1
Protocol:
UDP
TTL:
64
这里的:
TTL = 64
不是 DNS TTL。
这是 IP Header 里的 TTL。
千万不要混。
- 两种 TTL
这是 DNS 初学者最容易混淆的地方。
IP TTL
位于:
IP Header
用于防止 IP Packet 在网络中无限循环。
例如:
IP TTL = 64
DNS TTL
位于:
DNS Resource Record
例如:
google.com
300
IN
A
142.250.x.x
这里:
300
才是 DNS Cache TTL。
所以:
IP TTL ≠ DNS TTL
5. 第三层:UDP
典型 DNS:
User Datagram Protocol
Source Port:
53124
Destination Port:
53
所以:
192.168.1.100:53124
↓
192.168.1.1:53
客户端使用一个临时端口:
53124
DNS Server:
53
6. DNS Header
进入:
Domain Name System (query)
假设:
Transaction ID: 0x3a7c
Flags: 0x0100
Questions: 1
Answer RRs: 0
Authority RRs: 0
Additional RRs: 1
DNS Header 总共 12 bytes。
可以画成:
+--------------------+
| Transaction ID |
+--------------------+
| Flags |
+--------------------+
| QDCOUNT |
+--------------------+
| ANCOUNT |
+--------------------+
| NSCOUNT |
+--------------------+
| ARCOUNT |
+--------------------+
Wireshark 可以直接显示 DNS ID、Query Type、Question/Answer/Authority/Additional 数量等字段。
- Transaction ID
例如:
Transaction ID: 0x3a7c
Client:
Query ID = 0x3a7c
Server:
Response ID = 0x3a7c
这样客户端可以匹配:
Query
↓
0x3a7c
Response
↓
0x3a7c
8. Flags 开始真正有意思了
例如 Query:
Flags: 0x0100
拆开:
QR = 0
Opcode = QUERY
AA = 0
TC = 0
RD = 1
RA = 0
其中最值得关注:
QR
RD
RA
AA
TC
RCODE
9. QR
QR = 0
表示:
Query
如果:
QR = 1
就是:
Response
所以 Wireshark 里面:
Standard query
和:
Standard query response
就是这个区别。
- RD:Recursion Desired
Client → Recursive DNS:
RD = 1
意思:
我希望你帮我完成递归查询。
也就是:
Client
|
| google.com A?
| RD=1
↓
Recursive Resolver
客户端实际上是在说:
“别只告诉我下一步去哪里,我要最终答案。”
- RA:Recursion Available
Response 中:
RA = 1
意思:
这个 DNS Server 提供递归服务。
所以:
RD = 1
是:
Client 请求递归。
而:
RA = 1
是:
Server 表示自己支持递归。
两个完全不同。
- AA:Authoritative Answer
如果:
AA = 1
表示:
这个 Response 是来自负责该 Zone 的权威服务器。
例如:
google.com Authoritative
回答:
google.com A 142.250.x.x
那么:
AA = 1
而 Recursive Resolver 返回给客户端:
AA = 0
通常意味着:
我不是 google.com 的权威服务器,我只是把答案找到了。
- Question Section
继续往下:
Questions: 1
Name:
google.com
Type:
A
Class:
IN
所以:
google.com A IN
翻译成人话:
我要查询 Internet Class 下 google.com 的 IPv4 地址。
- A 到底是什么?
DNS Type:
A = 1
表示:
IPv4 address
Wireshark 的 DNS 类型定义中也明确将 A 标为 host address,同时 NS、CNAME、SOA、MX、TXT 等都是不同的 Resource Record 类型。
例如:
google.com A
↓
142.250.x.x
15. AAAA
如果:
QTYPE = AAAA
表示:
IPv6
例如:
google.com AAAA
↓
IPv6 address
所以:
A
↓
IPv4
AAAA
↓
IPv6
16. 现在看 Response
假设:
Transaction ID:
0x3a7c
Flags:
0x8180
Questions:
1
Answer:
1
Authority:
0
Additional:
1
我们拆 Flags:
QR = 1
RD = 1
RA = 1
AA = 0
翻译:
这是 Response;客户端要求递归;服务器支持递归;但这个服务器不是权威服务器。
这就是典型的:
Client ← Recursive Resolver
17. Answer Section
现在终于出现:
Answer:
google.com
TTL 300
IN
A
142.250.x.x
这就是最终答案。
- TTL
例如:
google.com
300
IN
A
142.250.x.x
结构:
Name
TTL
Class
Type
RDATA
其中:
300
是:
TTL = 300 seconds
Wireshark 将 Resource Record 的 TTL 暴露为 dns.resp.ttl。
- TTL 不是“IP 存活时间”
这是必须纠正的一个常见误解。
错误理解:
TTL 300 → IP 300 秒后失效。
正确理解:
TTL 300 → 这个 DNS Record 可以被缓存 300 秒。
比如:
google.com
TTL=300
A=142.250.x.x
表示:
DNS Cache
↓
最多缓存 300 秒
不是说:
Google Server
↓
300 秒以后关闭
20. 接下来进入最重要的:Referral
如果 Recursive Resolver 自己没有答案,它去问 Root:
google.com A?
Root 不会给:
google.com A 142.250.x.x
而可能返回:
Answer:
0
Authority:
13 records
Additional:
...
例如:
Authority:
com. NS a.gtld-servers.net.
com. NS b.gtld-servers.net.
com. NS c.gtld-servers.net.
...
这就是:
Referral
21. 为什么 Answer = 0?
因为 Root:
没有 google.com 的 A Record。
但它告诉你:
.com Zone 的 DNS Server 在哪里。
所以:
Answer = 0
Authority > 0
不等于失败。
这是一个非常重要的抓包判断技巧。
- 怎么判断这是 Referral?
看:
Answer
为空。
然后:
Authority
里面有:
NS
例如:
com. NS a.gtld-servers.net.
那么你基本可以判断:
这是 delegation / referral。
23. Additional Section
然后你可能看到:
Additional:
a.gtld-servers.net
A
192.5.x.x
或者:
AAAA
2001:...
这就是给 Recursive Resolver 提供下一跳 DNS Server 的地址。
- Glue 是什么?
把刚才的逻辑再讲透一点。
Root 告诉你:
.com
NS
a.gtld-servers.net
但是你需要访问:
a.gtld-servers.net
你必须知道它的 IP。
所以 Referral 可能附带:
a.gtld-servers.net
A
x.x.x.x
这就是 Glue/Additional 信息发挥作用的地方。
它让 Resolver 可以:
Root
↓
知道 .com NS
↓
直接知道 NS IP
↓
访问 .com TLD
而不是再次陷入名字解析。
- Recursive → TLD
接下来:
8.8.8.8
↓
.com TLD
Query:
google.com A
RD=0
注意:
RD = 0
这意味着:
Recursive Resolver 不要求 .com TLD 替它继续递归。
它自己负责继续下一跳。
- TLD Response
TLD:
Answer:
0
但是:
Authority:
google.com
NS
xxx.google...
意思:
我不知道 google.com A,但是我知道 google.com 的权威 DNS。
这又是一个 Referral。
所以你会看到:
Root
↓
Referral to .com
TLD
↓
Referral to google.com NS
Authoritative
↓
Actual Answer
27. Authoritative Response
最终:
google.com
TTL 300
IN
A
142.250.x.x
这次:
AA = 1
因为:
Authoritative DNS
真正负责这个 Zone。
- 如果你看到 CNAME 呢?
现实里经常不是:
www.google.com
↓
A
↓
IP
而可能是:
www.example.com
↓
CNAME
↓
something.example.net
↓
A
↓
IP
例如:
www.example.com
CNAME
edge.example.net
那么 Resolver 还要继续解析:
edge.example.net
然后:
edge.example.net
A
1.2.3.4
最终:
www.example.com
↓
CNAME
↓
edge.example.net
↓
A
↓
1.2.3.4
29. 所以 Answer 里可能同时有 CNAME + A
例如:
Answer:
www.example.com
CNAME
edge.example.net
edge.example.net
A
1.2.3.4
这时你不要误以为:
一个 Query 怎么出现两个答案?
因为:
CNAME 本身就是答案的一部分,而目标名字还需要继续解析。
- NXDOMAIN 又是什么?
现在假设:
abcxyz123.google.com
根本不存在。
Authoritative DNS 可能返回:
RCODE = NXDOMAIN
意思:
这个域名不存在。
注意:
NXDOMAIN
和:
NOERROR + Answer=0
不是一回事。
- 两者区别非常重要
NXDOMAIN
这个名字不存在。
NOERROR + Answer=0
名字可能存在,但是你问的这个 Record Type 没有。
例如:
google.com
存在。
但是你问:
google.com AAAA
如果没有 AAAA:
RCODE = NOERROR
Answer = 0
这和:
xyz123.google.com
不存在:
RCODE = NXDOMAIN
完全不同。
- DNS Negative Caching
这里又会出现一个很重要的 Cache。
假设:
abc.example.com
不存在。
Authoritative:
NXDOMAIN
Resolver 可以缓存这个“不存在”的结果一段时间。
所以:
第一次:
Client
↓
Recursive
↓
Authoritative
↓
NXDOMAIN
第二次:
Client
↓
Recursive
↓
Negative Cache
↓
NXDOMAIN
甚至不需要再访问权威 DNS。
- EDNS:你抓包时很可能看到 OPT
现代 DNS Packet 经常不是简单:
Question
Answer
Authority
Additional
你还会看到:
OPT
例如:
Additional Records:
. OPT
这是:
EDNS(0)
它允许 DNS 扩展协议能力,例如更大的 UDP Payload,以及 DNSSEC 相关的 DO bit 等。
Wireshark 也提供 dns.resp.edns0_version、UDP payload size、DO bit 等字段。
- DO Bit
如果进行 DNSSEC 查询,你经常看到:
DO = 1
意思:
DNSSEC OK
也就是:
我希望 DNS 响应里包含 DNSSEC 相关数据。
例如:
RRSIG
DNSKEY
DS
NSEC
NSEC3
等。
- DNSSEC 开始进入另一套逻辑
普通 DNS:
google.com
↓
A
↓
IP
DNSSEC:
google.com
↓
A
↓
RRSIG
↓
DNSKEY
↓
DS
↓
建立信任链
Wireshark 对 DNSKEY、DS、RRSIG 等都有专门的 DNS 字段解析。
- DNSSEC 的核心不是“加密”
这一点非常重要。
DNSSEC:
不是:
DNSSEC
↓
加密 DNS
而是:
DNSSEC
↓
数字签名
↓
验证 DNS 数据真实性
也就是说:
DNSSEC 主要解决 Authenticity / Integrity。
而:
DoH
DoT
主要解决:
DNS 查询传输过程中的隐私和加密。
两者完全是不同维度。
- 最终把 Wireshark 里最重要的字段整理一下
Wireshark 字段 含义
dns.id Transaction ID
dns.flags.response Query / Response
dns.flags.recdesired RD
dns.flags.recavail RA
dns.flags.authoritative AA
dns.flags.truncated TC
dns.flags.rcode Response Code
dns.qry.name 查询名称
dns.qry.type 查询类型
dns.qry.class 查询 Class
dns.resp.ttl Resource Record TTL
dns.a IPv4 A
dns.aaaa IPv6 AAAA
dns.resp.ns NS
dns.rrsig.* DNSSEC RRSIG
dns.dnskey.* DNSSEC DNSKEY
dns.ds.* DNSSEC DS
这些字段可以直接对应 Wireshark 的 DNS display-filter 字段体系。
- 最后给你一张“DNS 抓包判断表”
以后看到一个 DNS Response,按这个顺序判断:
DNS Response
│
▼
RCODE 是什么?
│
┌───────────┼────────────┐
│ │ │
NOERROR NXDOMAIN 其他
│
▼
Answer 有吗?
│
┌───┴────┐
│ │
有 没有
│ │
▼ ▼
最终答案 看 Authority
│
▼
NS?
│
▼
Referral
然后:
Answer
↓
看 Type
↓
A / AAAA / CNAME / MX / TXT ...
再:
TTL
↓
判断 Cache 生命周期
再:
AA
↓
是不是权威回答?
再:
RA / RD
↓
有没有递归?
最后:
Additional
↓
OPT?
Glue?
EDNS?
DNSSEC?
39. 到这里,你已经可以“读”DNS 包了
真正分析一个 DNS 故障时,你脑子里应该形成这样一条链:
① Client 有没有发 Query?
↓
② Query 到没到 Local DNS?
↓
③ Local DNS 有没有回?
↓
④ RCODE 是什么?
↓
⑤ Answer 有没有?
↓
⑥ 如果没有,Authority 是什么?
↓
⑦ 是不是 Referral?
↓
⑧ 下一跳 NS 的 IP 有没有 Glue?
↓
⑨ Recursive 能不能访问下一跳?
↓
⑩ Authoritative 有没有返回?
↓
⑪ AA 是否正确?
↓
⑫ TTL 多久?
↓
⑬ 是否 CNAME?
↓
⑭ 是否 DNSSEC?
↓
⑮ 最终 Client 是否拿到 IP?
这其实已经是真实 DNS troubleshooting 的基本框架。
下一节建议进入一个非常实战的场景
我们下一步可以直接做:
dig +trace google.com 全流程解剖。
因为 dig +trace 特别适合把刚才讲的理论变成实际:
$ dig +trace google.com
.
↓
.com
↓
google.com
↓
A / AAAA
然后我们
逐行解释:
;; Received ...
;; QUESTION SECTION:
;; AUTHORITY SECTION:
;; ADDITIONAL SECTION:
再进一步把 dig google.com、dig +trace google.com、dig @8.8.8.8 google.com、dig @权威DNS google.com 四个命令放在一起比较。
这样你就会彻底理解:
“普通 dig 为什么只看到一个答案,而 +trace 为什么能把 Root → TLD → Authoritative 全部暴露出来。”
.
也就是:
Root Zone
十二、你可能看到类似这样的输出
不同时间、网络和 BIND 版本输出会不同,所以这里重点看结构:
. 518400 IN NS a.root-servers.net.
. 518400 IN NS b.root-servers.net.
. 518400 IN NS c.root-servers.net.
...
这不是:
google.com
的答案。
这是:
Root 告诉你 Root Zone 的 Name Servers。
十三、然后发生什么?
dig +trace 会找到 Root Server。
然后问:
google.com A?
Root:
我不知道 google.com 的 A。
但是:
.com
由这些 TLD DNS Server 管理。
于是出现:
com. IN NS ...
十四、这就是我们前面说的 Referral
你现在终于可以把理论和命令对应起来:
Root
↓
Answer:
0
Authority:
com. NS ...
Additional:
NS IP
也就是:
Answer = 没有最终答案
Authority = 告诉你下一步去哪
Additional = 帮你找到下一跳 Server
十五、接下来 .com
现在 dig +trace 找到了:
.com TLD
于是继续:
.com
↓
google.com?
TLD:
我不知道 google.com 的 A。
但是:
google.com
的权威 DNS 在这里。
于是:
google.com. NS ...
再次 Referral。
十六、然后终于到 Authoritative
现在:
dig +trace
找到了:
google.com Authoritative DNS
于是:
google.com A?
Authoritative:
google.com.
300
IN
A
142.250.x.x
并且这一次:
AA = 1
十七、于是整个 +trace 可以画成
dig +trace google.com
|
↓
Root "."
|
"Where is .com?"
|
↓
.com TLD
|
"Where is google.com?"
|
↓
google.com NS
|
↓
Authoritative DNS
|
"google.com A = X"
|
↓
Final IP
这就是:
DNS Delegation Chain
十八、现在比较两个命令
普通 dig
dig google.com
看到的是:
Client
↓
Recursive DNS
↓
Final Answer
+trace
dig +trace google.com
看到的是:
Root
↓
.com
↓
google.com Authoritative
↓
Final Answer
所以:
dig
= recursive result
dig +trace
= iterative delegation path
十九、第三个非常重要的命令
现在我们直接问 Root。
例如:
dig @a.root-servers.net google.com
这时候你不是让 Root 帮你递归。
你是在直接问 Root:
google.com A?
通常:
RD = 0
Root:
Answer = 0
Authority = .com NS
二十、为什么 Root 不给 IP?
因为:
Root
负责:
.
它知道:
.com
.net
.org
.cn
...
的 delegation。
但是它不负责:
google.com A
所以:
Root
↓
".com 在这里"
而不是:
Root
↓
"Google IP 是 xxx"
二十一、第四个命令:直接问 TLD
假设你从 Root 得到了一个 .com TLD Server:
a.gtld-servers.net
那么可以:
dig @a.gtld-servers.net google.com
你得到:
Answer:
0
Authority:
google.com NS ...
这就是第二次 Referral。
二十二、然后直接问 Authoritative
假设 TLD 告诉你:
google.com NS ...
找到一个权威 DNS 后:
dig @
这一次:
Answer:
google.com.
TTL
IN
A
142.250.x.x
并且:
AA
应该是:
1
这才是真正的:
Authoritative Answer
二十三、所以我们可以手工完成 +trace
这非常重要。
+trace 其实可以理解成:
Step 1
找 Root
↓
Step 2
问 Root
google.com?
↓
Step 3
Root 告诉我 .com
↓
Step 4
问 .com
google.com?
↓
Step 5
.com 告诉我 google.com NS
↓
Step 6
问 Authoritative
google.com A?
↓
Step 7
得到 IP
二十四、这就是“递归”和“迭代”的真正区别
现在你应该能彻底理解:
dig google.com
你:
Client
|
| RD=1
↓
Recursive Resolver
"你帮我搞定。"
dig +trace google.com
你实际上:
Client
|
↓
Root
"告诉我下一步。"
↓
.com
"告诉我下一步。"
↓
Authoritative
"给我最终答案。"
所以:
Recursive:
"帮我完成整个任务"
Iterative:
"告诉我下一步该问谁"
二十五、再看 dig +short
普通:
dig google.com
输出很多。
如果你只想:
IP
可以:
dig +short google.com
例如:
142.250.x.x
官方文档也给出了 dig +short example.com 作为只显示简化结果的用法。
二十六、只看 Answer
非常实用:
dig +noall +answer google.com
得到:
google.com. 300 IN A 142.250.x.x
这对于脚本和故障排查非常好。
二十七、查询 NS
比如:
dig google.com NS
你会得到:
google.com.
NS
...
这回答:
google.com 的权威 DNS 是谁?
二十八、查询 MX
dig google.com MX
这回答:
google.com 的邮件服务器是什么?
例如:
google.com.
MX
...
注意:
DNS 不只是:
Name → IP
还有:
Name → Name Server
Name → Mail Server
Name → Alias
Name → Text
...
二十九、查询 CNAME
dig www.example.com CNAME
如果存在:
www.example.com.
CNAME
xxx.example.net.
那么你就知道:
www.example.com
↓
CNAME
↓
xxx.example.net
然后再查:
dig xxx.example.net A
三十、DNS 故障排查开始变得非常有意思
假设用户说:
“浏览器打不开 example.com。”
你不要直接猜。
第一步:
dig example.com
如果:
NOERROR
ANSWER
A
DNS 基本工作。
那么继续查:
TCP
TLS
HTTP
如果:
SERVFAIL
那么可能:
Recursive failure
DNSSEC validation failure
Upstream failure
Delegation problem
Timeout
DNSSEC 验证失败时,递归解析器可能向客户端表现为 SERVFAIL。BIND 官方 DNSSEC 文档也给出了这种典型表现。
如果:
NXDOMAIN
那么:
这个名字不存在。
如果:
NOERROR
ANSWER=0
则需要继续检查:
CNAME
AAAA
A
NS
SOA
以及具体查询的 Record Type。
三十一、一个非常实用的 DNS 排障套路
以后你遇到:
“DNS 有问题。”
直接按这个顺序:
dig google.com
↓
dig @8.8.8.8 google.com
↓
dig +trace google.com
↓
dig google.com NS
↓
dig google.com A
↓
dig google.com AAAA
如果怀疑 CNAME:
dig www.example.com CNAME
如果怀疑 DNSSEC:
dig +dnssec example.com
或者进一步使用:
delv example.com
delv 是 BIND 提供的 DNSSEC-aware 工具;官方文档还说明 delv +ns 可以模拟一个完整递归解析器的迭代过程。
三十二、dig +trace 有一个很重要的细节
很多人以为:
dig +trace google.com
就是:
向你的 Recursive DNS 请求:
"请给我 trace"
不是。
+trace 改变了 dig 的工作方式。
它自己进行:
Root
↓
TLD
↓
Authoritative
的迭代查询。BIND 官方文档明确描述了这一行为。
所以你可以把它理解成:
普通 dig:
┌──────────────┐
│ Recursive DNS│
└──────┬───────┘
↑
│
Client
而:
dig +trace:
Client/dig
│
├────→ Root
│
├────→ TLD
│
└────→ Authoritative
三十三、一个更准确的对比
命令 谁负责递归 主要目的
dig google.com 配置的 DNS Server 普通解析
dig @8.8.8.8 google.com 8.8.8.8 指定 Resolver
dig @root google.com 你自己 观察 Root Referral
dig @TLD google.com 你自己 观察 TLD Referral
dig @Auth google.com 你自己 获取权威答案
dig +trace google.com dig 自己逐级查询 查看完整 delegation chain
三十四、还有一个非常值得你记住的事实
dig +trace 不是严格等价于一个生产 Recursive Resolver 的完整行为。
BIND 文档特别指出,dig +trace 是做 delegation tracing;如果希望更接近 named 本身作为一个 cold-cache recursive resolver 的行为,可以使用 delv +ns。
所以:
dig +trace
特别适合:
教学 / 查看 delegation / DNS troubleshooting
而:
delv +ns
更适合:
模拟递归解析器的解析和验证过程
这个区别以后做高级 DNS 实验时会很有价值。
三十五、现在把整个专题连起来
我们最开始讲:
Browser
↓
OS Cache
↓
Local DNS
↓
Recursive
↓
Root
↓
TLD
↓
Authoritative
现在你已经可以把它映射到工具:
普通访问
─────────────────────────
Browser
↓
OS
↓
Local DNS
↓
Recursive
↓
最终 IP
对应:
dig google.com
而:
Recursive
↓
Root
↓
TLD
↓
Authoritative
对应:
dig +trace google.com
而单独观察每一层:
dig @root-server google.com
dig @tld-server google.com
dig @authoritative-server google.com
这样你就可以手工把 DNS 整棵树拆开检查。
三十六、最后送你一张“DNS 实战地图”
以后看到任何 DNS 问题,先在脑子里跑:
DNS Troubleshooting
│
▼
dig domain.example
│
┌─────────────┴──────────────┐
│ │
NOERROR ERROR
│ │
▼ ▼
Answer 有没有? RCODE 是什么?
│ │
┌───────┴──────┐ ├── NXDOMAIN
│ │ ├── SERVFAIL
有 无 ├── REFUSED
│ │ └── TIMEOUT
▼ ▼
A/AAAA CNAME?
│ │
▼ ▼
IP Follow CNAME
│
▼
dig +trace
│
┌────────┴────────┐
▼ ▼
Root TLD
│ │
▼ ▼
Referral Referral
│ │
└────────┬────────┘
▼
Authoritative
│
▼
Final Answer
│
▼
TTL
│
▼
Cache
下一步我建议我们进入 DNS 专题里非常关键的一关:DNSSEC。
我们可以从真实的:
dig +dnssec google.com
开始,逐个拆:
DNSKEY
↓
DS
↓
RRSIG
↓
NSEC / NSEC3
↓
Root KSK
↓
.com DS
↓
google.com DNSKEY
↓
A + RRSIG
然后解释 “Recursive Resolver 到底怎么判断 DNS 答案是真的,而不是被攻击者伪造的?”——这会把我们前面讲的 Root → TLD → Authoritative 再往上提升一个层次。
好,我们现在进入 DNS 最关键的一层:DNSSEC。
前面我们解决的是:
DNS 怎么找到 google.com?
DNSSEC 要解决的是:
“我找到的 google.com IP,怎么证明它是真的,而不是被人篡改/伪造的?”
DNSSEC 的核心就是 Chain of Trust(信任链):从 Root 的 Trust Anchor 开始,一层一层验证 .com、google.com,最后验证具体的 DNS Record。
- 先看整个 DNSSEC 信任链
可以把它想成:
ROOT "."
│
Root Trust Anchor
Root KSK
│
DS(.com)
│
.com
│
DS(google.com)
│
google.com
│
DNSKEY + RRSIG
│
A record
│
142.250.x.x
普通 DNS 的 resolution chain 是:
Root
↓
.com
↓
google.com
↓
A record
DNSSEC 多了一条密码学验证链:
Root Trust Anchor
↓
验证 Root DNSKEY
↓
验证 .com DS
↓
验证 .com DNSKEY
↓
验证 google.com DS
↓
验证 google.com DNSKEY
↓
验证 google.com A
所以:
DNS resolution 是“找到答案”。
DNSSEC validation 是“证明答案可信”。
ICANN 也把 Root Trust Anchor 描述为 DNSSEC 信任链最顶端的可信起点。
- DNSSEC 到底增加了哪些 Record?
最重要的 4 个:
Record 作用
DNSKEY 公钥
RRSIG DNS Record 的数字签名
DS 父 zone 对子 zone 公钥的“指纹/承诺”
NSEC/NSEC3 证明某个名字/Record 不存在
可以先记成:
DNSKEY = Key
RRSIG = Signature
DS = Parent → Child 的信任链接
NSEC = Proof of Non-Existence
BIND 官方 DNSSEC 文档也明确把 DNSKEY、RRSIG、NSEC/NSEC3 和父 zone 中的 DS 作为建立 DNSSEC chain of trust 的核心记录。
- DNSKEY:公钥在哪里?
假设:
google.com
开启 DNSSEC。
它的 zone 会发布:
google.com. DNSKEY ...
这里面包含 public key。
为什么需要 public key?
因为 authoritative server 生成:
A google.com → 142.250.x.x
以后,还会生成:
RRSIG(A record)
也就是:
A record
+
private key
↓
RRSIG
Resolver 拿到:
A record
RRSIG
DNSKEY
然后使用:
public key
验证:
RRSIG 是否真的对应这个 A record?
4. RRSIG 是什么?
假设:
google.com. 300 IN A 142.250.72.14
普通 DNS:
Question:
google.com A
Answer:
google.com A 142.250.72.14
DNSSEC:
Answer:
google.com A 142.250.72.14
RRSIG:
A record 的数字签名
概念上:
private key
│
▼
A record ──────────► Signature
│
▼
RRSIG
Resolver:
A record
+
RRSIG
+
DNSKEY(public key)
│
▼
cryptographic verification
│
├── PASS → answer authentic
│
└── FAIL → bogus
所以攻击者即使把:
google.com → 142.250.72.14
改成:
google.com → 6.6.6.6
也不能简单地重新生成一个合法的 RRSIG,因为他没有 zone 的 private signing key。
- 但这里马上出现一个问题
Resolver 拿到:
google.com DNSKEY
然后用这个 DNSKEY 验证:
google.com A
很好。
但是:
为什么相信这个 DNSKEY 本身是真的?
这是 DNSSEC 最漂亮的地方。
答案:
父 zone 来证明。
也就是:
.com
↓
证明 google.com 的 DNSKEY
具体就是:
google.com DNSKEY
│
▼
hash
│
▼
DS
│
▼
.com zone
6. DS:父 zone 如何“认可”子 zone?
假设:
google.com
有 DNSKEY:
google.com DNSKEY = PublicKeyGoogle
对它做 hash:
hash(PublicKeyGoogle)
得到:
DS
于是 .com zone 保存:
google.com. DS ...
这就形成:
.com
│
│ DS
▼
google.com DNSKEY
所以 DS 可以理解为:
Parent zone 对 Child zone DNSKEY 的密码学承诺。
- 再往上一层
但是:
为什么相信 .com 的 DNSKEY?
同样的问题。
答案:
Root
↓
DS(.com)
↓
.com DNSKEY
于是整个链条:
ROOT
│
│ DS(.com)
▼
.com DNSKEY
│
│ DS(google.com)
▼
google.com DNSKEY
│
│ RRSIG
▼
google.com A
这就是:
Chain of Trust
ICANN 对这个机制的描述也是:父 zone 为子 zone 的 key material 提供可验证的信任连接,从 Root 的 trust anchor 开始建立连续的信任链。
- Root 为什么可以被信任?
这是 DNSSEC 最关键的问题:
如果所有东西都需要验证,那第一个东西靠什么验证?
答案:
Trust Anchor
Resolver 本地预先配置 Root 的可信 key。
例如:
Recursive Resolver
│
│ local configuration
▼
Root Trust Anchor
这不是通过普通 DNS 查询得到以后才相信。
而是:
configured locally
所以逻辑是:
TRUST ANCHOR
│
▼
Root DNSKEY
│
▼
DS(.com)
│
▼
.com DNSKEY
│
▼
DS(google.com)
│
▼
google.com DNSKEY
│
▼
A + RRSIG
这就是整个系统的信任起点。
ICANN 将 root KSK 的 public key 作为 DNSSEC 的 root trust anchor;验证器利用它开始建立后续的 chain of trust。
- KSK 和 ZSK 又是什么?
这里又会遇到两个概念:
KSK
ZSK
分别是:
KSK
Key Signing Key
主要用来签署:
DNSKEY RRset
ZSK
Zone Signing Key
主要用来签署 zone 中其他 RRsets。
简化理解:
KSK
│
▼
DNSKEY RRset
│
▼
ZSK
│
┌───────┼────────┐
▼ ▼ ▼
A MX TXT
│ │ │
RRSIG RRSIG RRSIG
实际 DNSSEC 的 key-management 会更复杂,但这个模型对于理解 validation 非常有用。
- 现在真正走一遍 google.com
假设:
Client
↓
Recursive Resolver
用户:
dig google.com
Resolver 发现 cache miss。
Step 1:问 Root
Resolver:
google.com A ?
向 Root 查询。
Root 不知道:
google.com = ?
但是 Root 知道:
.com authoritative servers
所以返回:
Authority:
.com NS ...
同时 DNSSEC 情况下还有相关签名材料。
- Step 2:问 .com
Resolver:
google.com A ?
问 .com authoritative server。
.com 也不知道:
google.com A = ?
但它知道:
google.com authoritative servers
所以返回:
google.com NS ...
并且 DNSSEC 下:
google.com DS ...
RRSIG(DS)
注意这里非常重要:
.com 不仅告诉 resolver:
“Google 的 authoritative DNS 在这里。”
还告诉它:
“这是 Google DNSSEC key 的可信 fingerprint。”
- Step 3:问 Google Authoritative DNS
Resolver 去:
google.com authoritative server
查询:
google.com A
得到:
A
RRSIG(A)
同时 resolver 还需要:
google.com DNSKEY
RRSIG(DNSKEY)
13. Resolver 开始验证
现在 resolver 手里有:
Root trust anchor
.com DS
.com DNSKEY
google.com DS
google.com DNSKEY
google.com A
RRSIG(A)
开始:
验证 Root
Trust Anchor
↓
Root DNSKEY
↓
验证 .com
Root
│
└── DS(.com)
↓
.com DNSKEY
↓
验证 google.com
.com
│
└── DS(google.com)
↓
google.com DNSKEY
↓
验证 A record
google.com DNSKEY
+
google.com A
+
RRSIG(A)
↓
VALID
整个过程可以画成:
TRUST ANCHOR
│
▼
Root DNSKEY
│
verify DS
│
▼
.com DNSKEY
│
verify DS
│
▼
google.com DNSKEY
│
verify RRSIG
│
▼
google.com A
│
▼
VALID
BIND 的官方 DNSSEC guide 给出的 validation 流程也是从 child DNSKEY 一直向 parent 查询 DS,再到 Root DNSKEY,最后用本地 trust anchor 判断 Root key 是否可信。
- dig 直接观察 DNSSEC
现在我们开始真正操作。
先:
dig google.com
然后:
dig +dnssec google.com
你会看到类似:
;; flags: qr rd ra;
;; ANSWER SECTION:
google.com. 300 IN A 142.250.x.x
google.com. 300 IN RRSIG A ...
重点:
A
RRSIG
15. 查看 DNSKEY
运行:
dig +dnssec google.com DNSKEY
你会看到:
DNSKEY
RRSIG DNSKEY
大概结构:
google.com. IN DNSKEY ...
google.com. IN DNSKEY ...
google.com. IN RRSIG DNSKEY ...
这里的 DNSKEY RRset 本身也需要验证。
这就是为什么你会看到:
DNSKEY
+
RRSIG(DNSKEY)
16. 查看 DS
运行:
dig +dnssec google.com DS
这里查询的是:
google.com DS
但这个 record 实际上位于:
.com zone
所以你可以把它理解成:
.com
google.com. DS ...
它连接:
.com
↓
google.com DNSKEY
17. 这三个命令非常重要
建议你自己运行:
dig +dnssec google.com A
dig +dnssec google.com DNSKEY
dig +dnssec google.com DS
然后把它们放在一起:
A
│
└── RRSIG(A)
↑
│
DNSKEY
↑
│
DS
↑
│
Parent
这时候 DNSSEC 的结构就基本进入脑子了。
- delv 更有意思
如果你的系统安装了 BIND utilities,可以试:
delv google.com
delv 和 dig 有一个重要区别:
delv 本身就是为了 DNSSEC validation 而设计的。
BIND 文档说明,delv 默认会进行 DNSSEC validation,并使用 Root zone 的内置 trust anchor;它还可以显示验证相关信息。
所以:
dig
更像:
“让我看看 DNS 返回了什么。”
而:
delv
更像:
“让我验证这些 DNS 数据到底可信不可信。”
- DNSSEC 验证失败会发生什么?
这是面试里非常重要的问题。
假设攻击者伪造:
google.com A 6.6.6.6
但对应:
RRSIG
验证失败。
Resolver:
DNSSEC validation
│
▼
INVALID
│
▼
SERVFAIL
所以客户端可能看到:
SERVFAIL
而不是:
6.6.6.6
这也是为什么 DNSSEC validation 能防止某些 DNS spoofing / tampering 场景。ICANN 将 DNSSEC validation 描述为检查 DNS 数据真实性和完整性的机制。
- 那 NXDOMAIN 怎么办?
这是 DNSSEC 更厉害的一部分。
攻击者不只是可以伪造:
google.com → fake IP
还可能试图伪造:
doesnotexist.google.com → NXDOMAIN
DNSSEC 需要能够证明:
这个名字真的不存在。
于是出现:
NSEC
或者:
NSEC3
它们提供:
Proof of Non-Existence
也就是说:
普通 DNS:
"没有这个 domain"
DNSSEC:
"我不仅说没有,
我还给你密码学证据证明它不存在。"
21. DNSSEC ≠ DNS Encryption
这个非常容易混。
DNSSEC
解决:
Authenticity
Integrity
即:
DNS answer 是不是可信的?有没有被篡改?
但是 DNSSEC:
不负责加密 DNS query。
DoH / DoT
解决的是:
Privacy / Transport Encryption
例如:
DNS over HTTPS
DNS over TLS
它们保护:
Client
│
│ encrypted
▼
DNS Resolver
所以:
DNSSEC
↓
"答案是真的"
DoH / DoT
↓
"别人不容易看到/修改我和 resolver 之间的 DNS traffic"
两者解决的问题不同。
- 最终把整个 DNS + DNSSEC 合起来
现在我们终于可以把前面所有知识串起来:
Browser
│
▼
Browser DNS Cache
│
▼
OS DNS Cache
│
▼
Local DNS / Stub Resolver
│
▼
Recursive Resolver
│
│
├──────────► Root
│ │
│ ▼
│ .com
│ │
│ ▼
│ google.com Auth
│ │
│ ▼
│ A + RRSIG
│
▼
DNSSEC Validation
│
├── Root Trust Anchor
├── DS
├── DNSKEY
├── RRSIG
└── NSEC/NSEC3
│
▼
VALID
│
▼
IP Address
│
▼
TCP / QUIC
│
▼
TLS
│
▼
HTTPS
DNS resolution 告诉你:
google.com → IP
DNSSEC validation 告诉你:
这个 IP 的 DNS 数据
可以通过从 Root 开始的密码学信任链验证。
23. 还有一个非常有意思的现实问题
你现在可以把 DNSSEC 想成:
Root KSK
↓
.com
↓
google.com
↓
A record
但现实世界里 Root KSK 本身也会 rollover(更换)。
而且这是当前真实的 DNS 基础设施事件:ICANN 已公布 2026 年 10 月 11 日进行 Root Zone KSK rollover,新的 KSK-2024 key tag 是 38696;DNSSEC-validating resolver operators 需要确保新的 trust anchor 已正确配置。
所以你现在学到的:
Trust Anchor
↓
KSK
↓
Chain of Trust
并不是纯理论,而是整个 Internet DNS 基础设施目前正在实际维护的东西。
浙公网安备 33010602011771号