mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
4466 字
12 分钟
DNS域名系统:互联网的电话簿
2022-07-22

QUIC与HTTP/3 中,看到 QUIC 如何在传输层解决 TCP 的队头阻塞和连接迁移问题。但 QUIC 连接的第一步是什么?客户端需要知道服务器的 IP 地址。你在浏览器里输入的是 www.example.com,不是 93.184.216.34——从域名到 IP 地址的翻译,就是 DNS 的工作。

DNS 是互联网最古老的基础设施之一,也是每天被使用次数最多的协议。每一次网页加载、每一封邮件发送、每一个 API 调用背后,都有 DNS 查询在默默工作。它看起来简单——不就是”域名查 IP”吗?但当你深入进去,会发现一个精巧的分布式数据库系统:全球数百万台域名服务器协同工作,用层次化的命名空间和缓存机制,每秒处理数十亿次查询。

本章从 DNS 的设计动机出发,逐步展开它的层次结构、查询过程、记录类型、报文格式,再到 DNSSEC 和 DoH/DoT 等安全增强机制,最后通过动手实践追踪一次完整的 DNS 解析。理解了 DNS,你就理解了互联网”寻址”这一环;而下一章 TLS与安全通道 将在 DNS 解析的基础上,建立加密通道,确保数据在传输中不被窃听和篡改。

一、DNS的设计动机#

1.1 从 /etc/hosts 说起#

互联网早期只有几十台主机,网络信息中心维护一个 HOSTS.TXT 文件,列出所有主机名和 IP 地址的映射。每台主机定期从 SRI(斯坦福研究所)的 NIC 服务器下载这个文件,存为本地的 /etc/hosts

# 早期 ARPANET 的 HOSTS.TXT 片段
10.0.0.1 sri-nic
10.0.0.2 ucla-ccn
10.0.0.3 ucb-cad
10.0.0.4 rand-unix

这个方案在几十台主机时没问题,但随着互联网扩张,三个致命问题浮现:

  • 单点瓶颈:所有更新和下载都集中在 NIC 一台服务器上,随着主机数量增长,它的负载越来越重
  • 一致性问题:每次修改 HOSTS.TXT 后,所有主机必须重新下载才能看到更新,但下载频率有限,导致不同主机看到的映射不一致
  • 命名冲突:没有层次化的命名管理,主机名必须全局唯一。两个组织都想用 mail 作为主机名?只能先到先得

1.2 分布式命名的设计目标#

1983 年,Paul Mockapetris 设计了 DNS(RFC 882/883,后由 RFC 1034/1035 取代),核心思想是把一个巨大的平面文件拆成一个分布式的、层次化的数据库

  • 层次化命名:域名按树状结构组织,example.comexample.org 是不同的子树,各自独立管理
  • 分布式存储:每个区域(zone)有自己的权威域名服务器,不需要一台中心服务器存储所有数据
  • 缓存机制:查询结果可以在本地缓存,减少重复查询,降低根服务器和权威服务器的负载
Note

DNS 的设计哲学与互联网的端到端原则一脉相承:没有中心控制节点,每个参与者只负责自己管辖的那一部分,通过协议协作完成全局目标。这种”去中心化但有序”的设计,是互联网基础设施的共同特征。

二、DNS层次结构#

2.1 域名树的层级#

DNS 的命名空间是一棵从根向下的树。根节点用 . 表示(通常省略),下面是顶级域(TLD),再往下是二级域、三级域……每一层由不同的机构管理:

