写在前面
前面九篇把物理、链路、网络、传输四层讲透了:网线上的比特怎么成帧、IP 怎么跨网路由、TCP 怎么保证可靠、UDP 怎么图快。从这一篇开始,我们登上最高层——应用层。
应用层的协议很多(HTTP、SMTP、SSH、FTP……),但几乎每一个都绕不开同一个前置动作:拿到目标机器的 IP。用户记不住 93.184.216.34,只记得 example.com;而 IP 可能因为换机房、换云厂商而变。这套"域名 ↔ IP"的翻译系统,就是 DNS(Domain Name System)。它既是应用层协议,又是一个遍布全球的分布式数据库——这一篇就把它讲透。
一、为什么需要 DNS
先想一个没有 DNS 的世界:你想上网,就得在浏览器里敲一串 IP;服务换了 IP,得挨个通知所有用户。这显然不可行。DNS 解决三件事:
- 人友好 ——
www.example.com比93.184.216.34好记; - 解耦 —— 域名稳定,IP 可变,迁移机器只改 DNS 记录,用户无感;
- 负载与高可用 —— 一个域名可以映射到多台机器,DNS 轮询 / 智能调度都能在域名这一层做。
一句话:DNS 是互联网的"通讯录",把人用的名字翻译成网络层要的 IP 。
二、DNS 的层级结构:一棵全球共享的树
DNS 不是一个巨型数据库(单点会压垮、会被攻击、政治上也不可接受),而是按域名分段、层层授权的分布式数据库。域名的每一个点分隔一段,对应树上的一层:
| |
每一层由不同的服务器群体负责:
| 层级 | 服务器 | 职责 |
|---|---|---|
| 根域 | 根服务器(13 组逻辑实例,用 anycast 扩到上千台) | 告诉你各 TLD(.com / .org / .cn …)由谁管 |
| 顶级域 TLD | TLD 服务器(由注册局运营,如 Verisign 管 .com) | 告诉你 example.com 这类二级域由谁权威 |
| 权威域 | 权威服务器(域名所有者自建或托管) | 给出本域名的最终记录(A / AAAA / MX …) |
“13 台根服务器” 是历史限制——受早期 DNS 报文能塞进的 13 个地址约束。今天靠 anycast,这 13 个标签背后是全球几百个站点、几千台机器,任播让请求自动落到最近的一台。
授权 是这套树能扩展开的关键:根只管到 TLD,TLD 只管到二级域,二级域再往下可以继续授权(子域委托)。没有任何一台服务器需要知道全部答案,每台只负责自己那一段、并知道"再往下该问谁"。
三、解析流程:一次完整查询走了多远
假设浏览器要访问 www.example.com,完整流程是这样的:
| |
几个工程要点:
- hosts 文件优先 —— 这就是为什么改 hosts 能"劫持"域名做本地调试,也常被恶意软件篡改。
- 递归解析器做了绝大多数工作 —— 客户端只问它一次,它要自己去跑 (3)(4)(5) 这条链路。常见的
8.8.8.8(Google)、1.1.1.1(Cloudflare)、223.5.5.5(阿里)就是公共递归解析器。 - 缓存显著减少权威查询 —— 日常查询往往在浏览器、操作系统或递归解析器命中;递归解析器还会缓存从根 / TLD 获得的委派信息,因此很多查询不必再次访问根服务器。根、TLD、权威服务器并不是把请求逐级转发并各自缓存最终答案的“链路节点”。
四、递归查询 vs 迭代查询
这两个词在书里经常并列出现,混淆点在于"谁负责追到底":
| 模式 | 谁干活 | 谁返回最终答案 | 在 DNS 里出现在哪 |
|---|---|---|---|
| 递归查询 (recursive) | 被问的人去追完整条链路 | 被问的人 | 客户端 → 递归解析器 |
| 迭代查询 (iterative) | 问的人自己一级级往下追,被问的只给"下一步去问谁" | 问的人自己 | 递归解析器 → 根/TLD/权威 |
所以一次解析其实是 “客户端对解析器递归,解析器对权威链路迭代” 的组合。解析器拿到客户端的递归请求后,自己变成那个一级级追问的人(迭代),最终把答案递归地交回给客户端。
一套 DNS 软件甚至同一台机器可以同时承担权威和递归角色,但生产环境通常会分离职责并严格限制递归访问。公网权威服务一般不为任意客户端递归查询;递归解析器则代表获准客户端向权威体系发起非递归查询。若把递归能力无访问控制地暴露到公网,就可能成为开放解析器并被滥用于 DNS 放大攻击。
五、DNS 记录类型:不只是 IP
DNS 存的远不止"域名 → IP"一种映射,而是一张张资源记录(Resource Record, RR)。每条记录都有类型、域名、值和 TTL。常见类型:
| 类型 | 全称 | 作用 | 示例 |
|---|---|---|---|
| A | Address | 域名 → IPv4 地址 | www.example.com. IN A 93.184.216.34 |
| AAAA | IPv6 Address | 域名 → IPv6 地址(四个 A,因为 IPv6 地址是 IPv4 的四倍长) | www.example.com. IN AAAA 2606:2800:220:1:... |
| CNAME | Canonical Name | 别名,把一个域名指向另一个域名(常用于 CDN / 别名) | blog.example.com. IN CNAME example.github.io. |
| MX | Mail Exchange | 收邮件的服务器,带优先级(数字越小越优先) | example.com. IN MX 10 mail.example.com. |
| NS | Name Server | 这个域由哪台权威服务器管 | example.com. IN NS ns1.example.com. |
| TXT | Text | 任意文本,常用于域名所有权验证、SPF / DKIM / DMARC 防伪造 | example.com. IN TXT "v=spf1 -all" |
| SOA | Start of Authority | 一个区的权威元信息:主服务器、管理员邮箱、序列号、刷新/重试/过期时间、最小 TTL | 每个 zone 必有一条 |
几个容易踩的细节:
- CNAME 不能和其他记录共存 —— 同一域名要么是别名(CNAME),要么有自己的 A / MX 等记录,不能既要又要;根域(zone apex,如
example.com本身)尤其不能用 CNAME,这就是所谓的 CNAME flattening / ANAME / ALIAS 记录要解决的问题。 - MX 的优先级 —— 数字小者优先。同等优先级的两条 MX,收件方会随机挑,可做简单负载均衡。
- NS 决定授权边界 —— 子域一旦在父域里写了 NS 记录,就等于把该子域委托 出去,之后父域不再回答它的细节。
六、缓存与 TTL:为什么改了 DNS 不立刻生效
DNS 能扛住全球规模,缓存功不可没。最终答案可能被浏览器、操作系统和递归解析器缓存;递归解析器还会缓存 NS、A / AAAA 等委派相关信息:
| |
每条缓存能留多久,由记录的 TTL(Time To Live,秒) 决定。TTL 是域名所有者在权威服务器上设的"建议保质期"。
这就解释了 DNS 改动的一个经典坑:改完记录,总有部分用户还在访问老 IP。 因为各级缓存里的老记录要等自己的 TTL 到期才会刷新,而不同用户命中的递归解析器各不相同、缓存剩余时间也不同。所以线上切换 IP 之前,业内惯用做法是:
- 提前把 TTL 调小(比如从 3600s 降到 60s),等一个旧 TTL 周期过去;
- 再做 IP 切换,这样最多 60s 内全网收敛;
- 切稳之后再把 TTL 调回大值(减少查询压力)。
TTL 是个权衡:大 TTL 省查询、抗 DNS 抖动,但切换慢;小 TTL 切换快,但查询量大、对权威压力高 。CDN / 高频切换场景常用几十秒;稳定服务常用小时级。
七、安全与隐私:DNSSEC、DoH、DoT
传统 DNS 有两个先天缺陷:
- 明文传输 —— 查询走 UDP 53(或 TCP 53),链路上任何人都能看到你查了什么域名,甚至篡改返回的 IP;
- 无身份校验 —— 解析器拿到一个 IP,无法验证它是不是权威真正签发的,中间人塞个假 IP 你也信。
两套机制分别补这两个洞,别混为一谈:
| 机制 | 解决什么 | 怎么做 | 端口 |
|---|---|---|---|
| DNSSEC | 数据真实性与完整性(防篡改、防伪造) | 对每条记录加密码学签名,解析器沿信任链验证签名 | 53(不改传输) |
| DoT(DNS over TLS) | 传输加密(防窃听) | 用 TLS 包裹 DNS 查询 | 853 |
| DoH(DNS over HTTPS) | 传输加密 + 混在 HTTPS 流量里(更难与普通 HTTPS 区分) | 用 HTTPS 传 DNS 报文,可承载于 HTTP/2 或 HTTP/3 等版本 | 443 |
关键区分:DNSSEC 签的是"数据对不对",DoT / DoH 加密的是"传的过程看不看得到" 。两者正交,可以同时用(DoH + DNSSEC 验证)。DNSSEC 不提供机密性——签名让数据可被验证,但查询内容依旧明文;DoT / DoH 提供机密性,但如果上游解析器作恶,它返回的假 IP 你没法自己验(所以有人坚持要在客户端做 DNSSEC 验证)。
一个现实工程点:用了 DoH / DoT 之后,企业内网的 DNS 过滤、家长的域名黑白名单都会失效——因为查询绕过了本地解析器直接走加密通道去公网解析器了。这是"隐私"和"可控"的天然张力。
八、动手验证:dig 与 nslookup
讲了一堆原理,落到命令上最直观。dig(Linux/macOS 自带,Windows 可装 BIND 工具)和 nslookup(全平台自带)是最常用的两个:
| |
dig +trace 是理解第二节那棵树最好的工具——它会依次打印根、TLD、权威的应答,把整条授权链摆给你看。排 DNS 问题时,先用 dig 看记录对不对,再看是不是缓存(换个解析器 @1.1.1.1 对比),最后用 +trace 看授权链有没有配错。
小结
- DNS 是应用层的分布式数据库,按域名分段、层层授权,没有任何一台服务器需要知道全部答案;
- 一次解析通常是 “客户端请求递归解析器、解析器逐级查询权威体系” 的组合;客户端、本机和递归解析器可按 TTL 缓存结果,解析器也会缓存委派信息;
- 记录类型不只是 A/AAAA——CNAME 别名、MX 带优先级的邮件、NS 决定授权边界、TXT 承载验证信息、SOA 是区的元信息;
- 改 DNS 不立刻生效 是各级 TTL 缓存的必然结果,切换前先调小 TTL 是标准做法;
- DNSSEC 防篡改(签名),DoT / DoH 防窃听(加密) ,两者正交、可叠加。
下一篇:TCP/IP(十一):HTTP、HTTPS 与 TLS —— 拿到 IP 之后,浏览器怎么建连、发请求、传页面;HTTP 从 1.0 到 3 演进了什么;HTTPS 套的那层 TLS 又是怎么握手的。
参考: