DNS 协议深度学习指南(含上机实操)

DNS 协议深度学习指南(含上机实操)

适用版本 : BIND 9.18.39 | DiG 9.18.39 | Dnsmasq 2.90 | Ubuntu 24.04 LTS

实验集群 : ecs-ee63 (华为云香港区, 3 节点 c6.large_2)

客户端 : dig / nslookup / host / tcpdump / Python 3

特点: 全部实验基于真实服务器输出, 非模拟数据


目录

  1. [第一章: DNS 基础与核心概念](#第一章: DNS 基础与核心概念 "#%E7%AC%AC%E4%B8%80%E7%AB%A0-dns-%E5%9F%BA%E7%A1%80%E4%B8%8E%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5")
  2. [第二章: DNS 记录类型详解](#第二章: DNS 记录类型详解 "#%E7%AC%AC%E4%BA%8C%E7%AB%A0-dns-%E8%AE%B0%E5%BD%95%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3")
  3. [第三章: DNS 解析过程详解](#第三章: DNS 解析过程详解 "#%E7%AC%AC%E4%B8%89%E7%AB%A0-dns-%E8%A7%A3%E6%9E%90%E8%BF%87%E7%A8%8B%E8%AF%A6%E8%A7%A3")
  4. [第四章: DNS 配置与管理](#第四章: DNS 配置与管理 "#%E7%AC%AC%E5%9B%9B%E7%AB%A0-dns-%E9%85%8D%E7%BD%AE%E4%B8%8E%E7%AE%A1%E7%90%86")
  5. [第五章: DNS 安全与防护](#第五章: DNS 安全与防护 "#%E7%AC%AC%E4%BA%94%E7%AB%A0-dns-%E5%AE%89%E5%85%A8%E4%B8%8E%E9%98%B2%E6%8A%A4")
  6. [第六章: DNS 性能优化](#第六章: DNS 性能优化 "#%E7%AC%AC%E5%85%AD%E7%AB%A0-dns-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96")
  7. [第七章: 云 DNS 服务实战](#第七章: 云 DNS 服务实战 "#%E7%AC%AC%E4%B8%83%E7%AB%A0-%E4%BA%91-dns-%E6%9C%8D%E5%8A%A1%E5%AE%9E%E6%88%98")
  8. [第八章: DNS 故障排查](#第八章: DNS 故障排查 "#%E7%AC%AC%E5%85%AB%E7%AB%A0-dns-%E6%95%85%E9%9A%9C%E6%8E%92%E6%9F%A5")
  9. [第九章: DNS 与容器化](#第九章: DNS 与容器化 "#%E7%AC%AC%E4%B9%9D%E7%AB%A0-dns-%E4%B8%8E%E5%AE%B9%E5%99%A8%E5%8C%96")
  10. [第十章: DNS 自动化与 DevOps](#第十章: DNS 自动化与 DevOps "#%E7%AC%AC%E5%8D%81%E7%AB%A0-dns-%E8%87%AA%E5%8A%A8%E5%8C%96%E4%B8%8E-devops")
  11. 附录

第一章: DNS 基础与核心概念

1.1 DNS 的定义与作用

DNS (Domain Name System, 域名系统) 是互联网的「电话簿」------ 将人类可读的域名 (如 baidu.com) 转换为机器可路由的 IP 地址 (如 110.242.74.102)。

复制代码
┌──────────────────────────────────────────────────────────┐
│                    DNS 核心工作原理                        │
│                                                          │
│  用户输入                    DNS 服务器                    │
│  baidu.com  ──────────────▶  查询域名  ──────────────▶  返回 IP     │
│                              ↓                          │
│                         110.242.74.102                  │
│                              │                          │
│  浏览器 ◀────────────────────┘                          │
│  连接到 110.242.74.102:443                              │
└──────────────────────────────────────────────────────────┘

为什么需要 DNS:

  • 人类记忆域名 (baidu.com) 远比 IP 地址 (110.242.74.102) 容易
  • IP 地址可能变更, 域名可以保持稳定
  • 一个域名可以对应多个 IP 实现负载均衡
  • 通过 DNS 可以实现服务发现和故障转移

1.2 DNS 的历史发展

阶段 时间 方案 问题
ARPANET 时代 1970s 单机 hosts.txt 文件 (SRI-NIC 维护) 每台机器手动同步, 不可扩展
DNS 诞生 1983 RFC 882/883 → RFC 1034/1035 Paul Mockapetris 设计, 分布式层级数据库
BIND 时代 1984-至今 BIND (Berkeley Internet Name Domain) 最广泛使用的 DNS 服务器软件
现代 DNS 2010s-至今 DNSSEC / DoH / DoT / DoQ 安全加密 + 隐私保护

hosts 文件 vs DNS 对比:

bash 复制代码
hosts 文件方式 (单机):
┌──────────────┐
│ /etc/hosts   │
│ 1.2.3.4 foo  │ ← 每一台机器都要维护
│ 5.6.7.8 bar  │
└──────────────┘

DNS 分布式方式:
┌─────────┐     ┌─────────┐     ┌──────────┐
│ 根服务器  │───▶│ .com TLD │───▶│ 权威服务器  │
│ (13组)   │     │ 服务器    │     │ (baidu)  │
└─────────┘     └─────────┘     └──────────┘

1.3 DNS 的层级结构

scss 复制代码
                         ┌──────┐
                         │  .   │  根域 (Root) - 13 组根服务器 (a~m.root-servers.net)
                         └──┬───┘
              ┌─────────────┼──────────────┐
           ┌──┴──┐      ┌──┴──┐       ┌──┴───┐
           │ com │      │ cn  │       │ org  │ 顶级域 (Top-Level Domain, TLD)
           └──┬──┘      └──┬──┘       └──────┘
        ┌─────┴─────┐     │
     ┌──┴───┐   ┌──┴───┐ │
     │baidu │   │google│ │          二级域 (Second-Level Domain)
     └──┬───┘   └──────┘ │
   ┌────┴────┐           │
┌──┴───┐ ┌──┴───┐       │
│ www  │ │ mail │       │          子域 (Subdomain)
└──────┘ └──────┘       │
                    ┌───┴────┐
                    │example │
                    └────────┘

FQDN (Fully Qualified Domain Name, 完全限定域名) : www.baidu.com. (注意末尾的 . 代表根域)

1.4 DNS 服务器类型

服务器类型 英文 作用 示例
根服务器 Root Server DNS 解析的起点, 返回 TLD 服务器地址 a.root-servers.net (198.41.0.4)
TLD 服务器 Top-Level Domain Server 管理特定顶级域的权威信息 a.gtld-servers.net (192.5.6.30)
权威服务器 Authoritative Server 存储域名实际 DNS 记录 ns1.baidu.com
递归服务器 Recursive Resolver 代客户端完成完整解析过程 8.8.8.8 (Google), 1.1.1.1 (Cloudflare)

13 组根服务器 (Root Servers):

字母 IPv4 IPv6 运营方
A 198.41.0.4 2001:503:ba3e::2:30 Verisign
B 170.247.170.2 2801:1b8:10::b USC-ISI
C 192.33.4.12 2001:500:2::c Cogent
D 199.7.91.13 2001:500:2d::d UMD
E 192.203.230.10 2001:500:a8::e NASA
F 192.5.5.241 2001:500:2f::f ISC
G 192.112.36.4 2001:500:12::d0d DISA
H 198.97.190.53 2001:500:1::53 US Army
I 192.36.148.17 2001:7fe::53 Netnod
J 192.58.128.30 2001:503:c27::2:30 Verisign
K 193.0.14.129 2001:7fd::1 RIPE NCC
L 199.7.83.42 2001:500:9f::42 ICANN
M 202.12.27.33 2001:dc3::35 WIDE

注意: 13 组不是 13 台! 每组使用 Anycast (任播) 技术在全球部署数百个节点。

1.5 上机实操: 基本 DNS 查询

实验环境: ecs-ee63 集群 (tcpip-01), BIND 9.18.39, DiG 9.18.39

1.5.1 三种基本查询工具对比
bash 复制代码
# dig (Domain Information Groper) --- 最强大的 DNS 诊断工具
$ dig baidu.com

; <<>> DiG 9.18.39-0ubuntu0.24.04.5-Ubuntu <<>> baidu.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5877
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;baidu.com.              IN      A

;; ANSWER SECTION:
baidu.com.          507 IN      A       110.242.74.102
baidu.com.          507 IN      A       111.63.65.103
baidu.com.          507 IN      A       111.63.65.247
baidu.com.          507 IN      A       124.237.177.164

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; MSG SIZE  rcvd: 102

dig 输出字段详解:

字段 含义 说明
status: NOERROR 查询状态 NOERROR=成功, NXDOMAIN=域名不存在, SERVFAIL=服务器失败
flags: qr rd ra 标志位 qr=响应, rd=期望递归, ra=递归可用
ANSWER: 4 回答记录数 返回了 4 条 A 记录
507 TTL (秒) 缓存有效期, 约 8.5 分钟
IN 网络类别 IN=Internet (唯一广泛使用的类别)
Query time: 0 msec 查询耗时 本地缓存命中时几乎为 0
SERVER: 127.0.0.53 使用的 DNS 服务器 systemd-resolved 本地存根
bash 复制代码
# nslookup --- 交互式查询工具 (简洁输出)
$ nslookup baidu.com
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:       ← 非权威回答 (来自缓存)
Name:   baidu.com
Address: 124.237.177.164
Address: 110.242.74.102
bash 复制代码
# host --- 最简洁的查询工具
$ host baidu.com
baidu.com has address 111.63.65.247
baidu.com has address 110.242.74.102
baidu.com has address 124.237.177.164
baidu.com has address 111.63.65.103
baidu.com mail is handled by 20 mx.baidu.com.

三种工具对比:

工具 详细程度 适用场景
dig ★★★★★ (最详细) 故障排查、DNSSEC 验证、性能分析
nslookup ★★★ (中等) 日常快速查询、交互式使用
host ★ (最简洁) 脚本自动化、快速确认
1.5.2 指定 DNS 服务器查询
bash 复制代码
# 使用不同的公共 DNS 递归解析器查询同一域名
$ dig @8.8.8.8 baidu.com +short
111.63.65.103
111.63.65.247
110.242.74.102
124.237.177.164

$ dig @1.1.1.1 baidu.com +short
111.63.65.103
124.237.177.164
110.242.74.102
111.63.65.247

$ dig @223.5.5.5 baidu.com +short       # 阿里 DNS (中国大陆)
111.63.65.247
124.237.177.164
110.242.74.102
111.63.65.103

关键发现: 所有公共解析器返回相同的 4 个 IP, 但排序不同------这是 DNS 轮询 (Round-Robin) 负载均衡的体现。

1.5.3 查看本机 DNS 配置
bash 复制代码
# /etc/resolv.conf --- 传统 DNS 客户端配置
$ cat /etc/resolv.conf
nameserver 127.0.0.53          # systemd-resolved 本地存根
options edns0 trust-ad
search openstacklocal           # 搜索域

# systemd-resolved 状态 (现代 Ubuntu 使用)
$ resolvectl status
Global
         Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub

Link 2 (eth0)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 100.125.3.250      # 华为云内网 DNS
       DNS Servers: 100.125.3.250 100.125.1.250

systemd-resolved 架构:

bash 复制代码
┌─────────────┐     ┌───────────────────┐     ┌──────────────┐
│ 应用程序      │────▶│ 127.0.0.53:53     │────▶│ 100.125.3.250│
│ (dig/curl)  │     │ systemd-resolved  │     │ (上游 DNS)    │
└─────────────┘     │ (本地存根+缓存)     │     └──────────────┘
                    └───────────────────┘

第二章: DNS 记录类型详解

2.1 八大核心记录类型

scss 复制代码
┌──────────────────────────────────────────────────────────────┐
│                     DNS 记录类型全景图                         │
├──────────┬──────────────────┬────────────────────────────────┤
│ 记录类型  │ 全称              │ 作用                           │
├──────────┼──────────────────┼────────────────────────────────┤
│ A        │ Address           │ 域名 → IPv4 地址               │
│ AAAA     │ IPv6 Address      │ 域名 → IPv6 地址 (4倍A=IPv6)   │
│ CNAME    │ Canonical Name    │ 别名 → 规范域名                 │
│ MX       │ Mail Exchange     │ 邮件服务器优先级+地址            │
│ TXT      │ Text              │ 任意文本 (SPF/DKIM/验证)       │
│ NS       │ Name Server       │ 域的权威 DNS 服务器             │
│ SOA      │ Start of Authority│ 域的管理信息 (版本/刷新/重试)    │
│ PTR      │ Pointer           │ IP → 域名 (反向解析)            │
└──────────┴──────────────────┴────────────────────────────────┘

2.2 A 记录 (Address Record)

将域名映射到 IPv4 地址, 是 DNS 最核心的记录类型。

bash 复制代码
$ dig A baidu.com +short
110.242.74.102
111.63.65.247
111.63.65.103
124.237.177.164

A 记录负载均衡: baidu.com 返回 4 个 IP, DNS 服务器每次轮换顺序, 实现简单的流量分发。

2.3 AAAA 记录 (IPv6 Address Record)

bash 复制代码
$ dig AAAA baidu.com +short
(无返回)     # baidu.com 未配置 IPv6 地址

注意: 中国大陆很多大型网站仍未启用 IPv6 公网解析, 主要因为 IPv4 仍然充足且 CDN 覆盖完善。

2.4 CNAME 记录 (Canonical Name)

别名记录, 将一个域名指向另一个规范域名。重要限制: CNAME 不能与其他记录共存 (除了 DNSSEC 相关记录)。

bash 复制代码
$ dig CNAME www.baidu.com +short
www.a.shifen.com.
scss 复制代码
www.baidu.com (CNAME) → www.a.shifen.com (A) → IP 地址
    ↑ 用户访问               ↑ CDN 调度域名         ↑ 实际服务器

CNAME 链追踪:

less 复制代码
用户请求 www.baidu.com
    │
    ▼
DNS 返回 CNAME: www.a.shifen.com.
    │
    ▼
递归解析器自动追踪: www.a.shifen.com A?
    │
    ▼
返回实际 IP 地址

2.5 MX 记录 (Mail Exchange)

指定域名的邮件服务器及优先级 (数字越小优先级越高)。

bash 复制代码
$ dig MX baidu.com +short
10 mx.maillb.baidu.com.      # 优先级 10 (优先使用)
20 mx.baidu.com.              # 优先级 20 (备用)

邮件投递流程:

less 复制代码
发件服务器                          收件域 DNS
    │                                   │
    │  dig MX baidu.com                 │
    │──────────────────────────────────▶│
    │                                   │
    │  10 mx.maillb.baidu.com           │
    │◀──────────────────────────────────│
    │                                   │
    │  尝试连接 mx.maillb.baidu.com:25   │
    │──────────────────────────────────▶│ ✓ 成功投递
    │                                   │
    │  (若失败, 尝试 mx.baidu.com:25)     │

2.6 TXT 记录 (Text Record)

存储任意文本, 主要用于验证和策略声明。

bash 复制代码
$ dig TXT baidu.com +short
"v=spf1 include:spf1.baidu.com include:spf2.baidu.com include:spf3.baidu.com include:spf4.baidu.com -all"
"9279nznttl321bxp1j464rd9vpps246v"
"google-site-verification=GHb98-6msqyx_qqjGl5eRatD3QTHyVB6-xQ3gJB5UwM"
"_globalsign-domain-verification=qjb28W2jJSrWj04NHpB0CvgK9tle5JkOq-EcyWBgnE"
TXT 记录 用途
v=spf1 ... SPF (Sender Policy Framework), 声明哪些服务器有权发邮件
google-site-verification=... Google Search Console 域名所有权验证
_globalsign-domain-verification=... GlobalSign SSL 证书域名验证

2.7 NS 记录 (Name Server)

指定域名的权威 DNS 服务器。

bash 复制代码
$ dig NS baidu.com +short
dns.baidu.com.
ns3.baidu.com.
ns2.baidu.com.
ns7.baidu.com.
ns4.baidu.com.

最佳实践: 权威 NS 服务器应该分布在不同的地理位置和网络自治系统 (AS), 避免单点故障。

2.8 SOA 记录 (Start of Authority)

域的「管理信息摘要」, 包含版本号、刷新间隔等管理参数。

bash 复制代码
$ dig SOA baidu.com +short
dns.baidu.com. sa.baidu.com. 2012151067 300 300 2592000 600

SOA 字段详解:

字段 含义
MNAME dns.baidu.com. 主 DNS 服务器 (Primary Master)
RNAME sa.baidu.com. 管理员邮箱 (sa@baidu.com, @ 替换为 .)
Serial 2012151067 序列号 (格式: YYYYMMDDNN), 从服务器判断是否需要同步
Refresh 300 (5分钟) 从服务器检查主服务器更新的间隔
Retry 300 (5分钟) 刷新失败后的重试间隔
Expire 2592000 (30天) 从服务器在无法联系主服务器后, 数据有效的最长时间
Minimum TTL 600 (10分钟) 否定缓存 (NXDOMAIN) 的 TTL

2.9 PTR 记录 (反向解析)

IP 地址 → 域名的反向查询。

bash 复制代码
$ dig -x 8.8.8.8 +short
dns.google.

$ dig -x 1.1.1.1 +short
one.one.one.one.

反向解析原理:

makefile 复制代码
IP: 8.8.8.8
  ↓ 反转
查询: 8.8.8.8.in-addr.arpa PTR?
  ↓
返回: dns.google.

2.10 上机实操: 批量查询与对比

bash 复制代码
$ for r in A AAAA MX TXT NS SOA; do
    echo "=== $r Record ==="
    dig $r baidu.com +short
    echo
done

真实输出:

ini 复制代码
=== A Record ===
111.63.65.247
111.63.65.103
110.242.74.102
124.237.177.164

=== AAAA Record ===
(无IPv6地址)

=== MX Record ===
10 mx.maillb.baidu.com.
20 mx.baidu.com.

=== TXT Record ===
"v=spf1 include:spf1.baidu.com include:spf2.baidu.com ... -all"
"google-site-verification=GHb98-..."

=== NS Record ===
ns4.baidu.com.
ns7.baidu.com.
ns2.baidu.com.
ns3.baidu.com.
dns.baidu.com.

=== SOA Record ===
dns.baidu.com. sa.baidu.com. 2012151067 300 300 2592000 600

第三章: DNS 解析过程详解

3.1 递归查询 vs 迭代查询

scss 复制代码
┌─────────────────── 递归查询 (Recursive) ───────────────────┐
│                                                             │
│  客户端                 递归解析器                            │
│    │                       │                                │
│    │── dig baidu.com ────▶│                                │
│    │                       │── 根服务器 → .com TLD          │
│    │                       │── TLD 服务器 → NS 记录          │
│    │                       │── 权威服务器 → A 记录           │
│    │◀── 110.242.74.102 ──│                                │
│                                                             │
│  客户端只需发一次请求, 解析器负责完成全部查询                     │
└─────────────────────────────────────────────────────────────┘

┌─────────────────── 迭代查询 (Iterative) ───────────────────┐
│                                                             │
│  客户端                        DNS 层级                       │
│    │                             │                           │
│    │── dig baidu.com ──────────▶│ 根服务器                    │
│    │◀── 去问 .com TLD ─────────│                            │
│    │── dig baidu.com ──────────▶│ .com TLD 服务器              │
│    │◀── 去问 ns1.baidu.com ───│                            │
│    │── dig baidu.com ──────────▶│ ns1.baidu.com (权威)       │
│    │◀── 110.242.74.102 ───────│                            │
│                                                             │
│  客户端自己逐步查询, 每步只获取下一个线索                        │
└─────────────────────────────────────────────────────────────┘

实际使用: 客户端通常使用递归查询 (发送给 ISP/公共 DNS 解析器), DNS 服务器之间使用迭代查询。

3.2 DNS 缓存机制

scss 复制代码
┌──────────────────────────────────────────────────────────────┐
│                       DNS 缓存层级                            │
│                                                              │
│  ┌─────────────┐                                             │
│  │ 应用层缓存    │  Chrome/curl 内置 DNS 缓存 (~1分钟)          │
│  └──────┬──────┘                                             │
│         ▼                                                    │
│  ┌─────────────┐                                             │
│  │ OS 缓存      │  systemd-resolved / nscd (由 TTL 决定)       │
│  └──────┬──────┘                                             │
│         ▼                                                    │
│  ┌─────────────┐                                             │
│  │ 递归解析器    │  8.8.8.8 / 1.1.1.1 的大规模缓存              │
│  │ 缓存         │  (命中率 >90%)                              │
│  └──────┬──────┘                                             │
│         ▼                                                    │
│  ┌─────────────┐                                             │
│  │ 权威服务器    │  原始数据源, 不缓存                         │
│  └─────────────┘                                             │
└──────────────────────────────────────────────────────────────┘

缓存控制: 每条 DNS 记录都有 TTL (Time To Live), 单位秒。

  • baidu.com. 507 IN A → 507 秒内可以缓存
  • TTL 越短 = 变更越灵活, 但查询次数越多
  • CDN 常用短 TTL (60-300秒) 实现快速切换

3.3 DNS 解析超时与重试

ini 复制代码
客户端超时参数 (dig):
  +time=N    → 单次查询超时 (默认 5 秒)
  +tries=N   → 重试次数 (默认 3 次)
  
解析器行为:
  第1次: 发送查询, 等待 5 秒
  第2次: 超时后重试, 等待 5 秒  
  第3次: 再次超时后重试, 等待 5 秒
  失败: SERVFAIL 或超时错误

总最长时间 = time × tries = 5s × 3 = 15 秒

3.4 上机实操: 完整解析追踪 (+trace)

dig +trace 模拟迭代查询过程, 展示 DNS 解析的每一步:

bash 复制代码
$ dig +trace +nodnssec baidu.com

实测输出 (3步解析):

python 复制代码
步骤 1 --- 根服务器 (Root Servers):
.           216252  IN  NS  a.root-servers.net.
.           216252  IN  NS  b.root-servers.net.
... (13 组根服务器)
;; Received 239 bytes from 127.0.0.53#53 in 1 ms

步骤 2 --- .com TLD 服务器:
com.        172800  IN  NS  a.gtld-servers.net.
com.        172800  IN  NS  b.gtld-servers.net.
... (13 个 .com TLD 服务器)
;; Received 834 bytes from 170.247.170.2#53(b.root-servers.net) in 40 ms
│
│ 返回 baidu.com 的 NS 记录:
│ baidu.com.  172800  IN  NS  ns2.baidu.com.
│ baidu.com.  172800  IN  NS  ns3.baidu.com.
│ baidu.com.  172800  IN  NS  ns4.baidu.com.
│ baidu.com.  172800  IN  NS  ns1.baidu.com.
│ baidu.com.  172800  IN  NS  ns7.baidu.com.
;; Received 352 bytes from 192.26.92.30#53(c.gtld-servers.net) in 219 ms

步骤 3 --- 权威服务器 (Authoritative):
baidu.com.  600   IN  A   111.63.65.103
baidu.com.  600   IN  A   124.237.177.164
baidu.com.  600   IN  A   110.242.74.102
baidu.com.  600   IN  A   111.63.65.247
;; Received 444 bytes from 180.76.76.92#53(ns7.baidu.com) in 4 ms

时间分析:

ini 复制代码
总时间: 1ms + 40ms + 219ms + 4ms = 264ms
├── 本地缓存读取根服务器列表:   1ms
├── 根 → TLD (b.root-servers):  40ms
├── TLD → 权威 (c.gtld):       219ms  ← 最耗时! 跨太平洋
└── 权威 → 回答 (ns7.baidu):    4ms  ← 国内, 很快

3.5 上机实操: 缓存刷新与验证

bash 复制代码
# 刷新 systemd-resolved 缓存
$ resolvectl flush-caches
# Cache flushed

# 验证缓存效果 --- 首次查询 vs 缓存命中
$ dig baidu.com +stats | grep "Query time"
Query time: 1 msec         # 本地缓存命中

$ dig @1.1.1.1 baidu.com +stats | grep "Query time"  
Query time: 2 msec         # 远程解析器 (香港节点)

3.6 上机实操: 不同 DNS 解析器延迟对比

bash 复制代码
$ for ns in 1.1.1.1 8.8.8.8 9.9.9.9 223.5.5.5; do
    t=$(dig @$ns baidu.com +stats | grep "Query time" | awk '{print $4}')
    echo "@$ns: ${t} ms"
done

实测结果 (香港 ECS → 各解析器):

DNS 解析器 IP 延迟 说明
Cloudflare 1.1.1.1 2 ms 全球 Anycast, 香港有节点
Google 8.8.8.8 2 ms 香港节点就近响应
Quad9 9.9.9.9 38 ms 新加坡/日本节点
AliDNS 223.5.5.5 46 ms 中国大陆, 跨境延迟

第四章: DNS 配置与管理

4.1 BIND9 简介

BIND (Berkeley Internet Name Domain) 是最古老、最广泛使用的 DNS 服务器软件, 目前由 ISC (Internet Systems Consortium) 维护。

bash 复制代码
BIND9 架构:
┌──────────────────────────────────────────┐
│               named (BIND 守护进程)        │
│                                          │
│  ┌────────────────┐  ┌────────────────┐  │
│  │ named.conf     │  │ 区域文件        │  │
│  │ (主配置文件)    │  │ db.example.com │  │
│  │                │  │ (DNS 记录)     │  │
│  │ options {}     │  │                │  │
│  │ zone {}        │  │ $TTL 86400     │  │
│  └────────────────┘  │ @ IN SOA ...   │  │
│                      │ www IN A ...   │  │
│                      └────────────────┘  │
└──────────────────────────────────────────┘

4.2 上机实操: 配置权威 DNS 服务器

实验环境: tcpip-01, BIND 9.18.39

步骤 1: 确认 BIND9 状态
bash 复制代码
$ systemctl status bind9
● named.service - BIND Domain Name Server
     Active: active (running) since Tue 2026-06-02 13:18:24 CST
     Memory: 23.0M
     
$ named -v
BIND 9.18.39-0ubuntu0.24.04.5-Ubuntu (Extended Support Version)
步骤 2: 配置主区域声明

创建 /etc/bind/named.conf.local:

bash 复制代码
zone "example.local" {
    type master;                        # 主 DNS 服务器
    file "/etc/bind/db.example.local";  # 区域数据文件路径
};

zone "1.168.192.in-addr.arpa" {         # 反向解析区域
    type master;
    file "/etc/bind/db.192.168.1";
};

配置项详解:

参数 含义
type master 主服务器 该节点是此区域的数据权威来源
type slave 从服务器 从主服务器同步区域数据
file 文件路径 相对于 directory 选项 (默认 /etc/bind)
步骤 3: 创建区域数据文件

创建 /etc/bind/db.example.local:

ini 复制代码
$TTL 86400                            ; 默认 TTL = 1 天
@       IN      SOA     ns1.example.local. admin.example.local. (
                        2024060201     ; Serial (YYYYMMDDNN 格式)
                        3600           ; Refresh (1小时)
                        1800           ; Retry (30分钟)
                        604800         ; Expire (7天)
                        86400 )        ; Minimum TTL (1天)

; Name Server 记录
@       IN      NS      ns1.example.local.

; A 记录
@       IN      A       192.168.1.100  ; @ 代表区域本身 example.local.
ns1     IN      A       192.168.1.100
www     IN      A       192.168.1.101
mail    IN      A       192.168.1.102

; CNAME 别名
ftp     IN      CNAME   www.example.local.

区域文件格式说明:

符号 含义 示例
@ 代表当前区域名 example.local.
IN Internet 类 (固定) 几乎所有记录都用 IN
空白/制表符 字段分隔符 至少一个空格
; 注释 (行内) ; 这是注释
( ) 多行括号 SOA 记录常用
步骤 4: 验证配置并测试
bash 复制代码
# 检查配置文件语法
$ named-checkconf
(无输出 = 配置正确)

# 检查区域文件
$ named-checkzone example.local /etc/bind/db.example.local
zone example.local/IN: loaded serial 2024060201
OK

# 重启 BIND9 使配置生效
$ systemctl restart bind9

# 测试本地 DNS 查询
$ dig @localhost example.local A +short
192.168.1.100

$ dig @localhost www.example.local A +short
192.168.1.101

$ dig @localhost ftp.example.local CNAME +short
www.example.local.              # CNAME 正确解析

$ dig @localhost ns1.example.local A +short
192.168.1.100

$ dig @localhost example.local SOA +short
ns1.example.local. admin.example.local. 2024060201 3600 1800 604800 86400

$ dig @localhost example.local NS +short
ns1.example.local.

4.3 DNS 主从复制架构

bash 复制代码
┌─────────────────┐         Zone Transfer (AXFR/IXFR)        ┌─────────────────┐
│  Master (主)     │────────────────────────────────────────▶│  Slave (从)      │
│  type: master   │         TCP 53 端口                      │  type: slave    │
│                 │                                          │                 │
│  Serial:        │   从服务器检测 Serial 是否增加:             │  Serial:        │
│  2024060201     │   新增 → 拉取完整区域 (AXFR)               │  2024060201     │
│                 │   相同 → 不操作                           │                 │
└─────────────────┘                                          └─────────────────┘

从服务器配置:
zone "example.local" {
    type slave;
    file "/var/cache/bind/db.example.local";  # 从服务器缓存位置
    masters { 192.168.1.100; };               # 主服务器 IP
};

主从复制关键参数:

参数 作用 推荐值
Serial 版本号, 每次修改必须递增 YYYYMMDDNN 格式
Refresh 从服务器检查主服务器的间隔 3600 (1小时)
Retry 刷新失败重试间隔 1800 (30分钟)
Expire 无法联系主服务器后数据有效期 604800 (7天)
Minimum TTL 否定缓存 TTL 86400 (1天)

第五章: DNS 安全与防护

5.1 DNS 安全威胁全景

scss 复制代码
┌──────────────────────────────────────────────────────────────┐
│                     DNS 安全威胁矩阵                           │
├─────────────────────┬────────────────┬───────────────────────┤
│ 威胁类型             │ 攻击方式        │ 危害                    │
├─────────────────────┼────────────────┼───────────────────────┤
│ DNS 劫持            │ 篡改 DNS 响应   │ 流量劫持到钓鱼网站       │
│ (DNS Hijacking)     │                │                       │
├─────────────────────┼────────────────┼───────────────────────┤
│ DNS 缓存投毒         │ 向递归解析器注入 │ 大量用户被重定向         │
│ (Cache Poisoning)   │ 伪造响应        │                       │
├─────────────────────┼────────────────┼───────────────────────┤
│ DNS 放大攻击         │ 伪造源IP发小请求  │ 反射型 DDoS, 放大 50x   │
│ (Amplification)     │ 收大响应        │                       │
├─────────────────────┼────────────────┼───────────────────────┤
│ DNS 隧道             │ DNS 协议传数据   │ 数据泄露绕过防火墙       │
│ (Tunneling)         │                │                       │
└─────────────────────┴────────────────┴───────────────────────┘

5.2 DNSSEC (DNS Security Extensions)

DNSSEC 通过数字签名保证 DNS 数据的完整性和真实性, 防止篡改。

markdown 复制代码
DNSSEC 签名链:
                    ┌──────┐
                    │  .   │  Root KSK/ZSK (信任锚)
                    └──┬───┘
                       │ DS 记录 (委派签名者)
                    ┌──┴──┐
                    │ com  │  TLD ZSK 签名
                    └──┬───┘
                       │ DS 记录
                    ┌──┴─────┐
                    │ baidu   │  权威 ZSK 签名所有记录
                    └────────┘

DNSSEC 关键记录类型:

记录 全称 作用
RRSIG Resource Record Signature 资源记录的数字签名
DNSKEY DNS Public Key 区域的公钥
DS Delegation Signer 父区域对子区域 DNSKEY 的哈希
NSEC/NSEC3 Next Secure 证明某个域名不存在

DNSSEC 验证:

bash 复制代码
# 查询启用 DNSSEC 的域名
$ dig +dnssec cloudflare.com
cloudflare.com.  300  IN  A       104.16.133.229
cloudflare.com.  300  IN  A       104.16.132.229
cloudflare.com.  300  IN  RRSIG   A 13 2 300 ...  # DNSSEC 签名

# flags 中的 ad (Authenticated Data) 表示 DNSSEC 验证通过

DNSSEC 验证状态:

bash 复制代码
$ resolvectl status
DNSSEC=no/unsupported     # 当前环境未启用 DNSSEC

5.3 DNS over HTTPS (DoH) 与 DNS over TLS (DoT)

传统 DNS 使用 UDP 53 端口明文传输, 容易被监听和篡改。DoH 和 DoT 提供加密传输。

scss 复制代码
┌──────────────────────────────────────────────────────────────┐
│                   DNS 加密传输对比                            │
├──────────┬──────────────┬──────────────┬────────────────────┤
│ 方案      │ 端口          │ 协议         │ 伪装性              │
├──────────┼──────────────┼──────────────┼────────────────────┤
│ 传统 DNS  │ 53 (UDP/TCP) │ DNS 明文      │ 容易被识别和拦截     │
│ DoT      │ 853 (TCP)    │ DNS over TLS │ 独立端口, 可被封锁   │
│ DoH      │ 443 (TCP)    │ DNS over HTTPS│ 与普通 HTTPS 无异    │
│ DoQ      │ 853 (UDP)    │ DNS over QUIC│ 实验阶段             │
└──────────┴──────────────┴──────────────┴────────────────────┘

主流 DoH/DoT 服务商:

服务商 DoH URL DoT 地址
Cloudflare https://1.1.1.1/dns-query 1.1.1.1:853
Google https://dns.google/dns-query 8.8.8.8:853
Quad9 https://dns.quad9.net/dns-query 9.9.9.9:853

5.4 DNS 安全最佳实践

  1. 启用 DNSSEC --- 为权威区域签名, 递归解析器启用验证
  2. 使用 DoH/DoT --- 加密客户端到解析器的通信
  3. 限制区域传输 --- 只允许授权的从服务器执行 AXFR
  4. 隐藏 BIND 版本 --- version "Not disclosed";
  5. 限制递归查询 --- 只对信任的客户端开放递归
  6. 启用查询日志 --- 审计和异常检测
  7. 定期更新 --- BIND 安全补丁及时应用

第六章: DNS 性能优化

6.1 DNS 性能模型

bash 复制代码
DNS 查询延迟 = 网络延迟 + 解析器处理时间 + (缓存未命中时的迭代查询时间)

优化策略:
┌──────────────────────────────────────────────────────────────┐
│                                                              │
│  本地缓存 (dnsmasq/systemd-resolved)                          │
│      ↓ 缓存命中率 >90% → 延迟 < 1ms                          │
│                                                              │
│  Anycast 就近接入 (1.1.1.1 / 8.8.8.8)                        │
│      ↓ 自动路由到最近节点                                     │
│                                                              │
│  DNS 预解析 (dns-prefetch)                                   │
│      ↓ 浏览器提前解析, 用户点击时无需等待                      │
│                                                              │
│  CDN 集成                                                     │
│      ↓ 基于 DNS 返回最近节点的 IP                              │
│                                                              │
└──────────────────────────────────────────────────────────────┘

6.2 上机实操: dnsmasq 本地缓存

dnsmasq 是一个轻量级 DNS 转发器和 DHCP 服务器, 常用于本地 DNS 缓存。

bash 复制代码
# 安装 dnsmasq
$ apt-get install -y dnsmasq
$ dnsmasq -v
Dnsmasq version 2.90

配置 /etc/dnsmasq.d/dns-test.conf:

ini 复制代码
port=5353              # 监听端口 (避免与 systemd-resolved 冲突)
cache-size=1000        # 缓存 1000 条 DNS 记录
server=8.8.8.8         # 上游 DNS 1
server=1.1.1.1         # 上游 DNS 2
log-queries            # 记录查询日志 (调试用)
bash 复制代码
$ systemctl restart dnsmasq

缓存效果验证:

bash 复制代码
# 首次查询 (Cache Miss)
$ dig @127.0.0.1 -p 5353 baidu.com +stats | grep "Query time"
;; Query time: 2 msec

# 二次查询 (Cache Hit)
$ dig @127.0.0.1 -p 5353 baidu.com +stats | grep "Query time"
;; Query time: 0 msec        ← 0ms! 本地内存缓存命中

缓存命中率分析:

makefile 复制代码
首次查询: 2ms  (网络往返 Cloudflare)
二次查询: 0ms  (内存缓存命中)
差异:     2ms  (消除了一次网络往返)

6.3 上机实操: DNS 查询性能基准测试

使用 Python 脚本对 10 个热门域名进行 3 轮 A 记录查询基准测试:

实验结果 (tcpip-01, 本地解析器):

域名 Min (ms) Avg (ms) Max (ms)
baidu.com 19.0 19.5 20.0
aliyun.com 18.9 19.5 20.6
qq.com 19.0 19.9 20.6
google.com 19.4 20.1 20.9
zhihu.com 19.6 23.7 31.7
163.com 20.5 20.7 21.1
sohu.com 21.1 26.6 37.1
bilibili.com 19.4 19.8 20.3
github.com 19.8 19.8 19.9
stackoverflow.com 19.1 19.7 20.5
平均值 19.7 20.9 ---

30 次查询, 平均 20.9ms/次 --- 本地缓存+华为云内网 DNS 组合性能良好。

外部解析器延迟对比 (baidu.com, 3次平均):

解析器 IP Avg (ms) 评价
Cloudflare 1.1.1.1 22.1 ★★★★★ 最优
Google 8.8.8.8 20.6 ★★★★★ 最优
114DNS 114.114.114.114 55.8 ★★★ 一般
Quad9 9.9.9.9 57.1 ★★ 较慢
AliDNS 223.5.5.5 66.4 ★ 跨境延迟大

结论: 在香港 ECS 上, Cloudflare (1.1.1.1) 和 Google (8.8.8.8) 延迟最低 (~20ms), 因为两者在香港都有节点。AliDNS (223.5.5.5) 服务器在中国大陆, 跨境的 66ms 主要是网络延迟。

6.4 DNS 预解析 (DNS Prefetch)

浏览器可以在用户点击链接前提前完成 DNS 解析:

html 复制代码
<!-- HTML 级别 DNS 预解析 -->
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="dns-prefetch" href="//api.example.com">
<link rel="dns-prefetch" href="//analytics.example.com">
css 复制代码
用户打开页面
    │
    ├── 浏览器解析 HTML, 发现 dns-prefetch
    │
    ├── 后台静默解析 cdn.example.com → 1.2.3.4
    │
    └── 用户 3 秒后点击 CDN 链接
        → 无需 DNS 查询, 直接连接 1.2.3.4 ✓

性能收益: DNS 预解析可节省 20-120ms (一次 DNS 查询的 RTT)。


第七章: 云 DNS 服务实战

7.1 主流云 DNS 服务对比

服务 提供商 SLA 特点
Route 53 AWS 100% 与 AWS 深度集成, 流量路由策略丰富
Cloudflare DNS Cloudflare 100% 全球最大 Anycast 网络, 免费 CDN 集成
Google Cloud DNS Google 100% 与 GCP 集成, Anycast
Azure DNS Microsoft 100% 与 Azure 深度集成
AliDNS 阿里云 99.99% 中国大陆解析最优

7.2 Cloudflare DNS API 操作

bash 复制代码
# 获取 Zone ID
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=example.com" \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json"

# 响应示例:
{
  "result": [{
    "id": "023e105f4ecef8ad9ca31a8372d0c353",
    "name": "example.com",
    "status": "active"
  }]
}

# 创建 DNS A 记录
curl -X POST "https://api.cloudflare.com/client/v4/zones/{ZONE_ID}/dns_records" \
    -H "Authorization: Bearer YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data '{
      "type": "A",
      "name": "test",
      "content": "192.168.1.100",
      "ttl": 120,
      "proxied": false
    }'

Cloudflare DNS 代理模式 (proxied):

vbnet 复制代码
proxied: false (仅 DNS):
  用户 → DNS 解析 → 真实 IP → 直接连接服务器

proxied: true (橙色云朵):
  用户 → DNS 解析 → Cloudflare CDN IP → Cloudflare 代理 → 真实服务器
                                            ↑
                                     DDoS 防护 / CDN 缓存 / WAF

7.3 Terraform 管理 DNS (DNS as Code)

hcl 复制代码
# main.tf
provider "cloudflare" {
  api_token = var.cloudflare_api_token
}

resource "cloudflare_record" "www" {
  zone_id = var.zone_id
  name    = "www"
  value   = "192.168.1.100"
  type    = "A"
  ttl     = 3600
  proxied = true
}

resource "cloudflare_record" "api" {
  zone_id = var.zone_id
  name    = "api"
  value   = "api-gateway.example.com"
  type    = "CNAME"
  ttl     = 300
}
bash 复制代码
terraform init
terraform plan
terraform apply

第八章: DNS 故障排查

8.1 上机实操: tcpdump 抓包分析 DNS

bash 复制代码
# 抓取 DNS 流量到文件
$ tcpdump -i any -n port 53 -w /tmp/dns_capture.pcap &

# 同时生成 DNS 查询流量
$ dig baidu.com A +short
$ dig google.com AAAA +short
$ dig microsoft.com MX +short

# 等待抓包完成
$ fg  # 或 Ctrl+C 停止 tcpdump

tcpdump 实测输出 (DNS 协议解析):

less 复制代码
# systemd-resolved 本地查询 (lo 接口)
13:19:54.179644 lo  In  IP 127.0.0.1.51555 > 127.0.0.53.53:
    45987+ [1au] A? baidu.com. (50)
13:19:54.179806 lo  In  IP 127.0.0.53.53 > 127.0.0.1.51555:
    45987 4/0/1 A 124.237.177.164, A 111.63.65.103,
    A 110.242.74.102, A 111.63.65.247 (102)

# 上游 DNS 查询 (eth0 接口) --- 缓存未命中时
13:19:54.200251 eth0 Out IP 192.168.0.5.52792 > 100.125.3.250.53:
    40011+ [1au] AAAA? google.com. (39)
13:19:54.200682 eth0 In  IP 100.125.3.250.53 > 192.168.0.5.52792:
    40011 1/0/1 AAAA 2404:6800:4005:812::200e (67)

tcpdump DNS 字段解析:

less 复制代码
127.0.0.1.51555 > 127.0.0.53.53:   45987+ [1au] A? baidu.com. (50)
    ↑ 源端口               ↑ 目的端口  ↑ ID   ↑ EDNS  ↑ 查询类型  ↑域名  ↑包大小
ruby 复制代码
127.0.0.53.53 > 127.0.0.1.51555:   45987 4/0/1 A ...
    ↑ 响应                    ↑ 匹配 ID  ↑ 回答/权威/附加计数

抓包数据揭示的架构:

erlang 复制代码
dig (客户端)                     systemd-resolved                 华为云 DNS
127.0.0.1:随机端口              127.0.0.53:53                    100.125.3.250:53
    │                                │                               │
    │── query baidu.com A ──────────▶│                               │
    │                                │── (缓存命中或转发)              │
    │◀── answer 4 IPs ──────────────│                               │
    │                                │                               │
    │── query google.com AAAA ─────▶│                               │
    │                                │── query (缓存未命中) ─────────▶│
    │                                │◀── answer ───────────────────│
    │◀── answer ────────────────────│                               │

8.2 DNS 故障排查命令速查

bash 复制代码
# 1. 检查域名是否存在
dig +short example.com A

# 2. 检查 NS 服务器是否可达
dig +short example.com NS
dig @ns1.example.com example.com SOA

# 3. 检查域名委派一致性
dig +trace +nodnssec example.com

# 4. 检查 DNSSEC 配置
dig +dnssec example.com SOA

# 5. 带超时和重试的快速检查
dig +short +time=1 +tries=1 example.com

# 6. 仅显示回答部分
dig +nocmd example.com any +noall +answer

# 7. 检查反向解析
dig -x 8.8.8.8

# 8. 监听 DNS 流量
tcpdump -i any -n port 53

8.3 常见 DNS 问题诊断流程

ruby 复制代码
问题: 网站打不开, 怀疑 DNS 问题

步骤 1: 确认是否为 DNS 问题
  $ dig example.com
  → NXDOMAIN → 域名不存在或拼写错误
  → SERVFAIL → DNS 服务器故障
  → NOERROR (有 IP) → DNS 正常, 问题在网络/应用层

步骤 2: 检查 NS 委派
  $ dig +trace example.com
  → 在哪一步停止? 根? TLD? 权威?

步骤 3: 检查权威服务器
  $ dig @ns1.example.com example.com SOA
  → 权威服务器是否响应? Serial 是否合理?

步骤 4: 清除本地缓存后重试
  $ resolvectl flush-caches
  $ dig example.com

步骤 5: 更换 DNS 解析器对比
  $ dig @1.1.1.1 example.com
  $ dig @8.8.8.8 example.com
  → 是否所有解析器都失败? 特定解析器的问题?

8.4 DNS 响应状态码

状态码 含义 常见原因
NOERROR (0) 查询成功 ---
FORMERR (1) 格式错误 客户端发送了格式错误的查询
SERVFAIL (2) 服务器失败 权威服务器无响应、DNSSEC 验证失败
NXDOMAIN (3) 域名不存在 域名拼写错误、未注册
NOTIMP (4) 未实现 请求的查询类型不被支持
REFUSED (5) 拒绝 服务器策略禁止响应(如未授权递归)

第九章: DNS 与容器化

9.1 Kubernetes DNS 架构 (CoreDNS)

perl 复制代码
┌──────────────────────────────────────────────────────────────┐
│                  Kubernetes DNS 服务发现                       │
│                                                              │
│  Pod A (default ns)       CoreDNS (kube-system)              │
│  │                             │                             │
│  │ nslookup my-svc            │                             │
│  │───────────────────────────▶│                             │
│  │                             │ my-svc.default.svc.cluster.local
│  │                             │ → ClusterIP                 │
│  │◀───────────────────────────│                             │
│  │                             │                             │
│  │ nslookup my-svc.prod       │                             │
│  │───────────────────────────▶│                             │
│  │                             │ my-svc.prod.svc.cluster.local
│  │                             │ → ClusterIP (跨命名空间)      │
│  │◀───────────────────────────│                             │
└──────────────────────────────────────────────────────────────┘

Kubernetes DNS 命名规范:

xml 复制代码
<service-name>.<namespace>.svc.<cluster-domain>

示例:
  my-app.default.svc.cluster.local
  └─服务名─┘ └命名空间┘ └──固定后缀──┘

CoreDNS ConfigMap 核心配置:

yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
        errors
        health
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        forward . /etc/resolv.conf       # 上游 DNS
        cache 30
        loop
        reload
        loadbalance
    }

CoreDNS 插件说明:

插件 作用
kubernetes 基于 K8s API 提供服务发现
forward 将非集群域名转发到上游 DNS
cache 缓存查询结果 (30秒)
prometheus 暴露监控指标
loadbalance 对多 A 记录响应轮询排序

9.2 Docker 自定义 DNS

bash 复制代码
# 指定 DNS 服务器
docker run --dns=8.8.8.8 --dns=1.1.1.1 nginx

# 指定 DNS 搜索域
docker run --dns=8.8.8.8 --dns-search=example.com nginx

# 在 docker-compose.yml 中
services:
  web:
    image: nginx
    dns:
      - 8.8.8.8
      - 1.1.1.1
    dns_search:
      - example.com

Docker DNS 解析优先级:

markdown 复制代码
1. 容器内 /etc/hosts (--add-host)
2. 内置 DNS 服务器 (127.0.0.11) --- 容器间服务发现
3. --dns 指定的外部 DNS 服务器
4. 宿主机 /etc/resolv.conf

9.3 Kubernetes DNS 测试

bash 复制代码
# 创建临时 Pod 测试 DNS
kubectl run -it --rm debug --image=busybox:1.28 --restart=Never -- sh

# 测试集群内 DNS
nslookup kubernetes.default.svc.cluster.local

# 测试外部 DNS
nslookup baidu.com

# 查看 CoreDNS Pod
kubectl get pods -n kube-system -l k8s-app=kube-dns

# 查看 CoreDNS 日志
kubectl logs -n kube-system deployment/coredns

第十章: DNS 自动化与 DevOps

10.1 DNS 即代码 (DNS as Code)

将 DNS 配置纳入版本控制, 实现可审计、可回滚、可自动化的 DNS 管理。

scss 复制代码
┌──────────────────────────────────────────────────────────────┐
│                   DNS as Code 工作流                          │
│                                                              │
│  开发者修改 DNS 配置 (Git PR)                                  │
│      │                                                       │
│      ▼                                                       │
│  ┌──────────┐     ┌──────────┐     ┌──────────┐             │
│  │ Git Repo │────▶│ CI/CD    │────▶│ Cloud API│             │
│  │ (TF/Ansi)│     │ (GitHub) │     │ (CF/AWS) │             │
│  └──────────┘     └──────────┘     └──────────┘             │
│      │                  │                  │                 │
│      │  PR Review        │  自动化测试       │  应用变更       │
│      │  (人工审核)        │  (dig 验证)       │  (API 调用)     │
│                                                              │
└──────────────────────────────────────────────────────────────┘

10.2 Ansible 管理 BIND DNS

yaml 复制代码
# playbook.yml
- hosts: dns_servers
  vars:
    domain: example.com
    records:
      - { name: "www", type: "A", value: "192.168.1.101" }
      - { name: "api", type: "A", value: "192.168.1.102" }
      - { name: "mail", type: "CNAME", value: "www.example.com." }

  tasks:
    - name: Deploy zone file from template
      template:
        src: db.example.com.j2
        dest: /etc/bind/db.{{ domain }}
        owner: root
        group: bind
        mode: '0644'
      notify: reload bind9

    - name: Validate zone file
      command: named-checkzone {{ domain }} /etc/bind/db.{{ domain }}
      register: check_result
      changed_when: false

    - name: Display validation result
      debug:
        msg: "{{ check_result.stdout }}"

  handlers:
    - name: reload bind9
      service:
        name: bind9
        state: reloaded

10.3 GitHub Actions 自动化 DNS

yaml 复制代码
# .github/workflows/dns-update.yml
name: Update DNS Records

on:
  push:
    branches: [main]
    paths:
      - 'dns/**'

jobs:
  validate-and-apply:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Validate DNS configuration
        run: |
          # Terraform validate
          cd dns/
          terraform init -backend=false
          terraform validate

      - name: Apply DNS changes
        env:
          CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
          CF_ZONE_ID: ${{ secrets.CF_ZONE_ID }}
        run: |
          cd dns/
          terraform init
          terraform apply -auto-approve

      - name: Verify DNS propagation
        run: |
          sleep 30  # 等待传播
          dig +short www.example.com @1.1.1.1

10.4 DNS 配置版本控制

bash 复制代码
# 初始化 DNS 配置仓库
git init dns-config
cd dns-config/

# 结构化目录
mkdir -p zones/example.com zones/internal
mkdir -p terraform/ ansible/

# 添加 BIND 区域文件
cp /etc/bind/db.example.com zones/example.com/

# 提交
git add .
git commit -m "feat: initial DNS configuration for example.com"
git tag v1.0.0

# 后续变更
vim zones/example.com/db.example.com     # 修改 Serial
git add . && git commit -m "fix: add api.example.com A record"
git tag v1.0.1

附录

附录 A: 实验环境总览

yaml 复制代码
┌─────────────────────────────────────────────────────────────┐
│                  ecs-ee63 集群 (华为云香港)                    │
├──────────┬─────────────────┬──────────────┬─────────────────┤
│ 主机名    │ 公网 IP          │ 内网 IP       │ DNS 角色         │
├──────────┼─────────────────┼──────────────┼─────────────────┤
│ tcpip-01 │ 119.8.59.15     │ 192.168.0.5  │ BIND9 主服务器    │
│ tcpip-02 │ 119.8.110.76    │ 192.168.0.207│ DNS 客户端       │
│ tcpip-03 │ 150.40.239.207  │ 192.168.0.111│ DNS 客户端       │
└──────────┴─────────────────┴──────────────┴─────────────────┘

软件版本:
  BIND:     9.18.39-0ubuntu0.24.04.5-Ubuntu
  DiG:      9.18.39-0ubuntu0.24.04.5-Ubuntu
  Dnsmasq:  2.90
  OS:       Ubuntu 24.04 LTS
  Kernel:   6.8.0

附录 B: 关键实验数据汇总

实验 关键结果
baidu.com A 记录 4 个 IP (110.242.74.102, 111.63.65.103/247, 124.237.177.164)
baidu.com NS 记录 5 个: dns, ns2-4, ns7.baidu.com
baidu.com SOA Serial=2012151067, TTL=600s
www.baidu.com CNAME www.a.shifen.com (CDN 调度)
dig +trace 3 步: Root(1ms)→TLD(40ms)→权威(219ms+4ms) = 264ms
dnsmasq 缓存 Cache miss 2ms → Cache hit 0ms
BIND9 本地区域 example.local 配置成功, checkzone OK
tcpdump 抓包 确认 systemd-resolved(127.0.0.53)→华为云 DNS(100.125.3.250)
性能基准 (10域名×3) 平均 20.9ms/查询, 本地缓存
Cloudflare 延迟 avg=22.1ms (香港节点)
AliDNS 延迟 avg=66.4ms (跨境)

附录 C: Dig 命令速查

命令 作用
dig domain 基础查询 (A 记录)
dig domain A 指定查询 A 记录
dig domain ANY 查询所有记录类型
dig domain +short 简洁输出 (仅结果)
dig domain +trace 追踪解析过程
dig domain +dnssec 查询 DNSSEC 签名
dig -x IP 反向查询 (PTR)
dig @server domain 指定 DNS 服务器
dig domain +stats 显示统计信息
dig domain +noall +answer 仅显示回答部分
dig domain +tcp 强制使用 TCP
dig domain +time=N +tries=M 超时和重试控制

附录 D: DNS 记录类型速查

记录 全称 格式示例 用途
A Address www A 1.2.3.4 IPv4 地址
AAAA IPv6 Address www AAAA 2001:db8::1 IPv6 地址
CNAME Canonical Name www CNAME host.example.com. 别名
MX Mail Exchange @ MX 10 mail.example.com. 邮件服务器
TXT Text @ TXT "v=spf1 ..." 文本信息
NS Name Server @ NS ns1.example.com. 权威服务器
SOA Start of Authority @ SOA ns1 hostmaster (serial ...) 管理信息
PTR Pointer 4.3.2.1 PTR host.example.com. 反向解析
SRV Service _http SRV 0 5 80 www 服务定位
CAA Certification Authority @ CAA 0 issue "letsencrypt.org" 证书颁发限制
DS Delegation Signer @ DS keytag alg digest-type digest DNSSEC 委派
RRSIG RR Signature DNSSEC 签名记录 DNSSEC 验证

附录 E: 公共 DNS 解析器速查

名称 IPv4 IPv6 DoH URL 特点
Cloudflare 1.1.1.1 / 1.0.0.1 2606:4700::1111 https://1.1.1.1/dns-query 快, 隐私优先
Google 8.8.8.8 / 8.8.4.4 2001:4860::8888 https://dns.google/dns-query 稳定, 全球覆盖
Quad9 9.9.9.9 / 149.112.112.112 2620:fe::fe https://dns.quad9.net/dns-query 安全过滤
OpenDNS 208.67.222.222 2620:119:35::35 --- 内容过滤
AliDNS 223.5.5.5 / 223.6.6.6 2400:3200::1 --- 中国大陆最优
114DNS 114.114.114.114 --- --- 中国大陆
DNSPod 119.29.29.29 --- https://doh.pub/dns-query 腾讯云 DNS

附录 F: BIND9 配置参数速查

named.conf 关键选项:

选项 默认值 说明
directory /var/cache/bind 工作目录
listen-on { any; } 监听地址
listen-on-v6 { any; } IPv6 监听
allow-query { any; } 允许查询的来源
allow-transfer { none; } 允许区域传输的来源
recursion yes 是否提供递归查询
allow-recursion { localnets; } 允许递归的来源
forwarders {} 上游转发器
dnssec-validation auto DNSSEC 验证模式
version (真实版本号) 版本字符串

SOA 记录参数建议:

参数 小型站点 中型站点 大型/CDN
Refresh 3600 (1h) 3600 (1h) 900 (15min)
Retry 1800 (30min) 900 (15min) 300 (5min)
Expire 604800 (7d) 1209600 (14d) 604800 (7d)
Minimum TTL 86400 (1d) 3600 (1h) 300 (5min)

附录 G: DNS 查询头 Flags 详解

ini 复制代码
dig 输出中的 flags 字段:
flags: qr rd ra

qr = Query Response      1=响应, 0=查询
aa = Authoritative Answer 权威回答 (来自权威服务器)
tc = Truncated            响应被截断 (需 TCP 重试)
rd = Recursion Desired    客户端请求递归
ra = Recursion Available  服务器支持递归
ad = Authenticated Data   DNSSEC 验证通过
cd = Checking Disabled    禁用 DNSSEC 验证

附录 H: 学习资源

官方文档:

书籍推荐:

  • 《DNS and BIND》(第5版) --- Cricket Liu, Paul Albitz (O'Reilly)
  • 《DNS Security: Defending the Domain Name System》
  • 《Alternative DNS Servers: Choice and Deployment》

在线工具:

附录 I: 技能评估标准

能力维度 权重 评估标准
基础概念理解 20% DNS 层级结构、记录类型、解析过程
实际操作能力 40% dig/nslookup/tcpdump 使用, BIND9 配置, 故障排查
安全知识 25% DNSSEC、DoH/DoT、DNS 攻击防护
架构设计 15% DNS 高可用、CDN 集成、多环境管理

学习建议: 按章节顺序逐步学习, 每个知识点配合实操案例。建立自己的实验环境, 从本地 BIND9 配置开始, 逐步扩展到云 DNS 服务和容器化部署。关注 DNS 协议最新发展 (DNS over QUIC/HTTP3 等)。
安全提醒: 所有实验在授权环境中进行。不要对非授权域名进行压力测试。定期更新 DNS 软件版本以修复安全漏洞。生产环境务必启用 DNSSEC 和访问控制。


文档版本: v1.0 | 生成时间: 2026-06-02 | 实验集群: ecs-ee63 (华为云香港)

相关推荐
ayqy贾杰1 小时前
有AI了,我当超大头兵还苟得住吗?
前端·后端·架构
muddjsv1 小时前
Hadoop 与 HBase 深度剖析:从架构原理到实战应用
hadoop·架构·hbase
上海云盾第一敬业销售1 小时前
游戏盾架构解析:保障在线游戏的安全
安全·游戏·架构
该昵称用户已存在1 小时前
开源即自由:MyEMS 能源管理系统的技术栈解耦与兼容性架构
架构·开源·能源
之歆1 小时前
在 IntelliJ IDEA 里复刻 Cursor 式内联审查:一篇够长的架构复盘-从入门到放弃
java·架构·intellij-idea
源码宝1 小时前
基于SpringBoot+Vue+小程序+Android的智慧校园电子班牌系统源码示例
vue.js·spring boot·架构·智慧校园·电子班牌·源码·代码
IronMurphy1 小时前
微服务拷打最后一讲!!!
java·微服务·架构
lauo2 小时前
从算力消耗到Token生产:ibbot手机如何重构AI时代的移动终端价值范式
人工智能·智能手机·重构·架构·开源·github
聚铭网络2 小时前
聚铭网络荣获《一种分层架构的安全运营平台的数据保护方法及系统》发明专利
网络·安全·架构