graph TD ROOT["根域 ."] --> COM["com"] ROOT --> ORG["org"] ROOT --> CN["cn"] ROOT --> NET["net"] COM --> EXAMPLE_COM["example.com"] COM --> GOOGLE_COM["google.com"] COM --> CLOUDFLARE_COM["cloudflare.com"] ORG --> WIKI_ORG["wikipedia.org"] ORG --> IETF_ORG["ietf.org"] CN --> COM_CN["com.cn"] CN --> EDU_CN["edu.cn"] COM_CN --> EXAMPLE_CN["example.com.cn"] EDU_CN --> TSINGHUA["tsinghua.edu.cn"] EXAMPLE_COM --> WWW["www.example.com"] EXAMPLE_COM --> MAIL["mail.example.com"] EXAMPLE_COM --> API["api.example.com"] style ROOT fill:#ffcdd2,stroke:#c62828 style COM fill:#fff9c4,stroke:#f9a825 style ORG fill:#fff9c4,stroke:#f9a825 style CN fill:#fff9c4,stroke:#f9a825 style NET fill:#fff9c4,stroke:#f9a825

从右到左读域名:www.example.com. 的层级是根 → comexamplewww。每一层之间用 . 分隔,最后的 . 代表根域,日常使用中通常省略。

2.2 TLD 的分类#

顶级域按用途和管辖权分为几类:

类型示例管理方
通用顶级域(gTLD).com.org.net.infoICANN 授权的注册局
国家代码顶级域(ccTLD).cn(中国)、.jp(日本)、.uk(英国)各国指定机构
新通用顶级域(New gTLD).app.dev.blog.cloudICANN 新增,2012 年起开放申请
基础设施顶级域.arpaIANA,用于反向 DNS 等基础设施

2.3 区域与权威服务器#

DNS 管理的基本单位是区域(zone),不是域。一个区域对应域名树中某个节点及其子树的管辖权。example.com 的管理者可以将 example.com 及其所有子域作为一个区域管理,也可以把 mail.example.com 委派给另一个团队管理,形成独立的区域。

每个区域至少有两台权威域名服务器(Authoritative Name Server),它们存储该区域内所有记录的权威数据。当 DNS 查询到达权威服务器时,它给出的答案就是最终答案——不是缓存,不是猜测,而是该区域管理员配置的真实数据。

三、DNS查询过程#

3.1 递归查询与迭代查询#

DNS 查询有两种基本模式:

特性递归查询迭代查询
谁负责追踪答案递归解析器(代替客户端完成全部工作)客户端自己逐级查询
返回结果最终答案(IP 地址或错误)最佳参考(下一步该问谁)
工作量解析器承担全部工作量客户端承担多次往返
典型场景客户端 → 本地递归解析器递归解析器 → 根/TLD/权威服务器

日常使用中,你的电脑发出的几乎都是递归查询——交给运营商的递归解析器或公共 DNS(如 8.8.8.8)去处理。而递归解析器在背后用迭代查询逐级追踪答案。

3.2 完整解析过程#

以解析 www.example.com 的 A 记录为例,一次完整的 DNS 解析涉及多个服务器的协作:

sequenceDiagram participant C as 客户端 participant R as 递归解析器<br/>(8.8.8.8) participant ROOT as 根服务器 participant TLD as .com TLD服务器 participant AUTH as example.com<br/>权威服务器 C->>R: 查询 www.example.com A(递归) R->>ROOT: 查询 www.example.com A(迭代) ROOT-->>R: 我不知道,去问 .com 的 TLD 服务器<br/>[NS: a.gtld-servers.net] R->>TLD: 查询 www.example.com A(迭代) TLD-->>R: 我不知道,去问 example.com 的权威服务器<br/>[NS: a.iana-servers.net] R->>AUTH: 查询 www.example.com A(迭代) AUTH-->>R: www.example.com → 93.184.216.34<br/>[A 记录,TTL=3600] R-->>C: www.example.com → 93.184.216.34

整个过程看起来要四次往返,但实际上很少走完整个流程——递归解析器有强大的缓存机制。

3.3 缓存与 TTL#

DNS 缓存存在于多个层级:

  • 浏览器缓存:Chrome 内置 DNS 缓存,chrome://net-internals/#dns 可查看
  • 操作系统缓存:Linux 上由 nscdsystemd-resolved 管理,Windows 上由 DNS Client 服务管理
  • 递归解析器缓存:8.8.8.8 这类公共 DNS 缓存了大量热门域名的记录

