DNS 与命名:从根服务器到本地解析
0. 元信息
- 主题路径:
docs/topics/network/subtopics/dns-and-naming/README.md - 父主题:
network - 主分类:计算机基础
- 辅助分类:安全与可靠性
- 适合对象:会用
dig、curl、能看懂 UDP/TCP 抓包,知道 IP 与端口概念 - 建议周期:3~4 周(每周 6~8 小时,含抓包、命令实验、复盘)
- 前置知识:
tcp-ip-stack(UDP/TCP 与端口)、tcp-and-udp;会ip、ss基本用法 - 最终目标:能读懂 DNS 报文结构、解释递归与迭代解析、用
dig+tcpdump排查解析失败、能配置 DoH/DoT 客户端
1. 学习路线
DNS 角色与层级(根 / TLD / 权威 / 递归)
→ 报文格式:Header / Question / Answer / Authority / Additional
→ 资源记录类型:A / AAAA / CNAME / MX / NS / TXT / SOA / PTR / SRV / OPT
→ 解析流程:递归 vs 迭代;glue record;粘合记录
→ 缓存与 TTL:Negative TTL、TTL 失效、CDN 调度
→ 权威与区域传送:AXFR / IXFR;主从同步
→ DNSSEC:DS / DNSKEY / RRSIG / NSEC;信任链
→ 加密 DNS:DoT(853/TCP)/ DoH(443/TCP+HTTPS)/ DoQ(853/UDP)
→ 排障与生态:BIND / Unbound / CoreDNS / dnsmasq / systemd-resolved
每一步都要 dig +trace 一次真实的域名。DNS 不抓包只背字段,永远记不住——看到 wire format 字节流才算入门。
2. 阶段周数分配
| 阶段 | 3 周方案 | 4 周方案 | 备注 |
|---|---|---|---|
| 1. 层级与角色 | 0.5 周 | 0.75 周 | 看根、TLD、权威三层;理解 NS 与 glue |
| 2. 报文与 RR | 0.5 周 | 0.75 周 | tcpdump -X udp port 53 对照 RFC 1035 |
| 3. 递归与迭代 | 0.5 周 | 0.5 周 | dig +trace + dig +norecurse 区分 |
| 4. 缓存与 TTL | 0.5 周 | 0.5 周 | 改 TTL 观察命中;CNAME 链追踪 |
| 5. 区域传送 | 0.5 周 | 0.5 周 | dig AXFR 拉一次主区域(白名单域) |
| 6. DNSSEC | 0.5 周 | 0.75 周 | 验证链、DS 记录、“ 工具 |
| 7. 加密 DNS | 0.25 周 | 0.25 周 | DoT 与 DoH 抓包对比明文 DNS |
| 8. 排障与生态 | 0.25 周 | 0.5 周 | BIND/Unbound/CoreDNS 配置与日志 |
3. 九阶段表
| 阶段 | 核心知识 | 实践产出 | 可观察学会标准 |
|---|---|---|---|
| 1. 层级 | 根(13 组 a-m.root-servers.net)、TLD(gTLD/ccTLD)、权威 NS、递归 resolver | 一张「example.com」的解析路径图 | 能说出 .com 的 13 组根中任意一组的 IP |
| 2. 报文 | Header 12 字节、Question/Answer/Authority/Additional 四段、资源记录 5 元组 | 一份 hexdump 标注每段 | 能从十六进制找到 QR / Opcode / AA / TC / RD / RA |
| 3. 解析流程 | 递归(client → resolver → 权威迭代)、迭代(resolver 自上而下查)、glue record | dig +trace 全过程记录 | 能解释为什么 NS 记录要附 A 记录(glue) |
| 4. 缓存 | TTL、Negative TTL、CNAME 链、CDN 调度(基于 DNS 地理位置) | 不同 TTL 值的两次 dig 对比 | 能解释「DNS 改了不生效」 |
| 5. 区域传送 | AXFR / IXFR、SOA、主从同步、TSIG | dig @ns1.example.com AXFR example.com | 能从 SOA 看到主从、serial、refresh |
| 6. DNSSEC | DNSKEY / RRSIG / DS / NSEC / NSEC3;信任锚;验证链 | delv +rtrace example.com 或 dig +dnssec | 能解释 KSK/ZSK 分层与轮换 |
| 7. 加密 DNS | DoT(RFC 7858)走 853/TCP、DoH(RFC 8484)走 443/TCP+HTTPS、DoQ(RFC 9250)走 853/UDP | kdig @1.1.1.1 +tls 或 curl --doh-url | 能说出 DoH 与 DoT 各自的隐私边界 |
| 8. 排障 | dig 选项、systemd-resolved、nsswitch.conf、hosts 文件优先级 | 一次完整故障定位报告 | 30 分钟内定位未知解析问题 |
| 9. 综合 | 私有 zone + 签名 + DoH forwarder 串联 | 自建签名 zone 配 DoH 转发 | 能解释每段链路的认证状态 |
4. 第一周任务
| 日 | 任务 | 当天交付 |
|---|---|---|
| Day 1 | dig . NS 看 13 组根;dig com NS 看 .com 顶级;dig example.com NS 看权威 | 三段 dig 输出 + IP 列表 |
| Day 2 | dig +trace example.com 看完整路径;记录每一跳的 server、A、TTL | +trace 全过程 |
| Day 3 | tcpdump -ni any -X udp port 53 抓一次 dig,对照 RFC 1035 §4 标注 Header 12 字节 | hexdump 标注 |
| Day 4 | dig -x 8.8.8.8 看反向解析;dig AAAA example.com 看 IPv6;dig CNAME www.example.com | 三次反向/类型查询 |
| Day 5 | dig @1.1.1.1 dnssec example.com 看 RRSIG;delv +rtrace +v4 example.com 看验证链 | DNSSEC 验证输出 |
| Day 6 | kdig @1.1.1.1 +tls example.com 抓 DoT;curl --doh-url https://1.1.1.1/dns-query https://example.com 抓 DoH | DoT/DoH 抓包对比 |
| Day 7 | 项目:抓一次完整解析链:本机 → 1.1.1.1(DoT)→ 根 → .com → 权威,全程 tcpdump -w 保存 | pcap + 标注 |
Day 7 拆解
步骤 A —— 最小可用(60 分钟)
tcpdump -ni any -w /tmp/dns.pcap port 53 or port 853抓 60 秒;dig +trace example.com;tcpdump -r /tmp/dns.pcap -vv列出请求与应答;- 标注 Header 12 字节中的 QR / RD / RA / ID。
步骤 B —— 补齐边界(30 分钟)
- 同时
dig @1.1.1.1 +tls example.com,对比明文与 DoT 抓包; dig MX gmail.com看 MX 优先级;dig TXT gmail.com看 SPF/DKIM;- 记录到
notes/week1-day7.md。
进阶:稳定通过后,加
dnsperf或自定义脚本对同一域名打 100 次请求,看缓存命中。
5. 阶段通用验收
- 不看 RFC 也能画出 DNS Header 12 字节字段分布;
- 用自己的话解释「为什么 NS 记录要附 A 记录(glue)」;
- 画一张图:client → recursive → root → TLD → authoritative 每跳查询的内容;
- 测试异常:NXDOMAIN(不存在域名)、SERVFAIL(权威宕机)、REFUSED(策略拒绝);
- 准备 3 组自定义数据:CNAME 链、MX 优先级、DNSSEC 失败;
- 记录每次抓包的 BPF 过滤器和命令;
- 能修改
/etc/hosts和/etc/resolv.conf影响解析路径,而不是只能照抄。
6. 最终验收
- 独立完成:手画 DNS Header 字段、抓一次完整解析链、定位一次「DNS 改了不生效」故障;
- 至少完成 6 个实验(层级查询、报文标注、TTL 对比、AXFR、DNSSEC 验证、DoT/DoH 抓包);
- 完成 1 个综合排障项目:模拟一个 DNSSEC 验证失败场景,写定位报告;
- 能用 15 分钟讲清楚「递归 vs 迭代」「TTL 与缓存」「DNSSEC 信任链」「DoH 与 DoT 边界」。
7. 综合项目
首选:DNSSEC 验证失败定位(必做:在两台 Linux 上用 unbound 或 bind 配一个故意签名错误的子域,用 “ + tcpdump 定位链断裂点)。
备选:
- 抓包分析 100 条 DNS 报文并分类(递归 / 迭代 / 缓存命中 / NXDOMAIN);
- 用
coredns自建权威 +unbound自建递归 + DoH forwarder 串联; - 对比
systemd-resolved与dnsmasq在缓存行为上的差异。
综合项目必做要求:
- 场景描述:网络拓扑、预期行为、实际行为;
- 工具选择理由:为什么用
unbound而不是bind?为什么用tcpdump而不是wiresharkGUI? - 核心分析:每一跳的现象、判断依据、根因定位;
- 复现脚本:可重复运行的
unbound.conf/coredns Corefile/dig命令; - 边界测试:换 RR 类型(A / AAAA / MX / TXT)、换方向(正向 / 反向)、换 DO 模式(明文 / DoT / DoH);
- 运行说明:环境依赖(
bind-utils/unbound/ldns/dnsutils)、复现步骤; - README:项目介绍、目录结构、复盘;
- 复盘记录:用时、难点、收获、下一步。
本主题贡献
本主题沉淀 DNS 层级、DNS 递归 / 迭代解析、TTL 缓存、DNSSEC 信任链与 DoH / DoT 加密扩展的工程化,所有结论用 dig +trace + tcpdump + “ + kdig +tls 三角验证。
职责(3 项)
- 画 DNS Header 12 字节字段(ID/QR/Opcode/AA/TC/RD/RA/RCODE + QDCOUNT/ANCOUNT/NSCOUNT/ARCOUNT),能解释 NS 记录的 glue A 记录为什么必须有、TLD 委派胶水如何解决「找 NS 又要找 NS 的 NS」死循环;
- 区分 DNS 递归(client → resolver 代查 + 缓存)与迭代(resolver 自上而下查),用
dig +trace看每一跳的 server 与 RR,能解释 TTL 不生效与systemd-resolved缓存的边界,以及dig +nocache强制绕过; - 验 DNSSEC 信任链(DS 在父域签、DNSKEY/RRSIG 在子域签),用
delv +rtrace +v4验证失败定位,能解释 DoH/DoT 与 DNSSEC 的关系(前者加密、后者防篡改,两者正交)。
交付物(4 项)
dig +trace example.com完整路径记录,每跳 server/A/TTL/flags 标注,对照 RFC 1035 §4.1.1;- 明文 DNS(UDP 53)+ DoT(TCP 853)+ DoH(TCP 443 + HTTPS)三协议抓包对比(
tcpdump -ni any -X 'port 53 or tcp port 853 or tcp port 443'); - DNSSEC 验证失败定位报告(自签一个故意时间窗口错的 zone,用 “ 看 SERVFAIL 根因);
- Unbound / CoreDNS 配置 + DoH forwarder 串联的私有 zone(自签 + 签名 + 验证),含每段链路的认证状态说明。
指标(3 项)
- DNS 解析 P95 ≤ 50 ms(本地 resolver + 缓存命中);
- DNS 缓存命中率 ≥ 80%(同一域名短时间内多次查询命中缓存);
- DNSSEC 验证失败率 ≤ 0.1%(除故意实验外的 SERVFAIL 比例)。
8. 推荐开源资料(按角色分工)
| 角色 | 资料 | 链接 | 用法 |
|---|---|---|---|
| RFC 原文 | RFC 1034 / 1035(DNS) | https://www.rfc-editor.org/rfc/rfc1034 | 概念与报文 |
| RFC 原文 | RFC 4033 / 4034 / 4035(DNSSEC) | https://www.rfc-editor.org/rfc/rfc4033 | DNSSEC 三件套 |
| RFC 原文 | RFC 7858(DoT) | https://www.rfc-editor.org/rfc/rfc7858 | TLS 上的 DNS |
| RFC 原文 | RFC 8484(DoH) | https://www.rfc-editor.org/rfc/rfc8484 | HTTPS 上的 DNS |
| RFC 原文 | RFC 9250(DoQ) | https://www.rfc-editor.org/rfc/rfc9250 | QUIC 上的 DNS |
| 工具手册 | ISC BIND 文档 | https://www.isc.org/bind/ | bind 配置文件 |
| 工具手册 | NLnet Labs Unbound | https://nlnetlabs.nl/projects/unbound/about/ | 验证递归 + DNSSEC |
| 工具手册 | ldns / drill | https://nlnetlabs.nl/projects/ldns/about/ | DNSSEC 验证工具 |
| 工具手册 | CoreDNS | https://coredns.io/manual/toc/ | 云原生权威 / 转发 |
| 中文讲解 | 阿里云 DNS 文档 | https://help.aliyun.com/document_detail/58130.html | 云 DNS 入门 |
| 实验环境 | DNS-OARC | https://www.dns-oarc.net/ | 根与公共 resolver 测速 |
| 抓包练习 | Wireshark 官方样例 pcap | https://wiki.wireshark.org/SampleCaptures | DNS / DoT 真实报文 |
许可证提示:Wireshark 样例 pcap 是公开教学资源;BIND 是 MPL-2.0;Unbound 是 BSD-3-Clause;CoreDNS 是 Apache-2.0。复制或参考配置前先确认许可证。
源码阅读时机:Unbound 源码放到「阶段 8(排障)」之后再读;RFC 原文从 Day 1 就开始对照,但不要一次通读所有 RFC——按当前阶段挑相关章节。
9. 学习资料汇聚(v0.3 自包含)
本节内容基于公开 RFC、ISC/NLnet Labs 文档与个人整理,标注「由本计划生成」处为计划自写。本节是子主题自包含的最后一节,不再依赖
notes/子目录。
9.1 背景与动机
- 1983 年 RFC 882 / 883 定义 DNS,1987 年 RFC 1034 / 1035 取代至今。动机:hosts.txt 撑不住几万节点的互联网。
- 1990 年代末 NS 记录 + glue record 标准化,权威可以独立部署。
- 2004 年 RFC 4033 引入 DNSSEC,应对 Kaminsky 2008 年披露的缓存投毒漏洞(之前的生日攻击理论上可行)。
- 2018 年 RFC 8484 推出 DoH、2016 年 RFC 7858 推出 DoT,把 DNS 流量从明文 UDP 53 加密。
- 一句话总结:DNS 是互联网的「电话簿」也是攻击面最大的协议之一——默认明文、默认信任「第一个回包」,所以 DNSSEC 与 DoH/DoT 不是可选项。
9.2 概念地图
flowchart LR
Client[应用 / OS resolver] --> Stub[stub resolver]
Stub -->|UDP 53 / TCP 53 / DoT / DoH| Rec[recursive resolver]
Rec --> Root[根服务器]
Rec --> TLD[TLD 权威]
Rec --> Auth[权威 NS]
Root --> TLD
TLD --> Auth
Auth --> Glue[glue A/AAAA]
Auth --> SOA[SOA 主从]
Auth --> AXFR[AXFR/IXFR]
Rec --> Cache[(缓存 + TTL)]
Auth --> DNSSEC[RRSIG/DS/DNSKEY]
Rec --> Verify{验证链}
Stub --> Hosts[/etc/hosts/]
Stub --> NSS[nsswitch.conf]
关系说明:
Stub在 OS 内(glibc getaddrinforinfo→nsswitch.conf→/etc/hosts→/etc/resolv.conf);Rec通常是 ISP 或公共 resolver(1.1.1.1、8.8.8.8),负责「代查 + 缓存」;Root → TLD → Auth是迭代查询链,每一跳只问下一层;Auth维护自己的 zone,签发 DNSSEC 记录,主从通过 AXFR/IXFR 同步;Verify在 resolver 端完成 DNSSEC 验证,失败返回 SERVFAIL。
9.3 基础知识讲解
经典论文 / 经典书籍 / 优秀博客 / 核心人物 / 开发方法 五大类,每类 ≥3 条。
经典论文 / RFC(必读)
| 资料 | 角色 | 评分 | 链接 |
|---|---|---|---|
| RFC 1034 — Domain Names (Concepts) | DNS 概念与分层 | 5 | https://www.rfc-editor.org/rfc/rfc1034 |
| RFC 1035 — Domain Names (Implementation) | 报文与 RR | 5 | https://www.rfc-editor.org/rfc/rfc1035 |
| RFC 4033 / 4034 / 4035 — DNSSEC | 签名链三件套 | 5 | https://www.rfc-editor.org/rfc/rfc4033 |
| RFC 6891 — EDNS(0) | OPT 伪 RR、扩展机制 | 4 | https://www.rfc-editor.org/rfc/rfc6891 |
| RFC 7858 — DoT | TLS 上的 DNS | 4 | https://www.rfc-editor.org/rfc/rfc7858 |
| RFC 8484 — DoH | HTTPS 上的 DNS | 4 | https://www.rfc-editor.org/rfc/rfc8484 |
| RFC 9250 — DoQ | QUIC 上的 DNS | 4 | https://www.rfc-editor.org/rfc/rfc9250 |
| RFC 5936 — AXFR | 区域传送 | 3 | https://www.rfc-editor.org/rfc/rfc5936 |
经典书籍(系统化)
| 资料 | 角色 | 评分 | 链接 |
|---|---|---|---|
| 《DNS and BIND》(Cricket Liu / Paul Albitz) | DNS 圣经 | 5 | https://www.oreilly.com/library/view/dns-and-bind/0596001584/ |
| 《Computer Networking: A Top-Down Approach》(Kurose & Ross) | 应用层章节 | 4 | https://gaia.cs.umass.edu/kurose_ross/ |
| 《TCP/IP 详解 卷 1》(Richard Stevens) | DNS 报文详解 | 5 | https://www.amazon.com/TCP-Illustrated-Volume-Protocols/dp/0321336313 |
| 《Linux 高性能服务器编程》(游双) | resolver 实现 | 4 | https://book.douban.com/subject/24722642/ |
优秀博客(按问题查)
| 资料 | 角色 | 评分 | 链接 |
|---|---|---|---|
| Cloudflare Learning — DNS | 概念图解 | 4 | https://www.cloudflare.com/learning/dns/what-is-dns/ |
| Julia Evans「DNS!」zine | 命令可视化 | 5 | https://jvns.ca/dns-zine.pdf |
| APNIC Blog — DNS 系列 | 运营商视角 | 4 | https://blog.apnic.net/ |
| ISC Knowledge Base | BIND 实战 | 4 | https://kb.isc.org/docs |
| 阿里云 DNS 文档 | 国内云 DNS 实践 | 4 | https://www.alibabacloud.com/help/en/dns |
| 1.1.1.1 文档 | 公共 resolver 行为 | 4 | https://developers.cloudflare.com/1.1.1.1/ |
核心人物(知道谁定的规范)
| 人物 | 贡献 | 关键出处 |
|---|---|---|
| Paul Mockapetris | DNS 发明者 | RFC 882 / 883(1983) |
| Jon Postel | RFC 编辑、协议体系奠基 | RFC 920 等 DNS 早期 |
| Dan Kaminsky | 2008 缓存投毒漏洞披露 | 推动了 DNSSEC 强制验证 |
| Cricket Liu | BIND 维护者与《DNS and BIND》作者 | O’Reilly 经典 |
| W. Richard Stevens | 《TCP/IP 详解》《UNIX 网络编程》 | 工程师人手一本 |
| Olaf Kolkman | DNSSEC 部署推动者 | NLnet Labs / IETF DNSOP |
开发方法(动手习惯)
| 方法 | 适用 | 关键点 |
|---|---|---|
dig +trace 全过程 | 学习路径 | 看到每一跳的 server 与 RR |
tcpdump 对照报文 | 学习 wire format | hexdump 比图快 10 倍 |
| RR 字段级标注 | 抓包复盘 | 用 dig +multi 看人类可读格式 |
| TTL 对比 | 排障 | 同一域名两次 dig,看 ANSWER TTL 是否变 |
+dnssec / “ | DNSSEC 验证 | 显式开 validating stub |
| DoH/DoT 抓包 | 加密 DNS 验证 | 看 SNI 与 TLS 握手确认上游 |
| AXFR 拉 zone | 学习 RR 全集 | 注意绝大多数域禁止 AXFR |
缺失部分:
bind配置文件的view/rndc命令细节、unbound的local-zone语义。本计划不重写工具手册;查man named.conf/man unbound.conf即可。
9.4 经典问题与经典案例
| # | 问题 | 为什么会重要 | 最简答案 |
|---|---|---|---|
| 1 | DNS 改了不生效 | TTL 没过期或 recursive 缓存 | 看权威 TTL;强制 dig +nocache |
| 2 | NXDOMAIN vs NODATA | 一个是「不存在」,一个是「存在但无此 RR」 | NXDOMAIN 在 Header;NODATA 在 Answer |
| 3 | CNAME 与其他 RR 冲突 | RFC 1034 规定 CNAME 不能与任何 RR 共存 | MX 必须在 A 记录所在名,CNAME 不能同名 |
| 4 | Glue record 缺失 | TLD NS 记录指向未在 TLD zone 的名字 | 注册商在 NS 旁附加 A/AAAA(glue) |
| 5 | 缓存投毒 | 攻击者伪造权威应答抢先到 | DNSSEC 验证来源 + 端口随机化 |
| 6 | DNSSEC 验证失败 | NSEC3 缺失或时间窗口错 | 看 RRSIG 起始/结束时间、DS 链 |
| 7 | AXFR 被滥用 | 拉走整个 zone 做侦察 | 用 TSIG + ACL 限制传送 |
| 8 | DoH 与 split-horizon | 企业内网域名走 DoH 解析不到 | 内网保留 stub resolver,明文走内网 |
| 9 | UDP 53 被丢 | 防火墙常误杀 DNS | 改 TCP 53 或直接 DoH/DoT |
| 10 | NS 记录递归环 | 父与子互相指向 | resolver 检测到环返回 SERVFAIL |
| 11 | EDNS(0) 不支持 | 老旧解析器丢大响应 | 强制 TCP 或禁用 EDNS |
| 12 | 子域委托胶水缺失 | ns1.example.com 找不到 | 注册商添加 glue A 记录 |
9.5 学习难点
概念难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| 递归 vs 迭代 | 两个词听起来一样 | 用「代查 + 缓存 = 递归」「自上而下 = 迭代」记 |
| CNAME 链追踪 | 多层 CNAME 容易乱 | dig +trace 看 CNAME 链展开 |
| Glue record | 为什么 NS 旁边要 A 记录 | 画「找 NS 又要找 NS 的 NS」死循环 |
| DNSSEC 信任链 | DS / DNSKEY / RRSIG 关系 | 用「DS 在父域签、DNSKEY 自己签 RRSIG」记 |
| TTL 与负缓存 | Negative TTL 是另一个字段 | 看 SOA 的 minimum 字段 |
思维难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| Header 字段 | 12 字节 6 个 flag 记不住 | 抓一个包对照 RFC 1035 §4.1.1 标一遍 |
| RR 5 元组 | Name / Type / Class / TTL / RDLENGTH / RDATA | 写一个 Python dnspython 解析函数 |
| 权威 vs 递归 | 谁负责什么 | 画「client → recursive → authoritative」三角 |
| DNSSEC vs DoH | 都「加密」其实不一样 | DNSSEC 防篡改、DoH/DoT 防偷听 |
工程难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
dig 输出太长 | ANSWER/AUTHORITY/ADDITIONAL 三段 | 用 +noall +answer / +authority 切片 |
tcpdump BPF 写错 | 端口过滤不到 | udp port 53 or tcp port 53 or tcp port 853 or tcp port 443 |
| DoT/DoH 抓不到 | 用了 UDP 53 BPF | 加 tcp port 853;DoH 走 443 看 HTTP/2 stream |
systemd-resolved 缓存 | dig 看到 stale 答案 | resolvectl flush-caches |
nsswitch.conf 顺序 | hosts 先于 DNS | 看 hosts: files dns 顺序 |
| DNSSEC 时间窗 | RRSIG 过期 | delv +rtrace +v4 看时间戳 |
9.6 技术标准与接口
9.6.1 Entity
| 名称 | 版本 | 发布组织 | 状态 | 许可证 / 可访问性 |
|---|---|---|---|---|
| DNS (RFC 1034 / 1035) | 1987 | IETF / IESG | 现行标准(已多次更新) | 免费公开 |
| DNSSEC (RFC 4033-4035) | 2005 | IETF / IESG | 现行标准 | 免费公开 |
| EDNS(0) (RFC 6891) | 2013 | IETF / IESG | 现行标准 | 免费公开 |
| DoT (RFC 7858) | 2016 | IETF / IESG | 现行标准 | 免费公开 |
| DoH (RFC 8484) | 2018 | IETF / IESG | 现行标准 | 免费公开 |
| DoQ (RFC 9250) | 2022 | IETF / IESG | 现行标准 | 免费公开 |
| ISC BIND | 持续更新 | ISC | 事实标准 | MPL-2.0 |
| Unbound | 持续更新 | NLnet Labs | 事实标准 | BSD-3-Clause |
| CoreDNS | 持续更新 | CNCF | 云原生事实标准 | Apache-2.0 |
| ldns / drill | 持续更新 | NLnet Labs | DNSSEC 工具 | BSD-3-Clause |
9.6.2 Scope
- DNS 协议:定义名字到资源(IP、MX、SRV 等)的映射、报文格式、解析流程;
- DNSSEC:提供来源认证与完整性校验,不提供机密性(仍可见明文);
- DoH / DoT / DoQ:在 DNS 之上套加密通道,提供机密性与一定抗中间人;
- BIND / Unbound / CoreDNS:分别是「全功能 + 权威 + 递归」「专注验证递归」「云原生插件式」的代表实现;
- **ldns / drill / delv:DNSSEC 验证工具集。
不适用:权威服务发现(SRV 仅是 DNS 一部分;服务网格另说)、应用层路由(用 HTTP Host / SNI)。与传输层关系:DNS 默认 UDP 53,超 512 字节(EDNS 协商)切 TCP 53,DoT/DoH 强 TCP。
9.6.3 Structure
DNS Header(12 字节,必会字段):
| 偏移 | 字段 | 长度 | 说明 |
|---|---|---|---|
| 0-1 | ID | 2 字节 | 请求/应答匹配 |
| 2 | QR | 1 bit | 0=query, 1=response |
| 2 | Opcode | 4 bit | 0=QUERY, 5=UPDATE |
| 2 | AA | 1 bit | Authoritative Answer |
| 2 | TC | 1 bit | TrunCation |
| 2 | RD | 1 bit | Recursion Desired |
| 2 | RA | 1 bit | Recursion Available |
| 2 | Z | 3 bit | 保留 |
| 3 | RCODE | 4 bit | 0=NOERROR, 3=NXDOMAIN, 5=REFUSED |
| 4-5 | QDCOUNT | 2 字节 | Question 数 |
| 6-7 | ANCOUNT | 2 字节 | Answer 数 |
| 8-9 | NSCOUNT | 2 字节 | Authority 数 |
| 10-11 | ARCOUNT | 2 字节 | Additional 数 |
资源记录 5 元组:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NAME |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE | CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL (4 octets) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH (2 octets) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDATA (variable) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
常用 RR 类型:
| Type | 名称 | 用途 |
|---|---|---|
| 1 | A | IPv4 地址 |
| 28 | AAAA | IPv6 地址 |
| 5 | CNAME | 别名 |
| 15 | MX | 邮件交换 |
| 2 | NS | 权威名字服务器 |
| 16 | TXT | 文本记录(SPF / DKIM / 验证) |
| 6 | SOA | 区域起始授权(主从、serial、refresh) |
| 12 | PTR | 反向解析 |
| 33 | SRV | 服务定位 |
| 41 | OPT | EDNS(0) 伪 RR |
| 252 | AXFR | 区域传送 |
| 251 | IXFR | 增量区域传送 |
| 46 | RRSIG | DNSSEC 签名 |
| 43 | DS | DNSSEC 委托签名者 |
| 48 | DNSKEY | DNSSEC 公钥 |
9.6.4 Ecosystem
- 权威实现:BIND (
named)、NSD、PowerDNS、Knot DNS; - 递归实现:Unbound、BIND recursion、dnscrypt-proxy、dnsmasq、systemd-resolved;
- 云原生:CoreDNS(Kubernetes 默认)、Caddy(内置 DoH);
- 公共 resolver:1.1.1.1(Cloudflare)、8.8.8.8(Google)、9.9.9.9(Quad9);
- 事实标准 vs 标准本身:
dig默认走 UDP,超大响应切 TCP;- Windows
nslookup行为差异(始终用 TCP); systemd-resolved默认开 DNSSEC + DoT;- 浏览器 DoH(Chrome/Firefox)绕过系统 stub,需单独配置。
9.6.5 Depth Tiers
| 层级 | 名称 | 必须看到什么 |
|---|---|---|
| L0 | 知道存在 | 知道 DNS 是「名字→IP」映射;知道有根服务器 |
| L1 | 看得懂示例 | 看到 dig 输出能猜出哪个字段 |
| L2 | 能正确调用 | 能写 dig +trace / dig @server / dig -x 排查 |
| L3 | 能解释与排错 | 能解释 TTL 不生效、CNAME 冲突、DNSSEC 失败 |
| L4 | 能设计与扩展 | 能设计签名 zone + DoH forwarder + split-horizon |
本计划目标:阶段 9 综合排障时达到 L3。
9.6.6 Source
- RFC Editor:所有 DNS / DNSSEC / DoH / DoT 原文(
https://www.rfc-editor.org/); - IANA DNS Parameters:RR 类型 / Class / RCODE 权威分配(
https://www.iana.org/assignments/dns-parameters/); - ISC Knowledge Base:BIND 实战文档(
https://kb.isc.org/docs); - NLnet Labs 文档:Unbound / ldns / drill / Unbound 配置(
https://nlnetlabs.nl/documentation/); - Cloudflare 1.1.1.1 文档:DoH/DoT 端点(
https://developers.cloudflare.com/1.1.1.1/); - 引用版本快照日期:2026-07-30。
10. 常见误区
- 把
/etc/hosts当 DNS:/etc/hosts是 nsswitch 顺序里的一项,不是 DNS; - 改完 DNS 立刻 dig:
dig可能命中 resolver 缓存,等 TTL 或+nocache; dig看到 0.0.0.0 当解析成功:很多 DNS 服务返回 0.0.0.0 作为「屏蔽」信号,要看权威返回;- 忽略 EDNS(0):老旧递归会丢带 OPT 的响应,表现是 SERVFAIL;
- 用 AXFR 一定能拉 zone:99% 权威服务器禁止 AXFR,只对白名单 IP 开放;
- 把 CNAME 与 A 写在同一个名:RFC 规定 CNAME 不能与任何 RR 共存(除 DNSSEC 相关 RR);
- 以为 DoH/DoT 解决一切:DoH/DoT 只加密,不验证来源——仍要 DNSSEC;
- 信任任意递归:公共 resolver 看到你的 query 模式;隐私敏感请用 DoH + ECS 关闭;
- 用
ping测 DNS 通不通:ping走 ICMP,与 DNS 解析无关; - 把 NS 记录指向未注册的子域:注册商要的是「可解析的 NS」,否则 delegation 失败;
- DoH 与 split-horizon 冲突:内网域名在公网 DoH 上解不到,需要保留内网 stub resolver;
- 改完 TTL 立刻测:上一级 resolver 仍可能缓存旧 TTL,没 TTL=0 覆盖不掉。
11. 所有知识点分类(统一规则)
按本仓库统一分类规则(与父主题一致):
- 编程语言
- 数据结构与算法
- 计算机基础:网络协议、操作系统、组成原理
- 工程技术
- Web 与后端
- 前端与客户端
- 数据与人工智能
- 项目与职业能力
本计划归属:计算机基础 主 + 安全与可靠性 辅。
附录:常用命令片段
# 完整解析路径(递归 + 迭代全显示)
dig +trace example.com
# 指定 resolver + 类型
dig @1.1.1.1 AAAA example.com
# 反向解析
dig -x 8.8.8.8
# 显式 DNSSEC 验证 + 显示签名
dig @1.1.1.1 +dnssec example.com
# 完整 DNSSEC 信任链验证
delv +rtrace +v4 example.com
# 区域传送(多数域禁止,仅作测试)
dig @ns1.example.com AXFR example.com
# DoT 抓包(ldns 工具集)
kdig @1.1.1.1 +tls example.com
# DoH 查询
curl --doh-url https://1.1.1.1/dns-query https://example.com
# 抓明文 + 加密 DNS
tcpdump -ni any -w /tmp/dns.pcap 'port 53 or tcp port 853 or tcp port 443'