1 介绍

域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务。

它本质上是一个分布式数据库,通过 UDP 端口 53 提供服务。

为了保证系统的稳定性与规范性,DNS 对域名长度有严格限制:

  • 每一级域名(Label)最长为 63 个字符。

  • 域名总长度不得超过 253 个字符。

接下来,我们将通过一个实战案例,利用经典的 dig 工具来拆解一次完整的 DNS 查询过程。

2 DNS 实战拆解:解析 linjhs.top

假设我们在终端输入以下命令,向 Google 的公共 DNS 服务器(8.8.8.8)发起查询:

$ dig linjhs.top @8.8.8.8

你将得到如下反馈。我们将这段返回信息拆分为五个核心部分进行逐一解析。

; <<>> DiG 9.18.12-0ubuntu0.22.04.1-Ubuntu <<>> linjhs.top @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30977
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 4e2528dde14cfd1701000000694212d858c35ca01d4471b2 (good)
;; QUESTION SECTION:
;linjhs.top.                    IN      A

;; ANSWER SECTION:
linjhs.top.             281     IN      A       140.143.140.6

;; Query time: 0 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; WHEN: Wed Dec 17 10:18:00 CST 2025
;; MSG SIZE  rcvd: 83

2.1 报头与状态统计(Header Section)

这是 DNS 响应的第一部分,告诉我们查询的基本结果和状态。

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30977
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
  • opcode: 操作码。QUERY 表示这是一个标准查询。

  • status: 响应状态。NOERROR 表示查询成功;如果是 NXDOMAIN 则表示域名不存在。

  • id: 随机序列号,用于匹配请求和响应。

  • flags: 标志位。

    • qr (Query/Response): 代表这是一个响应。

    • rd (Recursion Desired): 客户端希望进行递归查询。

    • ra (Recursion Available): 服务器表示支持递归查询。

  • 计数器: 显示了后面各个部分的记录条数(例如 ANSWER: 1 表示有一个答案)。

2.2 伪指令与查询内容(Pseudo & Question Section)

在正式回答之前,协议会列出本次查询的具体参数。

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 4e2528dde14cfd1701000000694212d858c35ca01d4471b2 (good)

;; QUESTION SECTION:
;linjhs.top.                    IN      A
  • OPT PSEUDOSECTION: 这是扩展 DNS(EDNS)机制,允许传输更大的 UDP 数据包(此处为 1232 字节)并包含安全 COOKIE。

  • QUESTION SECTION: 确认查询的具体内容。

    • linjhs.top.: 查询的域名。

    • IN: 表示 Internet 类别。

    • A: 表示我们正在查询 A 记录(即寻找 IPv4 地址)。

2.3 核心答复部分(Answer Section)

这是我们最关心的部分,即查询的最终结果。

;; ANSWER SECTION:
linjhs.top.             281     IN      A       140.143.140.6
  • 281: 这是 TTL (Time to Live),表示这条记录在缓存中还可以保留 281 秒。

  • 140.143.140.6: 这就是 linjhs.top 对应的真实服务器 IP 地址。

2.4 权威与辅助信息(Authority & Additional Section)

有时,DNS 服务器不仅会给你 IP,还会告诉你“谁负责管理这个域名”以及“这些管理者的 IP 是多少”。

2.4.1 权威部分 (Authority)

如果 DNS 响应中没有直接给出 A 记录,或者为了展示完整的授权链,会显示 NS (Name Server) 记录:

;; AUTHORITY SECTION:
stackexchange.com.    171469  IN      NS      ns-1832.awsdns-37.c0.uk.
...(略)

这表示 stackexchange.com 的解析由这些指定的权威域名服务器负责。

2.4.2 额外部分 (Additional)

为了提高效率,防止你再去查一遍 NS 服务器的 IP,服务器会在额外部分直接给出这些 NS 服务器的 IP 地址:

;; ADDITIONAL SECTION:
ns-463.awsdns-57.com.    171406  IN      A       205.251.193.207
...(略)

2.5 传输与性能元数据

最后,dig 会汇总本次网络请求的消耗情况。