每条 DNS 记录都有一个 TTL(Time To Live) 值,单位是秒。它告诉缓存者”这条记录最多缓存多久”。TTL 到期前,缓存可以直接使用,无需重新查询;TTL 到期后,必须重新向权威服务器查询。

# 查看 DNS 记录的 TTL 值
dig www.example.com A
# 输出中 TTL 字段示例:
# www.example.com. 3600 IN A 93.184.216.34
# ^^^^
# TTL = 3600 秒(1 小时)
Warning

TTL 是一把双刃剑。短 TTL(如 60 秒)意味着 DNS 变更能快速生效,但会增加权威服务器的查询负载;长 TTL(如 86400 秒)减轻了服务器压力,但变更后需要等待 TTL 过期才能在全球生效。在做 DNS 切换(如故障转移、蓝绿部署)时,务必提前降低 TTL,等旧 TTL 过期后再切换 IP。

四、DNS记录类型#

DNS 不只是”域名→IP”的映射,它支持多种记录类型,每种服务于不同用途:

记录类型全称用途示例
AAddress域名→IPv4 地址www.example.com. → 93.184.216.34
AAAAIPv6 Address域名→IPv6 地址www.example.com. → 2606:2800:220:1:...
CNAMECanonical Name域名别名→另一个域名blog.example.com. → example.github.io.
MXMail Exchange邮件服务器地址(带优先级)example.com. → 10 mail1.example.com.
NSName Server区域的权威域名服务器example.com. → a.iana-servers.net.
TXTText任意文本数据(SPF、DKIM、验证等)example.com. → "v=spf1 include:_spf.google.com ~all"
SRVService服务的位置(主机+端口)_sip._tcp.example.com. → 10 60 5060 sip.example.com.
SOAStart of Authority区域的管理信息(主服务器、管理员邮箱、序列号、刷新间隔)example.com. → ns1.example.com. admin.example.com. 2024010101 3600 900 604800 86400

4.1 CNAME 的链式解析#

CNAME 记录让一个域名指向另一个域名,解析器会继续解析目标域名,直到得到 IP 地址:

# 追踪 CNAME 链
dig blog.example.com A +trace
# 可能的解析链:
# blog.example.com → CNAME → example.github.io
# example.github.io → CNAME → github.github.io
# github.github.io → A → 20.205.243.166

CNAME 有两个限制:第一,CNAME 不能和其他记录类型共存于同一域名(即 example.com 不能同时有 CNAME 和 MX 记录);第二,CNAME 指向的域名可以继续是 CNAME,形成链式解析,但过长的链会增加解析延迟。

4.2 MX 记录与邮件路由#

MX 记录指定了接收该域名邮件的服务器,带有优先级数值,数值越小优先级越高:

# 查询 Gmail 的 MX 记录
dig gmail.com MX
# 输出:
# gmail.com. 3600 IN MX 5 gmail-smtp-in.l.google.com.
# gmail.com. 3600 IN MX 10 alt1.gmail-smtp-in.l.google.com.
# gmail.com. 3600 IN MX 20 alt2.gmail-smtp-in.l.google.com.
# gmail.com. 3600 IN MX 30 alt3.gmail-smtp-in.l.google.com.
# gmail.com. 3600 IN MX 40 alt4.gmail-smtp-in.l.google.com.

邮件发送方会按优先级顺序尝试连接,5 优先于 10,10 优先于 20,以此类推。只有高优先级服务器不可达时,才会尝试低优先级服务器。

4.3 TXT 记录的多种用途#

TXT 记录最初设计用于存放人类可读的文本注释,但如今承载了大量结构化数据:

# SPF 记录——声明哪些服务器有权以该域名发送邮件
dig example.com TXT
# 输出可能包含:
# "v=spf1 include:_spf.google.com include:mailgun.org ~all"
# DKIM 记录——邮件签名验证的公钥
dig selector._domainkey.example.com TXT
# 域名所有权验证(Google、GitHub 等服务常用)
dig example.com TXT
# "google-site-verification=abc123..."
# ACME Challenge(Let's Encrypt 证书验证)
dig _acme-challenge.example.com TXT

五、DNS协议报文#

5.1 报文整体结构#

DNS 报文由 5 个部分组成,无论是查询还是响应,都使用相同的报文格式:

+---------------------+
| Header | 12 字节,固定长度
+---------------------+
| Question | 查询问题区
+---------------------+
| Answer | 应答区(响应时填充)
+---------------------+
| Authority | 权威区(指向权威 NS)
+---------------------+
| Additional | 附加区(额外信息)
+---------------------+

5.2 Header 格式#

Header 固定 12 字节,是 DNS 报文的核心控制信息:

1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

关键字段含义:

  • ID(16 位):事务标识,用于匹配查询和响应
  • QR(1 位):0 表示查询,1 表示响应
  • Opcode(4 位):查询类型,0=标准查询,1=反向查询,4=通知
  • AA(1 位):权威应答标志,表示响应来自权威服务器
  • RD(1 位):期望递归,客户端设置,请求解析器递归查询
  • RA(1 位):支持递归,服务器设置,表示该服务器支持递归查询
  • RCODE(4 位):响应码,0=无错误,3=域名不存在(NXDOMAIN)

5.3 用 dig 观察报文细节#

dig 命令是 DNS 调试的瑞士军刀,它的输出直接反映了 DNS 报文的各个部分:

# 基本查询
dig www.example.com A
# 输出解读:
# ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45231
# ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
#
# ;; QUESTION SECTION:
# ;www.example.com. IN A
#
# ;; ANSWER SECTION:
# www.example.com. 3600 IN A 93.184.216.34
#
# ;; Query time: 28 msec
# ;; SERVER: 8.8.8.8#53(8.8.8.8)
# ;; WHEN: Sat May 02 14:30:00 CST 2026
# ;; MSG SIZE rcvd: 56

逐行对应报文字段:

  • opcode: QUERY → Opcode = 0
  • status: NOERROR → RCODE = 0
  • flags: qr rd ra → QR=1(响应)、RD=1(请求了递归)、RA=1(服务器支持递归)
  • QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 → QDCOUNT、ANCOUNT、NSCOUNT、ARCOUNT

5.4 其他查询工具#

除了 dig,还有几个常用的 DNS 查询工具:

# nslookup——更简洁的输出,适合快速查询
nslookup www.example.com
# host——最简洁的输出格式
host www.example.com
# 指定 DNS 服务器查询
nslookup www.example.com 8.8.8.8
host www.example.com 1.1.1.1
# 反向查询(IP → 域名)
dig -x 93.184.216.34
host 93.184.216.34

六、DNS安全:DNSSEC与DoH/DoT#

6.1 DNS 的安全缺陷#

原始 DNS 协议设计于 1983 年,当时的安全威胁模型远不如今天复杂。它有两个根本性的安全缺陷:

缺陷一:没有身份验证。 DNS 响应没有任何机制验证”这个回答真的来自权威服务器”。攻击者可以伪造 DNS 响应,把用户导向恶意网站——这就是 DNS 缓存投毒(Cache Poisoning)

2008 年的 Kaminsky 攻击展示了这一缺陷的严重性:攻击者向递归解析器发送大量伪造响应,猜中事务 ID 和端口的概率虽然低,但只要成功一次,伪造的记录就会被缓存,TTL 期间所有用户都会被导向恶意 IP。

缺陷二:没有加密。 DNS 查询和响应以明文传输,任何中间人都可以看到你在查询什么域名——即使后续的 HTTP 流量被 TLS 加密,DNS 查询本身暴露了你正在访问哪些网站。

6.2 DNSSEC:签名验证#

