DNS · 层级、委任、缓存,以及不存在的「浸透」
DNS 解决的是一个规模问题。ARPANET 时代主机名与地址的对应表是一份叫 HOSTS.TXT 的文件,由 SRI-NIC 集中维护,各主机定期抄回本地;主机数上千之后,这套办法在三个维度上同时崩掉:文件分发的带宽、集中登记的人力、以及「谁有权决定某个名字归谁」的争议。1987 年的 RFC 1034 / 1035 用层级化的名字空间加委任换掉了它——vega.dev 这个名字归谁管,由 dev 这一级说了算,而 dev 归谁管,由根说了算。全球唯一性因此不再需要全球协调,只需要每一级各自保证自己下面那一层不重名。
这个结构一旦确立,其余部件都是它的推论。zone 是一次委任切出来的管理单元,也是数据与签名的单位;反复检索是自根向下沿委任链走一遍;缓存与 TTL 是让这条链不必每次都走的代价与前提;DNSSEC 是把「父指定子」这层关系从委任扩展到密钥,于是有了一条与委任同形的信任链。本系列各页拆的是这同一套结构的不同位置。
值得先说清一件事:DNS 里没有任何机制会把一次修改「推送」或「扩散」出去。全部动作都是 pull ——权威服务器改了数据只是坐等被问,缓存到期各自重新去问。中文语境里流行的「DNS 浸透」把这件事描述反了,也因此让人在该排查异常时选择等待。最后一组的 「浸透」这个说法 一页专门算这笔账。
前置知识只需知道 IP 地址与端口是什么。报文那一页会数字节,但不需要预先了解任何二进制格式。
先把静态的一半讲完:名字如何构成层级、委任如何切出 zone、一条资源记录由哪几段组成,以及同一份数据在多台权威服务器之间靠什么保持一致。
名字空间与委任:规模问题的解法
HOSTS.TXT 在带宽、人力、命名争议三个维度上同时失效,DNS 用层级名字空间加委任换掉它。本页讲清 label 与层级的反向关系、域名的字节模型,以及 zone 作为「一次委任切出的管理单元」的定义。
资源记录与 zone 里的四类数据
一条 RR 由 owner、TTL、class、type、RDATA 五段组成,而缓存与签名的单位是 RRset。zone file 里的行按权威性分四类,委任点之下的非 glue 记录会被静默遮蔽。
权威之间的一致性:SOA 与 zone transfer
一个 zone 有多台权威服务器,而协议要求它们给出同一答案。一致性靠 SOA 的 serial 加 zone transfer 达成,其中 serial 是环上的位置而非计数器——RFC 1982 规定差恰为 2³¹ 时比较无定义。
动态的一半。递归服务器代客户端沿委任链反复检索,途中五种应答各有各的含义;再往下一层是报文的字节,以及地址反查名字的那条平行名字空间。
名字解析:从根走到答案
递归检索要求是一次委托,反复检索是被委托方实际干的活——两者常被混称。本页走完自根向下的完整轨迹,说明 priming 如何解决「怎么找到根」这个自举问题,以及缓存为何同时是 DNS 可扩展的原因和改动不立即生效的原因。
报文的字节:12 字节头与名字压缩
委任应答与权威应答在报文层面的全部区别,是 AA 这一位加两个计数。本页数字节:头部那 16 位控制字段、QNAME 里为何不出现点、压缩指针的 14 位偏移,以及 EDNS(0) 如何不改头部就扩容。
逆向解析:地址反查名字
逆向解析不是正向的逆运算,而是一棵平行的名字树:地址逆序写成域名,挂在 in-addr.arpa 或 ip6.arpa 之下。两套数据由不同的人维护,因此正向与逆向对不上是常态而非异常。
DNS 最初的设计里应答无从验证、查询全程明文。DNSSEC 补前者,DoT / DoH 与 QNAME minimisation 补后者——两件事互不替代,解决的问题也不同。
应答的可验证性:cache poisoning 与 DNSSEC
原始 DNS 里应答无从验证,谁先答到就算谁的。DNSSEC 把「父指定子」这层关系从委任扩展到密钥,得到一条与委任同形的信任链;它提供权威认证与完整性,但不提供机密性,且断链的后果是 SERVFAIL 而非降级。
查询的可见范围:QNAME minimisation 与加密传输
DNSSEC 让应答可验证,但查询仍是明文。两条互补的路径:QNAME minimisation 减少向上游披露的信息量,DoT / DoH / DoQ 加密传输本身。前者减少必要的信任,后者只是转移信任的对象。
这一组是前面各页的现金价值:TTL 决定改动何时生效、权威服务器迁移有固定步骤、注册一个域名之后有几件事该顺手做完。末页反用整套机制,把线上域名在本机指到 dev server。
「浸透」这个说法
DNS 里没有任何把修改推送出去的机制,全部动作都是 pull。「等待浸透」把因果讲反了,代价是在该排查异常时选择等待。本页算清「改一条记录要等多久」的确定答案,并给出权威服务器迁移的五步。
注册一个域名:谁在管,之后该做什么
管理链是 ICANN 到各 TLD 的 registry 再到 registrar,用户经 registrar 下单。注册之后有一组与「用不用」无关的记录应当补齐:DNSSEC、null MX、SPF、DMARC、CAA。
应用:把线上域名在本机解析到 dev server
第三方登录 callback 与 passkey 的 rpId 都要求用线上域名 + HTTPS 访问本地服务。做法是在本机接管这一个域名的解析,再由 caddy 反代到 dev 端口——split-horizon DNS 的最小实例。
各页的载体落在哪些真实实现上
named-checkzone:$ORIGIN / $TTL / owner 继承 / 括号续行 / 相对名补全都按 RFC 1035 §5.1 实现,遮蔽 (occluded) 与 glue 的分类按 RFC 5936 §3.2。报文编解码含 RFC 1035 §4.1.4 的名字压缩与 RFC 3597 的未知类型透传,解码器带指针环检测。序列号算术是 RFC 1982 的完整实现,含差为 时比较无定义那条。反复检索的应答分类按 RFC 2308 与 RFC 4592(通配与空节点),QNAME minimisation 按 RFC 9156 的 MAX_MINIMISE_COUNT / MINIMISE_ONE_LAB 两个参数。密钥标签按 RFC 4034 附录 B,故各页 DS 与 DNSKEY 的标签是真算出来的、改坏一处会真的断链。生产实现方面:权威侧常见 BIND / NSD / Knot,递归侧常见 Unbound / Knot Resolver / PowerDNS Recursor。与相邻系列的边界
https://host:port/path 这条字符串,其中 host 一段的「注册域名 vs 公共后缀」由 Public Suffix List 判定——那是一份浏览器用的社会约定清单,与 DNS 的委任结构不是一回事:co.uk 在 PSL 里是后缀,在 DNS 里只是一个普通的委任点。本系列讲的是委任结构本身。passkey 一页的 rpId 与本系列末页的域名要求同源。Bloom filter 与本系列无关,但 NSEC3 的加盐迭代哈希与那一页的哈希族取舍属同类权衡。规范与工具
底本
-
大谷亘《DNS の基礎の基礎》
本地 · DNS-basics.pdf
本系列的底本,随本系列归档(76 页,日文,TLP:CLEAR)。慶應義塾大学 SFC 的讲义,每页角上标出对应的 RFC 编号,这套编号也是本系列各页参考文献的起点。它的七个部分与本系列的对应关系:
Why DNS?(p6–13)→ 第 1、10 讲;ゾーンとリソースレコード(p14–24)→ 第 2、3 讲;名前解決(p25–46)→ 第 4、6 讲;DNSSEC(p47–58)→ 第 7 讲;DNS Privacy(p59–62)→ 第 8 讲;附录一ドメイン名を登録したら(p64–67)→ 第 10 讲;附录二「浸透言うな」って?(p68–76)→ 第 9 讲。第 5 讲(报文的字节)与第 11 讲(本机解析的应用)不在底本范围内,是另补的。 - 滝澤隆史《DNS の RFC の歩き方》 dnsops.jp 底本参考文献里的一篇:把 DNS 相关的上百篇 RFC 按主题理成一张地图,指出哪些已被取代、哪些是当前口径。想从某一处深挖时比逐篇翻 RFC 索引省事。
- D. J. Bernstein · Notes on the Domain Name System cr.yp.to 同出自底本的参考文献。djbdns 作者对 DNS 协议细节的逐条笔记,立场鲜明且不少处与主流实现的做法相左——当作「另一种读法」看,能照出规范里那些含糊的地方。
核心 RFC
- RFC 1034 · Domain Names — Concepts and Facilities IETF 名字空间、zone、委任、解析器的原始定义。对应「名字空间与委任」「名字解析」两页,四十年来概念层几无变动。
- RFC 1035 · Domain Names — Implementation and Specification IETF 报文格式 (§4)、master file 格式 (§5.1)、名字压缩 (§4.1.4)。对应「资源记录」「报文的字节」两页,dns/core 的 zone.ts 与 wire.ts 直接实现它。
- RFC 9499 · DNS Terminology IETF 术语的裁决依据:in-domain glue 与 sibling domain glue、zone cut、full-service resolver、authoritative server 的准确定义。本系列的用词以它为准 (它已取代 RFC 8499)。
- RFC 2308 · Negative Caching of DNS Queries IETF 对应「名字解析」「「浸透」这个说法」两页:NXDOMAIN 与 NODATA 的区分,以及否定应答的 TTL = min(SOA MINIMUM, SOA 自身 TTL)——这一条废弃了 RFC 1035 给 MINIMUM 的原义。
- RFC 1982 · Serial Number Arithmetic IETF 对应「权威之间的一致性」页:SOA SERIAL 是环上的位置而非计数器,差恰为 2³¹ 时比较无定义。
- RFC 4592 · The Role of Wildcards in the DNS IETF 对应「资源记录」页:通配只在 closest encloser 之下展开、合成记录的 owner 是被问的名字、空节点为何是 NODATA 而不是 NXDOMAIN。
- RFC 6891 · Extension Mechanisms for DNS (EDNS(0)) IETF 对应「报文的字节」页:OPT 伪记录如何在不改头部的前提下扩出 payload size、扩展 RCODE 与 DO 位。DNSSEC 全靠它才装得下。
DNSSEC 与隐私
- RFC 4033 · DNS Security Introduction and Requirements IETF DNSSEC 提供什么、不提供什么。「不提供机密性」这一条常被误解,对应「应答的可验证性」页开头。
- RFC 4034 · Resource Records for DNSSEC IETF DS / DNSKEY / RRSIG / NSEC 的格式,§6.1 的 canonical name order,附录 B 的密钥标签算法。dns/core/dnssec.ts 实现了附录 B 与 §6.1。
- RFC 5155 · DNS Security (DNSSEC) Hashed Authenticated Denial of Existence IETF NSEC3:用加盐迭代哈希堵住 NSEC 的 zone walking,代价是验证方要做哈希。对应「应答的可验证性」页末节。
- RFC 9156 · DNS Query Name Minimisation to Improve Privacy IETF 对应「查询的可见范围」页:逐级放大 QNAME 的算法与两个参数,并放宽了 RFC 7816 用 NS 作为查询类型的建议。
- RFC 8484 · DNS Queries over HTTPS (DoH) IETF 对应「查询的可见范围」页:把 DNS 装进 HTTPS。它改变的是「谁能看见查询」,而不是「答案是否可信」。
运维与工具
- Root Server Technical Operations root-servers.org 对应「名字解析」页的 anycast 一节:13 个字母、12 家运营组织,以及全球实例的实时清单与地图(核对于 2026-08 时为 2003 个实例)。
- named.root(根提示文件) InterNIC 对应「名字解析」页的 priming 一节:递归服务器启动时唯一的先验知识,一份纯文本的根服务器名与地址清单。
-
RFC 7208 · Sender Policy Framework (SPF)
IETF
对应「注册之后」页:不收发邮件的域名也应显式声明,
v=spf1 -all与 null MX 一起把冒用成本抬高。 -
RFC 7505 · A "Null MX" No Service Resource Record
IETF
对应「注册之后」页:
MX 0 .明确宣告本域名不收邮件,让发送方立刻失败而不是反复重试。 - DNSViz dnsviz.net 把某个域名的 DNSSEC 信任链画成图并逐环诊断。「应答的可验证性」页讲的断链形态,在真实域名上可以用它当场看到。
- RFC 9364 · DNS Security Extensions (DNSSEC) — BCP 237 IETF DNSSEC 现行文档集的索引与当前最佳实践口径,比逐篇翻 4033–4035 省事。