3019 字
15 分钟
DNS 协议解析
2026-03-20

速通版视频解析:🖥️DNS

互联网的“电话簿”:深入解析 DNS 的运行机制#

在互联网世界中,IP地址是每台设备的“身份证”,但人类并不擅长记忆像 139.159.241.37 这样晦涩的数字。于是,DNS(Domain Name System) 应运而生,它像一个巨大的分布式电话簿,将域名翻译为机器可读的 IP。

1. DNS 的层级架构:递归与迭代#

如果把全球所有域名和IP的映射关系全部存放在一台服务器里,那这台服务器瞬间就会被全球网民的请求压垮。因此,DNS 的核心哲学是分布式存储层级委派

  • 根域名服务器(Root Server):最高层。全球共有 13 组逻辑根服务器(编号从 A 到 M),负责指向 .com, .cn, .org 等顶级域名服务器的地址。
  • 顶级域名服务器(TLD Server):负责管理特定的顶级域名,如 .com 顶级域名服务器知道 google.com 归哪里管。
  • 权威域名服务器(Authoritative Server):寻址的最终目的地,这里存储着域名和IP的真实映射记录(A记录、CNAME等),如阿里云 DNS、腾讯云 DNS 或 Cloudflare 就是典型的权威服务器。

两种查询模式:#

  1. 递归查询(Recursive):MUA(浏览器/操作系统)请求本地域名服务器(local DNS Resolver),要求它:“不管用什么方法,请直接给我 IP。”本地域名服务器必须跑完全程给出最终结果的模式,就是递归查询。
  2. 迭代查询(Iterative):本地域名服务器向其他服务器询问时,对方只会回答:“我不知道,你去问那台服务器吧。”这是 DNS 架构高效运行的关键,它让处于流量顶端的根服务器和顶级服务器只负责“指路”,避免了单点计算资源的耗尽,极大增强了互联网的抗压能力。

2. DNS 的缓存与性能平衡#