;; Query time: 0 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; WHEN: Wed Dec 17 10:18:00 CST 2025
;; MSG SIZE  rcvd: 83
  • Query time: 查询耗时(此处 0 msec 说明命中本地或近端缓存)。

  • SERVER: 响应服务器的 IP 和端口。

  • WHEN: 请求发生的具体时间。

  • MSG SIZE: 接收到的报文总大小(83 字节)。

3 递归与迭代:DNS 的两副面孔

在上一章中,我们通过 dig linjhs.top 得到了最终的 IP 地址。但在幕后,这个结果并非一蹴而就。为了弄清楚 DNS 服务器之间是如何“对话”的,我们需要引入两个核心概念:递归查询(Recursive Query)与迭代查询(Iterative Query)

为了更直观地观察这个过程,我们使用 dig +trace linjhs.top 命令来模拟一个递归服务器的工作路径。

3.1 实战:追踪一次完整的迭代过程

当你执行 +trace 时,dig 不再直接向你的本地 DNS 服务器要答案,而是从全球 DNS 树的顶端——根服务器开始,一步步向下走。

$ dig +trace linjhs.top
; <<>> DiG 9.18.39-0ubuntu0.24.04.2-Ubuntu <<>> +trace linjhs.top
;; global options: +cmd
.                       9       IN      NS      d.root-servers.net.
.                       9       IN      NS      c.root-servers.net.
.                       9       IN      NS      k.root-servers.net.
.                       9       IN      NS      g.root-servers.net.
.                       9       IN      NS      m.root-servers.net.
.                       9       IN      NS      f.root-servers.net.
.                       9       IN      NS      h.root-servers.net.
.                       9       IN      NS      e.root-servers.net.
.                       9       IN      NS      i.root-servers.net.
.                       9       IN      NS      l.root-servers.net.
.                       9       IN      NS      b.root-servers.net.
.                       9       IN      NS      j.root-servers.net.
.                       9       IN      NS      a.root-servers.net.
;; Received 239 bytes from 127.0.0.53#53(127.0.0.53) in 1 ms

top.                    172800  IN      NS      a.zdnscloud.cn.
top.                    172800  IN      NS      b.zdnscloud.cn.
top.                    172800  IN      NS      c.zdnscloud.com.
top.                    172800  IN      NS      d.zdnscloud.com.
top.                    172800  IN      NS      f.zdnscloud.cn.
top.                    172800  IN      NS      g.zdnscloud.com.
top.                    172800  IN      NS      i.zdnscloud.cn.
top.                    172800  IN      NS      j.zdnscloud.com.
top.                    86400   IN      DS      26780 8 2 5D6E7869EE8E3B536A617DE89482DDD1DCB9DB9DBB1AC33D6ED351E2 CA095B1B
top.                    86400   IN      RRSIG   DS 8 1 86400 20260106050000 20251224040000 61809 . WF1UjdRi9CmwzQLscR2QhNScOzUN63gLFKJrgDYD6OxJ+atcYELi36rl bYp/CrqmL9GaKwM99rzgcNPQC3zc3c2cVLBE/+cIZS3GWwP1DNLW8/KN JhVO/L48AZxzv/I6EXD/tHDsq+0ZN1a/PomMwWpBm9XrNRCihVSfexHQ +JC1m+5Z2HxOzTj+6qY38AdlNVXn5EqyR+vgaRpMdlZpzfiZRKDPH+G+ U0Xkf8ZRYvi2apzPWS/Fr+vr9PuVFgyJ0yPRo52FoZVPQnIUq2iuZRDT oiAMpHjGPpvB93xGSYQu4nJ0xJOmRvb6WvWBhHzkK5cfL4ZMnXZuBz3G 1Iy1jQ==
;; Received 729 bytes from 199.7.83.42#53(l.root-servers.net) in 3 ms