DNSSEC(DNS Security Extensions,RFC 4033-4035)通过数字签名解决第一个缺陷——验证 DNS 响应的真实性和完整性。它不加密数据,而是给数据签名:

graph TD ROOT_KEY["根区 KSK<br/>信任锚"] -->|"签名 .com 的 ZSK"| COM_KSK[".com KSK"] COM_KSK -->|"签名 .com 的 ZSK"| COM_ZSK[".com ZSK"] COM_ZSK -->|"签名 example.com 的 KSK"| EX_KSK["example.com KSK"] EX_KSK -->|"签名 example.com 的 ZSK"| EX_ZSK["example.com ZSK"] EX_ZSK -->|"签名记录"| RECORDS["A/AAAA/MX/TXT<br/>等记录"] style ROOT_KEY fill:#ffcdd2,stroke:#c62828 style COM_KSK fill:#fff9c4,stroke:#f9a825 style EX_KSK fill:#c8e6c9,stroke:#2e7d32 style RECORDS fill:#e3f2fd,stroke:#1565c0

DNSSEC 引入两种密钥:

  • ZSK(Zone Signing Key):对区域内的记录签名,频繁轮换
  • KSK(Key Signing Key):对 ZSK 签名,长期使用,由父区域签名认证

这形成了一条从根区到具体记录的信任链:根区的 KSK 是信任锚(由 ICANN 仪式性管理),根区签名 .com 的 KSK,.com 的 KSK 签名 example.com 的 KSK,example.com 的 KSK 签名 ZSK,ZSK 签名具体记录。验证者只需信任根区的 KSK,就能验证整条链上的任何记录。

DNSSEC 新增了四种记录类型:

记录类型用途
DNSKEY发布区域的公钥(ZSK 和 KSK)
RRSIG对记录集的数字签名
DSDelegation Signer——父区域对子区域 KSK 的摘要
NSEC/NSEC3证明某个域名不存在(防枚举)
# 查询 DNSSEC 签名
dig www.example.com A +dnssec
# 输出中会多出 RRSIG 记录:
# www.example.com. 3600 IN A 93.184.216.34
# www.example.com. 3600 IN RRSIG A 8 3 3600 20260515000000 ...签名数据...
# 验证 DNSSEC 信任链
dig www.example.com A +dnssec +sigchase

6.3 DoH 与 DoT:加密 DNS 查询#

DNSSEC 解决了”回答是否真实”的问题,但没有解决”查询是否私密”的问题。DoH 和 DoT 通过加密 DNS 查询来保护隐私:

特性DoT(DNS over TLS)DoH(DNS over HTTPS)明文 DNS
协议TLS over TCP/853HTTPS over TCP/443UDP/53(或 TCP/53)
端口85344353
传输格式标准 DNS 报文DNS 报文编码为 HTTP 消息标准 DNS 报文
防火墙友好性专用端口,易被识别和封锁与普通 HTTPS 流量混合,难以区分基本不封锁
隐私保护加密查询内容,但元数据(连接到 853 端口)暴露完全混入 HTTPS 流量
典型实现Unbound、Knot Resolver、systemd-resolvedCloudflare 1.1.1.1、Google 8.8.8.8、浏览器内置传统 DNS 客户端
RFCRFC 7858RFC 8484RFC 1035
graph LR subgraph 明文DNS["明文 DNS"] C1["客户端"] -->|"UDP 53<br/>明文可嗅探"| R1["递归解析器"] end subgraph DoT["DNS over TLS"] C2["客户端"] -->|"TCP 853<br/>TLS 加密"| R2["递归解析器"] end subgraph DoH["DNS over HTTPS"] C3["客户端"] -->|"TCP 443<br/>HTTPS 加密"| R3["递归解析器"] end style 明文DNS fill:#ffcdd2,stroke:#c62828 style DoT fill:#fff9c4,stroke:#f9a825 style DoH fill:#c8e6c9,stroke:#2e7d32