试想一下,如果全球几十亿网民每次打开网页、加载一张图片,都要让 DNS 走一遍“根 -> 顶级 -> 权威”的完整层级查询,互联网的骨干网和根服务器恐怕会在一秒钟内瘫痪。因此,DNS 极度依赖缓存机制

  • 浏览器缓存:最快,直接从内存读取。(chrome://net-internals/#dns 你可以直接看到浏览器内部维护的域名映射和过期状态)
  • 操作系统缓存:如果浏览器缓存没有,操作系统会优先读取本地的 hosts 文件,如果没有命中再查找 OS 本身的DNS缓存。(Windows: ipconfig /displaydns 查看, ipconfig /flushdns 清理)
  • 路由器缓存(Router Cache):如果系统缓存也没有,请求会被发给你的路由器,大部分智能路由器也会缓存常用域名。
  • 本地域名服务器(Local DNS):通常由你的 ISP(电信/移动/联通)提供,或你手动配置的公共 DNS(如 114.114.114.114),这里是一个巨大的共享资源池,汇聚了全网用户的查询结果,命中率极高。
  • 只有当这四道缓存全部未命中或已过期时,Local DNS 才会真正向外网发起迭代查询。 关键属性:TTL (Time to Live) TTL 定义了记录在缓存中存活的时间。TTL设置是一门艺术
  • 设置过短:解析压力大,网页加载慢。
  • 设置过长:服务器 IP 变更时,全球用户会因为缓存过期慢而无法访问新地址。

💡 运维的实战技巧:如何做到服务器IP的无感平滑迁移? 假设你的网站域名原本 TTL 为 24 小时。现在你要把网站搬迁到新服务器:

  1. 提前降级:在搬迁前两三天,将 DNS 的 TTL 修改为 300 秒(5分钟)。
  2. 等待扩散:等待至少 24 小时,让全球各地的旧缓存(长TTL)自然失效,全部替换为新的 5 分钟短缓存。
  3. 切换IP:在新服务器部署好代码后,去 DNS 后台将域名指向新 IP。此时,全球用户最多只需 5 分钟就会访问到新服务器。
  4. 恢复常态:观察几天确认无误后,将 TTL 重新调回 24 小时,降低解析压力。

3. 协议核心:为什么是 UDP?何时切换 TCP?#

很多人知道 DNS 默认运行在 端口53,但它是基于 UDP 还是 TCP 呢?答:绝大部分时间是 UDP,特殊情况是 TCP。

为什么首选 UDP?—— 极致的速度#

如果使用TCP,查询前需要三次握手(消耗约 1.5 个 RTT),查询完毕还要四次挥手。而 DNS 查询通常只需要一问一答,数据量极小。使用无连接的UDP协议,只需要 1个RTT 就能拿到结果,这对于动辄需要加载几十个域名的现代网页来说,速度提升是巨大的。

什么时候会切换到 TCP?—— 突破网络传输的限制与保证可靠性#

早期的以太网传输中有一个不成文的约定:为了避免 IP 层分片导致丢包率剧增,DNS 协议严格规定,UDP报文有效载荷不能超过 512 字节

  1. 突破网络传输的限制
    • 如果权威服务器返回的解析记录(比如包含大量的 IPv6 地址或复杂的 DNSSEC 加密签名)超过了 512 字节,它会狠心把塞不下的数据直接砍掉,服务器会在DNS响应报文的首部将 TC(Truncated,截断)标志位置为 1
    • 客户端收到带有 TC=1 的报文后,会立刻丢弃该结果,并使用TCP协议(端口53)重新发起完整的查询。
  2. 保证数据的可靠性
    • 大型企业为了防止 DNS 宕机,往往会部署多台 DNS 服务器(一主多从)。当主服务器的记录发生更新时,需要把成千上万条记录一次性同步给从服务器(这叫区域传送,分为 AXFR 全量和 IXFR 增量)。 这种动辄几 MB 的海量数据传输,如果用 UDP 肯定会丢包乱序,因此区域传送强制使用 TCP 53 端口。 (此外,主从 DNS 服务器之间进行“区域传送 / Zone Transfer”同步海量记录时,也会使用 TCP 以保证数据的可靠性。)

4. 动手实践:DNS 的“透明”抓包#

我们可以利用 dig 工具来窥探 DNS 查询的每一个细节。

Terminal window
# 查看一个域名的完整解析过程
dig bilibili.com +trace
# ...
# ;; Received 811 bytes from 172.23.240.1#53(172.23.240.1) in 851 ms
# 向本地 DNS 获取全球 13 组根服务器 (Root Server) 的地址作为查询起点。
# bilibili.com. 172800 IN NS ns3.dnsv5.com.
# bilibili.com. 172800 IN NS ns4.dnsv5.com.
# ;; Received 768 bytes from 192.5.6.30#53(h.root-servers.net) in 333 ms
# 随机询问一个根服务器(h.root-servers.net),它根据顶级域名(.com)的记录,将查询委派给负责该域名的 权威DNS(腾讯云 DNSPod)。
# bilibili.com. 60 IN A 139.159.241.37
# bilibili.com. 60 IN A 47.103.24.173
# bilibili.com. 60 IN A 119.3.70.188
# bilibili.com. 60 IN A 8.134.50.24
# bilibili.com. 86400 IN NS ns4.dnsv5.com.
# bilibili.com. 86400 IN NS ns3.dnsv5.com.
# ;; Received 159 bytes from 117.89.178.52#53(ns4.dnsv5.com) in 42 ms
# 最终由权威服务器(腾讯云 DNSPod)返回该域名对应的 A 记录(IPv4 地址列表)及 TTL 值,并完成解析。

抓包观察重点:

  • 端口:DNS 默认运行在 UDP 53 端口(为了追求速度,一次查询通常只有一发一收)。
  • 包结构
    • Question:我要找谁(域名、类型)。
    • Answer:对应的 IP 地址。
    • Authority/Additional:权威服务器信息。
Terminal window
tshark -i eth0 -f "udp port 53" -w output.pcap # eth0 替换为你的网卡
nslookup bilibili.com
ping -c 1 bilibili.com
dig bilibili.com +trace
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| Transaction ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| Questions Count |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| Answer RRs |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

核心字段解析:

  • Transaction ID:客户端随机生成,服务端原样返回,用于匹配“哪一个回答对应哪一个问题”。
  • QR(Query/Response)0 代表这是查询包,1 代表这是响应包。
  • TC(Truncated):也就是上文提到的截断标志位。
  • RCODE:返回码。如果是 0 代表成功;如果是 3 代表 NXDOMAIN(域名不存在)。

5. 常见的 DNS 记录类型#

理解以下记录,你就看懂了域名背后的业务逻辑:

  • A(Address):最核心的记录,将域名指向一个 IPv4 地址。
  • AAAA:将域名指向一个 IPv6 地址。
  • CNAME(Canonical Name):别名记录,将一个域名指向另一个域名(CDN 厂商最常用的引流手段,如你的域名 CNAME 到阿里的节点域名)。
  • MX(Mail Exchange):指定邮件服务器的地址,如果别人给你发邮件,SMTP 协议就是靠它找到你公司的邮件服务器。
  • TXT:记录任意文本信息,常用于域名所有权验证或防伪验证(如 SPF/DKIM 的邮件防伪标识)。

6. 现代 DNS 的痛点与演进(劫持 vs 污染)#

DNS 设计于 1983 年,由于 UDP 明文传输的特性,它在复杂的现代网络中面临着严峻的安全挑战。很多人分不清“劫持”和“污染”,这里用通俗的语言解释:

  1. DNS 劫持 (Hijacking)
    • 原理:你的 Local DNS 变成了别人的恶意DNS。收到你的正确请求后,故意给你返回一个错误的 IP(比如把你导向满屏广告的网页,或者钓鱼网站)。
    • 现象:输错网址时弹出的运营商导航页,就是最典型的劫持。
  2. DNS 污染 / 缓存投毒 (Poisoning)
    • 原理:因为 UDP 是无连接的,谁先返回数据,客户端就信谁。攻击者并不用控制你的 DNS 服务器,但他一直在网络链路上监听。当你发出查询时,攻击者赶在真正的服务器响应前,抢先伪造一个包含错误 IP 的响应包发给你。你的系统收下这个错误结果后,真正的包裹哪怕晚到了0.1秒,也会被直接丢弃。
    • 现象:通常被用于实现国家级防火墙拦截,或者局域网恶意的中间人攻击。
  3. 缺乏加密:你的每一次上网请求,ISP 都能一清二楚地看到。

下一代安全与隐私解决方案:#

为了解决明文和伪造问题,现代 DNS 正在进行加密演进:

  • DNSSEC(DNS Security Extensions):对 DNS 记录进行非对称加密数字签名,客户端收到结果后可以验证“这到底是不是权威服务器发出的原始数据”,完美防篡改(防DNS污染)。
  • DoH(DNS over HTTPS):将 DNS 查询包装在 HTTPS 流量中(端口 443)。在运营商看来,你只是在访问一个普通的加密网页,它不仅无法篡改,连你在查询什么域名都无法知晓,极大保护了用户隐私。
  • DoT(DNS over TLS):通过专门的 TLS 协议通道加密 DNS 数据(端口 853)。

7. 经典排障#

  1. 你的电脑突然打不开任何网页了,但QQ却依然能正常收发消息。这是为什么?
  • 网页浏览器的逻辑:浏览器极度依赖 DNS。当你在地址栏输入 www.bilibili.com 时,浏览器必须先向本地配置的 DNS 服务器询问该域名对应的 IP,拿到 IP 后才能建立 TCP 连接。如果你的 DNS 配置错误或者运营商的 DNS 服务器宕机,解析就会失败,网页自然打不开。
  • QQ的逻辑:这类客户端在软件内部硬编码(Hardcode)了一批核心业务服务器的IP地址列表。即使系统 DNS 彻底瘫痪,客户端依然可以直接通过这些内置的 IP 发起通信。 结论:这个现象是典型的 DNS 解析故障。解决办法通常是检查网卡设置,将 DNS 修改为公共 DNS(如 114.114.114.1148.8.8.8),或者检查本地的 hosts 文件是否被篡改。
DNS 协议解析
https://blog.alinche.dpdns.org/posts/net/dns/
作者
Oeasy1412
发布于
2026-03-20
许可协议
CC BY-NC-SA 4.0