一段話先講結論
DNS 協議早期被設計為執行在 IPv4 + UDP 上, 單個 UDP 資料包不分片的最大有效載荷上限是 512 位元組。根域名伺服器列表必須能塞進一個 UDP 應答包 (防止 fallback 到 TCP 導致延遲和複雜度), 按照 DNS 報文的位元組佈局倒推, 根伺服器數量最多能放 13 組。這個數字不是"剛好夠用", 而是 1995 年的"協議物理上限",並因數十億臺終端的相容性而沿用至今。
一、協議層面的硬約束: 512 位元組
1.1 IPv4 MTU 與 UDP 不分片
ARPAnet / 早期 IPv4 網路規定最小 MTU 是 576 位元組。任何主機都必須能接收這個尺寸的資料包, 否則連最基礎的可達性都沒法保證 (RFC 791)。
Total Length is the length of the datagram, measured in octets,
including internet header and data. This field allows the length of
a datagram to be up to 65,535 octets. Such long datagrams are
impractical for most hosts and networks. All hosts must be prepared
to accept datagrams of up to 576 octets (whether they arrive whole
or in fragments). It is recommended that hosts only send datagrams
larger than 576 octets if they have assurance that the destination
is prepared to accept the larger datagrams.- 576 位元組總長 - 典型 20 位元組 IP 頭 - 8 位元組 UDP 頭 ≈ 548 位元組 可用 (IP 頭帶選項時最多 60 位元組, 餘量更少)
- RFC 1035 § 4.2.1 取更保守的 2 的冪 512 位元組 作為 DNS over UDP 的硬上限 — 即使 IP 頭帶滿選項也不會撐破 576
- UDP 響應若超過 512 位元組, 必須截斷並設定 TC 標誌位, 讓客戶端回退到 TCP — 而 TCP 三次握手會讓首次解析延遲翻幾倍
這就意味著, "完整的根伺服器列表必須能裝進一個 512 位元組的 UDP 包", 否則全球每次根查詢都要走 TCP, 這在 1980s 的硬體上幾乎等於宕機。
1.2 DNS 報文的位元組分佈
一次完整的 "查 . 的 NS 記錄" 響應包結構 (伺服器返回所有根 NS + 膠水 A 記錄):
Header (12 位元組)總長公式:
L(N) = 12 + 5 + 31 + 15(N-1) + 16N = 31N + 33代入 512 位元組限制:
31N + 33 ≤ 512 ⇒ N ≤ 15.45理論上最多 15 組, 但要給 DNSSEC 簽名預留空間、EDNS0 OPT 偽記錄、欄位填充 buffer, 最終定格為 13 組 — 1996 年 RFC 2010 給出了根伺服器的運營規範, 次年 M-root 就位後數量再未變動。
1.3 自己實測一下 — <code>dig +noedns -t ns .</code> 響應約 490–510 位元組
上面是理論。現在我們用 dig 命令真的去問根伺服器, 看響應到底多大:
$ dig +noedns -t ns .
; <<>> DiG 9.10.6 <<>> +noedns -t ns .
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35973
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 15
;; QUESTION SECTION:
;. IN NS
;; ANSWER SECTION:
. 430502 IN NS a.root-servers.net.
. 430502 IN NS b.root-servers.net.
… (共 13 條 NS, c ~ l 略)
. 430502 IN NS m.root-servers.net.
;; ADDITIONAL SECTION:
a.root-servers.net. 516909 IN A 198.41.0.4
b.root-servers.net. 562547 IN A 170.247.170.2
… (13 條 A 膠水記錄全部塞進來了)
m.root-servers.net. 516941 IN A 202.12.27.33
a.root-servers.net. 516930 IN AAAA 2001:503:ba3e::2:30
b.root-servers.net. 562547 IN AAAA 2801:1b8:10::b
↑ AAAA 只塞下 2 條 — 包已經到頂了
;; Query time: 8 msec
;; SERVER: 192.168.1.1#53
;; MSG SIZE rcvd: 492
關鍵看最後一行 — 響應總大小約 490–510 位元組, 穩穩低於 512 (具體數值取決於你問的是哪臺根、返回了多少條 IPv6 膠水記錄), 與前面的位元組預算一致。注意必須加 +noedns: dig 預設會帶 EDNS0, 那樣響應是 800 多位元組 — 正因為現代 resolver 普遍支援 EDNS0, 512 位元組早已不是硬限制, 但 13 這個數字當年就是這麼定下來的。
二、13 組從哪來? 歷史演變
這個數字並不是一上來就定的。DNS 的根伺服器數量經歷過多次擴張, 1997 年 M-root (WIDE, 日本) 就位後再沒動過:
| 年份 | 數量 | 關鍵事件 |
|---|---|---|
| 1984 | 4 | DNS 協議初始設計, 全部位於美國 |
| 1991 | 7 | 增加學術界 / 美國國防部節點 |
| 1995 | 9 | RIPE NCC 加入 (K-root) — 歐洲第一臺 |
| 1997 | 13 | WIDE Project 加入 (M-root) — 亞洲第一臺, 數量定格 |
| 2007 | 13 | IPv6 雙棧支援, 但 IP "組數" 不變 |
| 2023 | 13 | USC-ISI 把 B-root IP 切到 170.247.170.2 (舊 IP 199.9.14.201 退役) |
數字定格在 13 後, A~M 字母名永遠不變, 只升級硬體、增加 anycast 映象。整個網際網路的根 hint 檔案 (named.root) 早就被燒進了億萬臺遞迴 resolver / stub 客戶端的程式碼裡, 改一個數字等於全球升級。
三、但是, 全球真的只有 13 臺機器嗎?
不是。這是最常見的誤解。"13 組根伺服器" 指的是 13 個 NS 名稱 (a~m.root-servers.net), 每個名稱對應一組 IPv4 + IPv6 地址 — 不是 13 臺物理伺服器。
每個 IP 背後是一個 anycast 叢集 — 同一個 IP 地址同時被全球數百個資料中心通過 BGP 宣告, 使用者的 DNS 查詢會被路由到 RTT 最近的映象。一臺 root server "宕機" 一般指某個城市的映象維護, 全球解析不受影響。
2024 年 13 組根伺服器現狀
| 字母 | 運營機構 | IPv4 | IPv6 | Anycast 映象數 |
|---|---|---|---|---|
| A | Verisign | 198.41.0.4 | 2001:503:ba3e::2:30 | 53 |
| B | 南加州大學 ISI | 170.247.170.2 | 2801:1b8:10::b | 6 |
| C | Cogent | 192.33.4.12 | 2001:500:2::c | 12 |
| D | 馬裡蘭大學 | 199.7.91.13 | 2001:500:2d::d | 187 |
| E | NASA 艾姆斯研究中心 | 192.203.230.10 | 2001:500:a8::e | 254 |
| F | ISC | 192.5.5.241 | 2001:500:2f::f | 274 |
| G | 美國國防部 NIC | 192.112.36.4 | 2001:500:12::d0d | 6 |
| H | 美國陸軍研究實驗室 | 198.97.190.53 | 2001:500:1::53 | 17 |
| I | Netnod (瑞典) | 192.36.148.17 | 2001:7fe::53 | 75 |
| J | Verisign | 192.58.128.30 | 2001:503:c27::2:30 | 168 |
| K | RIPE NCC (歐洲) | 193.0.14.129 | 2001:7fd::1 | 113 |
| L | ICANN | 199.7.83.42 | 2001:500:9f::42 | 218 |
| M | WIDE (日本) | 202.12.27.33 | 2001:dc3::35 | 12 |
| 累計 anycast 映象 (2024) | 1395 | |||
中國大陸 (北京、上海、深圳、廣州、合肥等) 部署了 F / I / J / K / L 等多個根伺服器的 anycast 映象節點, 國內查根 RTT 實測通常 < 20ms。
四、EDNS0 之後, 512 位元組早就不是限制了
有人會問: 現在 DNS 包 ≥ 4KB 都很常見, 那為啥不"突破 13"?
- EDNS0 (1999 年 RFC 2671, 現行版 RFC 6891) — 可協商更大的 UDP 載荷 (常見 4096 位元組), 現代 resolver 全部支援
- DNSSEC 強制使用 EDNS0, 簽名資料本身就遠超 512 位元組
- TCP fallback — 現代 TCP 三次握手 + TLS / cookies 已經廉價
但根伺服器列表已經是 全網共識: 全球每一臺遞迴 resolver 的 hint 檔案 (named.root) 裡都寫死了這 13 組, 而它們背後是數十億臺終端的解析入口。變更動力 = 零, 風險 = 全球網際網路斷裂, 所以這個數字大機率永遠是 13。
一句話: "13 組" 在物理上早就過時, 在工程上不可推翻。
五、總結要點
- 歷史原因: DNS over UDP 512 位元組限制 → 數學上限 15 組 → 留 buffer 取 13 組, 1997 年 M-root 就位後定格
- 協議慣性: 升級數十億終端的 hint 檔案不現實, 永遠不動
- 真實容量: 1395+ 個 anycast 映象節點, 單點故障機率近乎零
- 中國可達: F / I / J / K / L 多個根在中國大陸有映象, 實測 RTT < 20ms
延伸閱讀
- 騰訊雲: 為什麼全球只有 13 組根域名伺服器本文協議位元組計算公式參考來源
- IANA Root Servers 官方列表運營機構 / IP / anycast 映象數權威源
- root-servers.org 即時映象分佈圖全球映象數量即時統計
- RFC 1035 § 4.2.1 — DNS UDP usage 512 位元組限制的原文
- RFC 6891 — Extension Mechanisms for DNS (EDNS0) 如何突破 512 位元組