Skip to content
Go back

DNS域名解析——从输入URL到返回IP的完整链路

DNS:互联网最被忽视的关键基础设施

一句话结论(30s)

DNS 是互联网的分布式树状「电话簿」,把人类可读的域名翻译成机器可路由的 IP;因为它是分布式分级数据库 + 多级缓存(浏览器 → hosts → 本地 DNS → 权威服务器),所以 90%+ 的查询在本地网内完成、根服务器只处理极小比例——但这也意味着它一旦被劫持或故障,整个互联网就会「消失」而不是「变慢」。

核心原理(2min)

底层深入(5-10min)

DNS 是什么

DNS(Domain Name System)是互联网的”电话簿”——把人类可读的域名(如 www.example.com)翻译成机器可路由的 IP 地址(如 93.184.216.34)。它是一个分布式、分级的数据库系统

域名空间的树状结构

                        . (根)
          ┌───────────────┼───────────────┐
         com              org             cn
    ┌─────┴─────┐         ...             ...
  example    google

   www (A记录 → 93.184.216.34)

每个节点由一个或多个权威 DNS 服务器管理。.com 的权威服务器只认 example.com 的 NS 记录是谁,不存 www.example.com 的具体 A 记录。

思考:为什么 DNS 要设计成「分布式树状」而不是一张大表?因为一张全球集中大表既不现实也不可靠——数十亿域名、每秒上亿次查询,任何单点都扛不住,还会成为唯一故障点。树状分级让每个层级只负责自己的「下一跳」:根只指路到 TLD,TLD 只指路到权威,权威才管具体的 A 记录;责任分散、可横向扩展,任何一层挂了也只影响自己管辖的范围。

完整查询链路

当浏览器请求 www.example.com

1. 浏览器 DNS 缓存 → 命中?直接返回
2. hosts 文件 → 有配置?直接返回
3. 向本地 DNS 服务器(由 DHCP 配置,如 8.8.8.8)发起递归查询:
   a. 本地 DNS → 根域名服务器: "www.example.com 的 IP?"
      根: "不知道,但 .com 的权威 DNS 在 ns1.com (IP: x.x.x.x)"
   b. 本地 DNS → ns1.com: "www.example.com 的 IP?"
      ns1.com: "不知道,但 example.com 的权威 DNS 在 ns1.example.com (IP: y.y.y.y)"
   c. 本地 DNS → ns1.example.com: "www.example.com 的 IP?"
      ns1.example.com: "A 记录是 93.184.216.34"
4. 本地 DNS 缓存结果(TTL 秒),返回给浏览器

这就是递归查询——本地 DNS 服务器代表客户端逐级查找,客户端只发出一份请求、等待一份响应。

思考:为什么一次 www.example.com 解析要「逐级问」而不是一次直达?因为没有任何一个服务器知道全量答案,只知道「谁负责下一级」的索引。本地 DNS 代表客户端一层层问下去,客户端只发一份请求、等一份响应——把复杂度留给本地 DNS,把简单留给客户端。再叠加多级缓存,90%+ 的查询根本到不了根服务器。

TTL 的意义

每条 DNS 记录有 TTL(Time To Live),告诉各级缓存这条记录可以存活多久。CDN 利用短 TTL(几十秒)实现快速切换 IP 做故障转移;静态网站用长 TTL(几小时甚至几天)减少 DNS 查询次数。

思考:TTL 长好还是短好?没有绝对答案,取决于「变更频率 vs 查询成本」的权衡。CDN 要快速切 IP 做故障转移,短 TTL 让变更尽快生效;静态站 IP 几乎不变,长 TTL 减少查询、降低延迟。所以 TTL 本质是「缓存的保鲜期」——越短越新鲜但查询越频繁,越长越省但越难更新。

DNS 劫持

攻击者篡改 DNS 响应,将域名解析到恶意 IP,用户访问正常域名却被带到钓鱼/恶意站点。

常见劫持手段

  1. 运营商劫持:修改 DNS 服务器返回虚假 IP,插入广告或劫持流量
  2. 路由器劫持:修改路由器的 DNS 配置指向恶意 DNS 服务器
  3. 本地 hosts 劫持:在用户机器上修改 hosts 文件