;; UDP setup with 2401:8d00:2::1#53(2401:8d00:2::1) for linjhs.top failed: network unreachable.
;; no servers could be reached
;; UDP setup with 2401:8d00:2::1#53(2401:8d00:2::1) for linjhs.top failed: network unreachable.
;; no servers could be reached
;; UDP setup with 2401:8d00:2::1#53(2401:8d00:2::1) for linjhs.top failed: network unreachable.
linjhs.top.             3600    IN      NS      dns17.hichina.com.
linjhs.top.             3600    IN      NS      dns18.hichina.com.
uuot5k8vj2lohe3gl3f0id99qtfp555l.top. 3600 IN NSEC3 1 0 0 - UUOT65QSRA1D3732CRD2BH5RJR94MDEF NS
uuot5k8vj2lohe3gl3f0id99qtfp555l.top. 3600 IN RRSIG NSEC3 8 2 3600 20260107032616 20251224015616 57763 top. P8boqoScH5mbhNX/lHKv4N3rfjKxA8kR3qlq4A7qX73+wPBnM1LrBre4 hpnf0jdMuOkc/CQxFqncg5ntOZiaj/saZ3CPVVIx3ZGpL+d7OgTK1AYY j+hY5KOpPlGhvXOrcyiPDPataSGUdAkxOJCkX9OllwGhgT9qRIMUJrGB fGY=
;; Received 327 bytes from 203.99.24.1#53(a.zdnscloud.cn) in 220 ms

linjhs.top.             600     IN      A       140.143.140.6
;; Received 55 bytes from 139.224.142.98#53(dns18.hichina.com) in 28 ms

3.1.1 第一阶段:问候“根服务器” (Root Section)

.                       9       IN      NS      d.root-servers.net.
... (此处省略其他 12 组根服务器)
;; Received 239 bytes from 127.0.0.53#53(127.0.0.53) in 1 ms

这是逻辑的起点。根服务器(用 . 表示)不会告诉你 linjhs.top 的 IP,它只会告诉你:“关于 .top 后缀的域名,请去问顶级域名服务器(TLD)。”

3.1.2 第二阶段:进入“顶级域名” (.top Section)

top.                    172800  IN      NS      a.zdnscloud.cn.
top.                    86400   IN      DS      26780 8 2 5D6E7869EE8E3B...
top.                    86400   IN      RRSIG   DS 8 1 86400 20260106...
;; Received 729 bytes from 199.7.83.42#53(l.root-servers.net) in 3 ms

在这里,我们从根服务器 l.root-servers.net 拿到了负责管理 .top 的服务器列表。你会注意到这里出现了几个新面孔:

  • DS (Delegation Signer):这是域名系统安全扩展(DNSSEC)的一部分,用于验证下一级区域的公钥哈希,确保解析过程没有被篡改。

  • RRSIG (Resource Record Signature):这是对记录的数字签名。它证明了这条 DNS 信息确实是由权威机构发布的。

3.1.3 第三阶段:寻找“权威服务器” (Authoritative Section)

linjhs.top.             3600    IN      NS      dns17.hichina.com.
linjhs.top.             3600    IN      NS      dns18.hichina.com.
uuot5k8vj2lohe...top.   3600    IN      NSEC3   1 0 0 - UUOT65QSRA...
;; Received 327 bytes from 203.99.24.1#53(a.zdnscloud.cn) in 220 ms

.top 的服务器(a.zdnscloud.cn)告诉我们:linjhs.top 的具体记录托管在万网的服务器上。

  • NSEC3:这是另一种 DNSSEC 记录,用于安全地证明某个子域名“不存在”,防止攻击者通过遍历域名来探测你的主机列表。

3.1.4 第四阶段:拿到最终答案

linjhs.top.             600     IN      A       140.143.140.6
;; Received 55 bytes from 139.224.142.98#53(dns18.hichina.com) in 28 ms

最后,我们向 dns18.hichina.com 发起询问,它作为权威服务器,终于给出了我们苦苦寻找的 A 记录

3.2 深度对比:递归 vs. 迭代

通过上面的追踪,我们可以清晰地定义这两者的区别:

维度

递归查询 (Recursive)

迭代查询 (Iterative)

查询主体

客户端(如你的 PC)与 本地 DNS。

