Computer NetworkNotes

第 13 章:DNS

zjc 于 2026-01-13 发布

这是《计算机网络 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 DNS 把人类可读的域名转换为 IP 地址,是每一次外部访问的第一跳。它看似简单,实际是一个分层、缓存、可委托的全球分布式系统。DNS 解析失败、TTL 过长、地域调度错误或解析超时,都会直接影响可用性。

13.1 域名结构

www.example.com.
 |     |      |
 |     |      +-- TLD
 |     +--------- Second Level
 +--------------- Subdomain

末尾的 . 表示 DNS 根,日常输入时通常省略。

解析层级:

Stub Resolver
  -> Recursive Resolver
     -> Root
     -> TLD
     -> Authoritative DNS

13.2 递归与迭代

客户端通常只向本地递归 DNS 发起请求:

浏览器 / 操作系统
  -> Local Recursive DNS
     -> 逐级查询
     -> 返回最终 IP

递归 DNS 负责代替客户端完成迭代查询,并缓存结果。客户端看到的是一次递归查询。

13.3 常见记录

类型 说明 示例
A 域名到 IPv4 1.2.3.4
AAAA 域名到 IPv6 2001:db8::1
CNAME 别名指向另一域名 cdn.example.net
NS 委托子域解析 ns1.example.com
MX 邮件服务器 10 mail.example.com
TXT 文本记录 SPF、验证
CAA 允许签发证书的 CA 0 issue "letsencrypt.org"
SRV 服务地址和端口 _sip._tcp
PTR IP 反向解析 常用于邮件和日志

13.4 dig 与 nslookup

dig www.example.com
dig www.example.com A
dig www.example.com AAAA
dig www.example.com CNAME
dig @8.8.8.8 www.example.com
dig www.example.com +short
dig www.example.com +trace
dig -x 1.2.3.4

重点字段:

QUESTION SECTION:查询内容
ANSWER SECTION:结果和 TTL
AUTHORITY SECTION:授权 NS
Query time:查询耗时
SERVER:使用的 DNS 服务器

简单查看:

nslookup www.example.com
host www.example.com
resolvectl query www.example.com

13.5 缓存与 TTL

TTL 是记录可缓存时间:

TTL 300:缓存 300 秒

缓存层级:

浏览器
  -> 操作系统
  -> 家用路由器
  -> 运营商 / 公共递归 DNS
  -> 权威 DNS

切换 IP 前:

  1. 提前降低 TTL;
  2. 等待旧 TTL 过期;
  3. 切换记录;
  4. 多地验证解析;
  5. 保留旧服务可用;
  6. 观察流量迁移;
  7. 再恢复 TTL。

不要在 TTL 600 秒的情况下期待 DNS 切换立即生效。

13.6 负载均衡与地域调度

DNS 可以返回多个 A/AAAA 记录:

www.example.com A 1.1.1.1
www.example.com A 2.2.2.2

调度方式:

方式 特点
轮询 简单,无法感知健康
权重 可控比例,受缓存影响
GeoDNS 按解析者位置调度
健康检查 自动摘除故障地址
Low TTL 快速切换,递归压力大

局限:

  1. 客户端可能只用第一个地址;
  2. Local DNS 位置不等于用户位置;
  3. 缓存让权重不精确;
  4. 无法感知真实应用负载;
  5. 网络路径质量动态变化。

大型系统通常 DNS 只做入口和高层级调度,再由 LB 或服务发现做细粒度流量治理。

13.7 DNS 解析失败排查

dig @127.0.0.53 www.example.com
dig @8.8.8.8 www.example.com
dig @<authoritative-dns> www.example.com
cat /etc/resolv.conf
resolvectl status

定位顺序:

  1. 本机网络是否可用;
  2. /etc/hosts 是否覆盖;
  3. 系统 resolver 是否异常;
  4. 公共 DNS 是否能解析;
  5. 权威 DNS 是否返回正确记录;
  6. 域名是否过期;
  7. NS 委托是否正确;
  8. TTL 缓存是否导致旧结果;
  9. AAAA 是否可用但 IPv6 路由异常。

13.8 应用中的 DNS

潜在问题:

  1. 启动时解析一次,之后 IP 变化不生效;
  2. 客户端未设置解析超时;
  3. 连接池没有感知地址变化;
  4. IPv4/IPv6 选择策略导致失败;
  5. DNS 服务不可用导致雪崩;
  6. 内部服务发现依赖单一 DNS。

实践:

  1. 设置解析和连接超时;
  2. 使用多个 DNS Server;
  3. 关键结果本地短缓存;
  4. 重试使用幂等策略;
  5. 定期刷新服务地址;
  6. 监控解析成功率和耗时;
  7. 内部服务发现准备降级方案。

Java 示例:

InetAddress[] addresses =
        InetAddress.getAllByName("www.example.com");

for (InetAddress address : addresses) {
    System.out.println(address.getHostAddress());
}

注意 JVM 的 DNS 缓存策略,容器和服务重启也会影响解析刷新。

13.9 DNS 安全

风险:

  1. DNS 劫持;
  2. 缓存投毒;
  3. DDoS;
  4. 子域接管;
  5. 泄露内部域名;
  6. 邮件伪造。

防护:

方案 作用
DNSSEC 签名验证,防篡改
DNS over TLS / HTTPS 加密本地到递归的查询
CAA 限制证书签发机构
SPF / DKIM / DMARC 邮件域保护
子域治理 清理悬挂 CNAME
权限控制 防止记录被误改

DoH/DoT 加密查询链路,但不改变递归 DNS 可以看到目标域名这一事实。

本章小结

DNS 通过分层委托和递归查询完成域名到 IP 的转换,A、AAAA、CNAME、NS 和 TXT 等记录承载不同语义。TTL 决定缓存和切换速度,DNS 调度适合粗粒度入口选择,不能替代负载均衡和服务发现。排查 DNS 应从本机 resolver 到公共 DNS 再到权威 DNS 逐层验证,同时关注 IPv6、缓存和应用刷新策略。

思考题

  1. 递归查询和迭代查询分别由谁执行?
  2. 切换公网服务 IP 前,DNS TTL 应如何操作?
  3. 为什么 DNS 权重调度不精确?
  4. dig +trace 能帮助定位什么问题?
  5. 设计一套内部服务的 DNS 超时、缓存和降级策略。