DoH 的一个争议在于:它绕过了网络管理员的 DNS 策略。企业网络通常用 DNS 过滤来阻止恶意网站访问,但浏览器内置的 DoH 会绕过本地 DNS 服务器,直接向公共 DNS 查询。Firefox 和 Chrome 都提供了禁用 DoH 的策略选项,但这场”用户隐私 vs 网络管控”的争论仍在继续。

Note

DNSSEC 和 DoH/DoT 解决的是不同的问题:DNSSEC 保证”回答是真的”(完整性+真实性),DoH/DoT 保证”查询是私密的”(机密性)。两者互补而非替代——理想情况下,你应该同时使用 DNSSEC 验证和 DoH/DoT 加密。

七、动手实践:追踪DNS解析#

7.1 用 dig +trace 追踪完整解析路径#

dig +trace 从根服务器开始,逐级追踪 DNS 解析过程,让你亲眼看到每一跳:

# 追踪 www.example.com 的完整解析路径
dig www.example.com A +trace
# 输出大致如下:
# . 518400 IN NS a.root-servers.net.
# . 518400 IN NS b.root-servers.net.
# ;; Received 277 bytes from 199.7.83.42#53(199.7.83.42) in 28 ms
#
# example.com. 172800 IN NS a.iana-servers.net.
# example.com. 172800 IN NS b.iana-servers.net.
# ;; Received 192 bytes from 192.5.6.30#53(192.5.6.30) in 120 ms
#
# www.example.com. 3600 IN A 93.184.216.34
# ;; Received 56 bytes from 199.43.135.53#53(199.43.135.53) in 85 ms

每一段输出对应一次迭代查询:先问根服务器,再问 .com TLD 服务器,最后问 example.com 权威服务器。

7.2 用 Wireshark 捕获 DNS 报文#

Wireshark 可以实时捕获和解析 DNS 报文,让你看到每个字段的值:

# 用 tshark 命令行捕获 DNS 查询
sudo tshark -i eth0 -f "udp port 53" -Y "dns"
# 只看 DNS 查询(不含响应)
sudo tshark -i eth0 -f "udp port 53" -Y "dns.qr == 0"
# 只看 DNS 响应
sudo tshark -i eth0 -f "udp port 53" -Y "dns.qr == 1"
# 查看 NXDOMAIN 响应(域名不存在)
sudo tshark -i eth0 -f "udp port 53" -Y "dns.flags.rcode == 3"
# 查看 DNS 报文的事务 ID 和标志位
sudo tshark -i eth0 -f "udp port 53" \
-T fields \
-e dns.id \
-e dns.flags.response \
-e dns.qry.name \
-e dns.a

在 Wireshark 图形界面中,过滤 DNS 报文只需在过滤栏输入 dns,然后展开 Domain Name System 部分,可以看到 Header 的每个字段、Question 和 Answer 区域的每条记录。

7.3 搭建本地递归解析器(Unbound)#

Unbound 是一个安全优先的开源递归 DNS 解析器,支持 DNSSEC 验证:

# 安装 Unbound
sudo apt install unbound
# 基本配置
sudo tee /etc/unbound/unbound.conf.d/custom.conf << 'EOF'
server:
# 监听地址
interface: 127.0.0.1
interface: ::1
# 访问控制
access-control: 127.0.0.0/8 allow
access-control: ::1/128 allow
# 启用 DNSSEC 验证
auto-trust-anchor-file: "/var/lib/unbound/root.key"
# 日志级别
verbosity: 1
# 性能调优
num-threads: 2
msg-cache-size: 64m
rrset-cache-size: 128m
forward-zone:
# 转发到公共 DNS(可选)
name: "."
forward-addr: 8.8.8.8
forward-addr: 1.1.1.1
EOF
# 生成根信任锚
sudo unbound-anchor -a /var/lib/unbound/root.key
# 启动 Unbound
sudo systemctl restart unbound
# 测试解析
dig @127.0.0.1 www.example.com A

7.4 DNSSEC 验证实践#