防御方案

思考:为什么 DNS 这么容易被劫持,根源在哪?因为传统 DNS 是明文 + 无身份验证的——查询和响应都不签名、不加密,任何中间节点都能篡改或伪造。DNSSEC 解决「内容是否被篡改」(数字签名),DoH/DoT 解决「传输是否被偷看和替换」(加密通道),两者一个保真、一个保密,缺一不可。

为什么 DNS 用 UDP?

DNS 的查询通常 < 512 字节(一个域名 + 一个请求类型),响应也很小。UDP 无连接的”一次请求一次响应”模型刚好匹配 DNS 的请求模式,避免了 TCP 三次握手的额外延迟。

超过 512 字节的响应(如 DNSSEC 签名链、区域传输)则用 TCP 53 端口。

思考:为什么 DNS 偏偏用不可靠的 UDP?因为 DNS 的请求模型是「一问一答、数据极小」,UDP 的无连接模型恰好匹配:省掉三次握手和连接维护,一次往返就完成;可靠性由「重试」兜底——丢了就重发一次,比建立 TCP 连接更快。只有当响应超过 512 字节(DNSSEC、区域传输)时,才退回到可靠的 TCP。

总结

DNS 是互联网最被忽视的关键基础设施——它出问题时,不是”慢”,是整个互联网”消失了”。分布式树状结构让它支撑了全球数十亿域名的解析,多级缓存让 90%+ 的查询在本地网内完成,根服务器只处理极小比例的查询。

章末提问

Q1:DNS 解析的完整过程是怎样的?

结论先行:浏览器缓存 → hosts → 本地 DNS 递归查询根 → TLD → 权威服务器逐级查找,最终拿到 A 记录返回。因为没有任何单一服务器知道全量答案,本地 DNS 代表客户端一层层问「谁负责下一级」;多级缓存命中则提前返回,90%+ 的查询在本地完成,根服务器只处理极小比例。

Q2:为什么 DNS 用 UDP 而不是 TCP?

结论先行:因为 DNS 查询通常 < 512 字节、一问一答,UDP 无连接模型恰好匹配、省三次握手、一次往返完成。因为建 TCP 连接的握手和状态维护对「极小的一次性查询」是纯开销,UDP 的不可靠由应用层重试兜底;只有超大响应(DNSSEC、区域传输)才用 TCP 53。

Q3:递归查询和迭代查询的区别是什么?

结论先行:递归查询 = 本地 DNS 替客户端跑完整条链路、返回最终结果;迭代查询 = 每次只返回「下一步该问谁」的指引,客户端自己接着问。因为递归把复杂度集中到本地 DNS、对客户端简单友好(只发一份请求等一份响应),迭代则把逐级查询的负担留给客户端;实际中客户端到本地 DNS 是递归,本地 DNS 向上到根/TLD/权威多为迭代。

Q4:DNS 劫持有哪些手段?怎么防御?

结论先行:常见手段是运营商劫持、路由器劫持、本地 hosts 劫持;防御靠 DNSSEC 签名 + DoH/DoT 加密。因为传统 DNS 明文且无身份验证,中间节点可随意篡改;DNSSEC 用数字签名保证响应未被篡改(保真),DoH/DoT 走加密通道保证内容不被偷看替换(保密),两者一真一密配合防御。

Q5:TTL 在 DNS 里起什么作用?为什么 CDN 用短 TTL?

结论先行:TTL 是各层缓存的「保鲜期」,控制记录被缓存多久;CDN 用短 TTL 是为了快速切换 IP 做故障转移。因为 TTL 是变更频率与查询成本之间的权衡——短 TTL 让新 IP 尽快生效(几十秒内全网更新),代价是查询更频繁;静态站 IP 不变,用长 TTL 减少查询、降低延迟。


Share this post on:

Previous Post
HTTP vs RPC:两种服务间通信协议的全面对比
Next Post
DNS over TCP vs UDP:为什么域名解析默认走UDP