本地 DNS 与 全球各级权威 DNS。

服务器响应

必须返回最终结果(IP 或 报错)。

返回“我不知道,但你可以去问那台服务器”。

优势

节省客户端带宽,逻辑简单。

降低根服务器压力,实现分布式架构。

3.3 专家视角:日志中的“杂音”

在你的 trace 日志中,可能会看到类似 UDP setup... network unreachable 的提示。作为专家,我们需要明白:

  1. 协议回退:现代 DNS 尝试同时使用 IPv6 和 IPv4。如果你的网络不支持 IPv6,你会看到 network unreachable,随后 dig 会自动切换到 IPv4 继续查询。

  2. UDP 与 TCP:DNS 默认使用 UDP。但如果返回的数据包太大(超过了 EDNS 指定的 1232 字节),它会自动切换到 TCP 端口 53 以保证数据的完整性。

总结:递归查询是用户感受到的“便捷”,而迭代查询则是互联网骨干运作的“逻辑”。正是这种层层授权、逐级指引的机制,才让 DNS 成为了支撑全球互联网而不崩溃的基石。

4 时间的艺术:揭秘 DNS 缓存与 TTL

在前面的章节中,我们见证了 DNS 如何通过“递归”和“迭代”在全球范围内的服务器间奔走,最终锁定 140.143.140.6 这个 IP。然而,如果每一次访问网页都要经历这种“全球长跑”,互联网的响应速度将无法忍受。

这就是 DNS 缓存(DNS Caching) 大显身手的地方。它让 DNS 解析从“秒级”提升到了“毫秒级”。

4.1 核心字段:TTL(生存时间)

在第一章的 dig 案例中,我们曾看到这样一个细节:

;; ANSWER SECTION:
linjhs.top.             281     IN      A       140.143.140.6

请关注数字 281。这就是该记录的 TTL (Time to Live),单位为秒。

  • 含义:它告诉缓存服务器(如运营商的 DNS 或你的路由器),这条记录可以在你的内存里存放多久。

  • 动态变化:如果你在 10 秒后再执行一次 dig,你会发现这个数字变成了 271。当它倒计时归零时,缓存失效,系统必须重新发起一次完整的迭代查询。

4.2 缓存的“五重奏”:查询去哪儿了?

DNS 缓存并不是存在于某一个地方,而是分布在从你的指尖到目标服务器的整个路径上。当你在浏览器输入域名时,查询会按以下顺序“撞”缓存:

缓存层级

所在位置

说明

浏览器缓存

Chrome, Firefox 等浏览器内部

浏览器会缓存最近访问过的域名,通常只有几分钟。

操作系统缓存

Windows (DNS Client 服务), macOS, Linux

系统内核维护的缓存。你可以通过命令手动刷新。

路由器缓存

你的家用网关/路由器

路由器通常充当第一级 DNS 代理,也会保留一份副本。

ISP (递归解析器) 缓存

运营商 DNS (如 114.114.114.114)

这是最强大的缓存层,服务于成千上万的用户。

权威服务器缓存

托管域名的云服务商

虽然它们是源头,但在分布式架构(如 Anycast)下也存在内部缓存。

4.3 为什么“修改解析后不生效”?

作为开发者或运维专家,最常遇到的问题是:“我已经在后台把域名指向了新 IP,为什么我访问的还是旧页面?”

这就是 DNS 传播(DNS Propagation) 的延迟问题,本质上是各级缓存尚未到期。

  • 假设 TTL 设为 86400(24小时):这意味着全球范围内的 ISP 缓存可能需要长达一天的时间才会去拉取你的新 IP。

  • 最佳实践:如果你计划迁移服务器,请务必提前一天将 TTL 调小(例如设为 600 秒)。待迁移完成并稳定后,再将其调回正常值。

4.4 总结

DNS 缓存是互联网性能的基石。它通过牺牲一定的“实时性”,换取了极高的“响应性”。理解了 TTL 和各级缓存的运作逻辑,你就掌握了排查 90% 网络访问故障的钥匙。