配置好 Unbound 后,可以验证 DNSSEC 是否正常工作:

# 查询 DNSSEC 签名的域名,验证应答
dig @127.0.0.1 www.example.com A +dnssec
# 用 unbound-checkconf 验证配置
unbound-checkconf
# 用 unbound-host 验证 DNSSEC 状态
unbound-host -v www.example.com
# 输出含义:
# www.example.com has address 93.184.216.34 (secure)
# ^^^^^^^
# secure = DNSSEC 验证通过
# 测试故意失败的 DNSSEC(dnssec-failed.org 是专门用于测试的域名)
unbound-host -v dnssec-failed.org
# 预期输出:BOGUS(DNSSEC 验证失败)

7.5 用 BIND 搭建权威 DNS#

如果你想在本地搭建一个权威 DNS 服务器来实验区域管理和记录配置:

# 安装 BIND
sudo apt install bind9
# 配置区域文件
sudo tee /etc/bind/db.example.com << 'EOF'
$TTL 3600
@ IN SOA ns1.example.com. admin.example.com. (
2026050201 ; 序列号
3600 ; 刷新间隔
900 ; 重试间隔
604800 ; 过期时间
86400 ; 否定缓存 TTL
)
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
@ IN A 192.168.1.100
@ IN MX 10 mail.example.com.
@ IN TXT "v=spf1 mx -all"
ns1 IN A 192.168.1.1
ns2 IN A 192.168.1.2
www IN A 192.168.1.100
mail IN A 192.168.1.200
blog IN CNAME www.example.com.
EOF
# 在 named.conf 中引用区域文件
sudo tee -a /etc/bind/named.conf.local << 'EOF'
zone "example.com" {
type master;
file "/etc/bind/db.example.com";
};
EOF
# 检查配置语法
sudo named-checkconf
sudo named-checkzone example.com /etc/bind/db.example.com
# 重启 BIND
sudo systemctl restart bind9
# 测试查询
dig @127.0.0.1 www.example.com A
dig @127.0.0.1 example.com MX
dig @127.0.0.1 blog.example.com CNAME

八、本章小结#

主题核心要点
设计动机从 /etc/hosts 的单点瓶颈到分布式层次化命名,解决可扩展性、一致性和命名冲突
层次结构根域 → TLD → 二级域 → 子域,每层独立管理;区域是管理的基本单位
查询过程递归查询由解析器代劳,迭代查询逐级追踪;多级缓存(浏览器/OS/解析器)大幅减少查询
记录类型A/AAAA(地址)、CNAME(别名)、MX(邮件)、NS(权威服务器)、TXT(文本/验证)、SRV(服务发现)、SOA(区域管理)
协议报文5 段式结构(Header/Question/Answer/Authority/Additional),12 字节 Header 携带控制信息
DNSSEC数字签名验证响应真实性,KSK/ZSK 双密钥体系构建从根到叶的信任链
DoH/DoT加密 DNS 查询保护隐私,DoH 混入 HTTPS 流量更难封锁,DoT 专用端口更易管理

DNS 是互联网基础设施中看似简单实则精巧的一环。它用层次化的命名空间把一个全球性的命名问题分解成无数个本地管理问题,用缓存机制把频繁的查询压力化解在离用户最近的地方,用信任链和加密分别解决真实性和隐私性。

但 DNS 解析只是第一步——你拿到了服务器的 IP 地址,接下来要建立安全连接。下一章 TLS与安全通道 将展示 TLS 如何在 TCP(或 QUIC)连接之上建立加密通道,通过证书链验证服务器身份,通过密钥交换协商会话密钥,确保你的数据在穿越互联网时不被窃听和篡改。


参考#

支持与分享

如果这篇文章对你有帮助,欢迎支持作者或分享给更多人

DNS域名系统:互联网的电话簿
https://blog.souloss.com/posts/internet-architecture/dns-domain-name-system/
作者
Souloss
发布于
2022-07-22
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时