網上很多人都說 DNS 根服務器只有 13 臺,中國一臺也沒有。在網絡世界,中國被美國卡住了脖子。那 DNS 根服務器真的只有 13 臺嗎?如果是,那原因又是什么?今天就給大家說道說道。
DNS 基本概念
在回答這個問題之前,我們需要先回顧一些基本概念。DNS 是一種分層結構,這種層級就體現在域名的『點』里。以我的域名為例,TAOSHU.IN它的完整域名其實是TAOSHU.IN.。注意最后有一個點。它分三個層級,結結構為.?IN?TAOSHU。
DNS 又是分布式系統,每一層級都有自己的解析服務器。.是第一層級,它的解析服務器就是根服務器。第二層級是對應我們常說的COM/NET等頂級域名 TLD,而我用的IN是印度的國家域名,跟中國的CN一樣,它們都是 CCTLD,也就是所謂的國家頂級域名。TAOSHU就是普通的一級域名。每個域名都可以自行設置子域名,不受上級域名限制。
域名解析過程也是分布式的。還是以TAOSHU.IN為例。客戶端先找到根服務器的地址,并其查詢IN的解析服務器。再向IN的服務器查詢TAOSHU.IN的服務器。最后向TAOSHU.IN的服務器查詢具體的解析記錄,比如 A 記錄等。
當前根服務器
從上面的過程可知,所有的 DNS 查詢都從根服務器開始。所以根服務器是整個 DNS 系統的核心。如果根服務器出現故障,那所有 DNS 查詢都會失敗!為了避免出現這種問題,人們設置了多個 DNS 根服務器。發展到現在,互聯網社區累計設置了 13 臺,它們分別是:
主機名 | IP 地址 | 運營機構 | 國家 |
---|---|---|---|
a.root-servers.net | 198.41.0.4, 2001ba3e:30 | Verisign, Inc. | 美國 |
b.root-servers.net | 199.9.14.201, 2001200::b | University of Southern California, Information Sciences Institute | 美國 |
c.root-servers.net | 192.33.4.12, 20012::c | Cogent Communications | 美國 |
d.root-servers.net | 199.7.91.13, 20012d::d | University of Maryland | 美國 |
e.root-servers.net | 192.203.230.10, 2001a8::e | NASA (Ames Research Center) | 美國 |
f.root-servers.net | 192.5.5.241, 20012f::f | Internet Systems Consortium, Inc. | 美國 |
g.root-servers.net | 192.112.36.4, 200112::d0d | US Department of Defense (NIC) | 美國 |
h.root-servers.net | 198.97.190.53, 20011::53 | US Army (Research Lab) | 美國 |
i.root-servers.net | 192.36.148.17, 2001:53 | Netnod | 瑞典 |
j.root-servers.net | 192.58.128.30, 2001c27:30 | Verisign, Inc. | 美國 |
k.root-servers.net | 193.0.14.129, 2001:1 | RIPE NCC | 荷蘭 |
l.root-servers.net | 199.7.83.42, 20019f::42 | ICANN | 國際 |
m.root-servers.net | 202.12.27.33, 2001:35 | WIDE Project | 日本 |
資料來源:IANA1 資料截止時間:2023年06月06日
在 1984 年,Jon Postel 和 Paul Mockapetris 在南加州大學設立了世界上第一臺根服務器2。到了 1990 年,根服務器的數量擴展到了 7 臺,分屬不同的組織給護,但全都在美國。到了 1991 年,KTH 在瑞典設立一臺根服務器。這是首次在美國之外部署根服務器。此后一直有舊的根服務器退役,新的服務器入役。到了 1995 年,根服務器已經擴展到 9 臺。這個時候就遇到了技術瓶頸,無法添加新的根服務器了。
到底是什么技術瓶頸呢?這就得說說 DNS 的底層實現細節了。
Priming 查詢
前面說所有的 DNS 查詢都從根服務器開始。那客戶端怎么知道當前有哪些根服務器呢?沒什么好辦法,就是在各自的代碼中寫死!對,是硬編碼。但我們前面也說了,在役的根服務器并非一成不變,寫死的話新添加的服務怎么生效呢?
這就用到了所謂的 Priming Queries3。簡單來說,所有 DNS 解析客戶端都隨軟件附帶一個列表文件,里面有當前所有根服務器的信息,包括域名、IP地址等信息。這個文件叫 Root Hints,可以從 IANA 官網4下載。但考慮到根服務器的列表可能會變,所以客戶端需要定期從已知的根服務器查詢當前最新的服務器列表,用的也是 DNS 協議,這類請求叫作 Priming 查詢。
對于客戶端來說,它先從 Root Hints 中根據某種規則5選出一臺根服務器,然后向它查詢最新的根服務器列表,并本機緩存一段時間,過期之前都以該列表為準。
因為 Priming 查詢也是用 DNS 協議,自然也走 UDP 傳輸。互聯網早期 IP 網絡的最大傳輸單元長度(MTU)也就五百多字節,所以 DNS 回復信息的最大長度同樣不能太長。所以 DNS 協議規定回復信息不能超過 512 字節。這就是添加根服務器遇到的技術瓶頸。
其實解決這個問題很容易,完全可以要求客戶端使用 TCP 連接傳輸 Priming 查詢結果嘛。可惜當時沒有采用這種方案。不過,如果是我,也不會選 TCP 方案。因為所有 DNS 查詢都走 UDP 協議,簡單而統一。雖然 DNS 也支持使用 TCP,但讓 Priming 查詢單獨走 TCP 明顯會讓系統變得很復雜。
社區最終決定想辦法壓縮查詢結果長度。
報文結構與編碼
DNS 報文結構如下,分為五個部分6。
+---------------------+ |Header| +---------------------+ |Question|thequestionforthenameserver +---------------------+ |Answer|RRsansweringthequestion +---------------------+ |Authority|RRspointingtowardanauthority +---------------------+ |Additional|RRsholdingadditionalinformation +---------------------+
Header
Header 為報文頭信息,長度固定為 12 字節,結構如下:
0123456789012345 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |ID| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR|Opcode|AA|TC|RD|RA|Z|RCODE| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QDCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |ANCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |NSCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |ARCOUNT| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Header 中跟本文內內直接相關的就是 QDCOUNT/ANCOUNT/NSCOUNT/ARCOUNT 這四個字段,分別表示后續 Question/Answer/Authority/Additional 段的數量。
Question
Question 段保存查詢請求信息,通長只有一個。它分成三個部分。后兩個部分表示查詢類型和網絡類型。含義不重要,重要的是長度固定為 4 字節。
0123456789012345 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ || /QNAME/ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QTYPE| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QCLASS| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
第一部分 QNAME 長度可變,保存查詢的域名。但存儲的方式有點特別。以域名A.ROOT-SERVERS.NET.為例,它會分成三部分A、ROOT-SERVERS和NET。每一部分稱作一個標簽(Label), QNAME 字段只保存標簽,不保存.。每個標簽用第一個字節記錄當前標簽長度,后面跟著標簽內容。最后用一個長度為零的標簽表示結尾。所以完整的 QNAME 字段編碼為:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 20|1|A| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 22|12|R| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 24|O|O| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 26|T|-| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 28|S|E| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 30|R|V| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 32|E|R| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 34|S|3| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 36|N|E| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 38|T|0| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
長度為 20 字節。特別的,對于根域名.,它的 QNAME 編碼是:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 20|0|| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
長度為 1 字節。
Answer
Answer 段是服務器返回的響應結果。數量為一條到多條不等。每一條稱為一個 RR,全稱是 Resource Record。其結構如下:
0123456789012345 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ || // /NAME/ || +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |TYPE| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |CLASS| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |TTL| || +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |RDLENGTH| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| /RDATA/ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
RR 跟前面的 Question 相比多了 TTL/RDLENGTH/RDATA 三個字段。TTL 表示有效時長, RDLENGTH 表示后續 RDATA 的長度,RDATA 保存實際的響應數據。根據 TYPE 和 CLASS 的不同,RDATA 內容也各不相同。在 Priming 查詢中,RDATA 保存各根服務器的域名,編碼跟前 Question 中的 QNAME 一樣。
如果服務器返回如下一條 RR 數據:
.518400INNSa.root-servers.net.
那么 RR 的總長度是 1+2+2+4+2+20=31 字節。
Authority
Authority 段用來返回待查詢域名的權威服務器信息。比如我們嘗試向根服務器直接查詢TAOSHU.IN的A記錄,根服務器就會在 Authority 段返回IN域名的解析服器。因為根服務器并不保存TAOSHU.IN的域名信息。不過在本文中,Priming 查詢的權威服務器就是根服務器,所以此段長度為零。
最后的 Additional 段用來返回一些附加信息。Answer 中只有域名信息。我們希望直接返回 IP 地址,所以需要用到 Additional 段。Additional 中也是一條一條的 PR,計算方式跟 Answer 的一模一樣。
因為 Priming 查詢會返回所有的根服務器域名及其對應的 IP 地址7,所以根服務器數量越多,返回的數據就越長。但 DNS 協議規定最長只能是 512 字節,這就產生了瓶頸。
到了 1995 年,已經開通了 9 臺根服務器,Priming 查詢結果快要超過 512 字節了。社區開始著手解決這個問題。方案是標簽壓縮。
標簽壓縮
壓縮辦法也很簡單,就是在 NAME 中引入指針結構:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |11|OFFSET| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
DNS 還有一個規定,域名的長度不能超過 63 字節。NAME 中第一個字節表示長度,最大值就是 63,二進制表示為00111111,可見高兩位是零。于是大家約定高兩位設為11的時候,后面的 14 位就表示從報文 Header 開始的偏移量。這樣一來,如果多個 RR 的域名中有相同的部分,就不需要重復傳輸,減少響應長度。
舉個例子,比如要同時返回A.ROOT-SERVERS.NET和B.ROOT-SERVERS.NET兩個域名,顯然它們有共同的后綴ROOT-SERVERS.NET。假設A.ROOT-SERVERS.NET的偏移量為 20,那么可以表示為:
A.ROOT-SERVERS.NET +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 20|1|A| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 22|12|R| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 24|O|O| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 26|T|-| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 28|S|E| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 30|R|V| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 32|E|R| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 34|S|3| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 36|N|E| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 38|T|0| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ B.ROOT-SERVERS.NET +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 40|1|B| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 44|11|20| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 46|0|| +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
利用標簽壓縮技術,域名B.ROOT-SERVERS.NET只需要占用 5 個字節,比A.ROOT-SERVERS.NET節省了 15 個字節。
根服務器更名
要想使用壓縮,前提是所有域名有重復的部分。但之前的根服務器域名不相同,這就得改名。到了 1995 年,社區統一的域名為根服務器重新編組并部署標簽壓縮功能。
舊域名 | 新域名 | 運營機構 |
---|---|---|
NS.INTERNIC.NET | A.ROOT-SERVERS.NET | InterNIC (operated by NSI) |
NS1.ISI.EDU | B.ROOT-SERVERS.NET | Information Sciences Institute, USC |
C.PSI.NET | C.ROOT-SERVERS.NET | PSINet |
TERP.UMD.EDU | D.ROOT-SERVERS.NET | University of Maryland |
NS.NASA.GOV | E.ROOT-SERVERS.NET | NASA Ames Research Center |
NS.ISC.ORG | F.ROOT-SERVERS.NET | Internet Software Consortium |
NS.NIC.DDN.MIL | G.ROOT-SERVERS.NET | GSI (operated by NSI) |
AOS.ARL.ARMY .MIL | H.ROOT-SERVERS.NET | U.S. Army Research Lab |
NIC.NORDU.NET | I.ROOT-SERVERS.NET | NORDUnet |
上線之后,為新的根服務器留出了空間。于是在 1997 年,又上線了 J/K/L/M 四臺根服務器。
這時候 Priming 查詢響應的返回值有多大呢?我們可以算一下:
Header 固定 12 字節
第一個 PR 保存完整域名,31 字節
另外 12 PR 保存壓縮后的域名,12*15 = 180 字節
13 個 PR 保存 A 記錄,13 * 16 = 208 字節8
Question 段中 QTYPE 和 QCLASS 字段, 4 字節
Question 段中 QNAME 字段,1 字節
總共為 12+31+180+208+4+1=436 字節。剩余可用 512?436=76 字節。一組臺服務器需要額外占用 15+16=31 字節。理論上還可以再添加兩臺根服務器,也就是最多15臺。
如果只管根服務器功能,確實還可以添加。但是早期的根服務器同時也是COM/NET/ORG的解析服務器。客戶端可以向根服器發起針對特定COM域名的 Priming 查詢。因為響應結果需要包含查詢域名 QNAME,所以上面說的 76 字節中至少要保留 64 字節給 QNAME。這樣就只剩下 12 字節。所以就不能再添加新的根服務器了。
IPv6 與 Anycast
雖然理論上是不能再加新的根服務器了,但后來網絡不斷發展,UDP 報文早已不需要把長度限制到 512 字節。而且引入 IPv6 網絡后,Priming 查詢結果中還需要返回 AAAA 記錄, 512 個字節肯定不夠用。所以社區又設計了 EDNS09 來支持返回超過 512 字節的 DNS 響應。
理論上還是可以繼續添加新的根服務器。但為什么不加了呢?那是因為有了更先進的技術 Anycast,中文譯作任播。任播,可以簡單理解為允許不同網絡中的計算機共用一個 IP 地址,同時對外提供 DNS 查詢服務。互聯網會根據客戶端的位置將請求路由到就近的計算機。
Anycast 技術將原來的單臺服務器變成了一組多臺服務器。到了2002年,J根服務器首次部署 Anycast 功能。到現在為止,前面說的13臺根服務器嚴格來說是 13 個域名并且對應 13 對 IPv4 和 IPv6 地址。每對地址之后都通過 Anycast 部署了很多臺實例,總計有超過 1500 臺根服務器實例。這些實例又稱為根鏡像服務器。
中國根服務器鏡像
雖說中國沒有自己的根服務器,但境內還是有不少根鏡像服務器:
編號 | 城市 |
---|---|
A | 廣州 |
D | 香港 臺北 |
E | 臺北 |
F | 北京 重慶 杭州 高雄 南寧 臺北 |
I | 北京 香港 沈陽 臺北 |
J | 北京 香港 湖州 上海 |
K | 北京 廣州 貴陽 臺北 |
L | 北京 長沙 海口 上海 武漢 西寧 新北 鄭州 |
M | 高雄 |
大家不妨通過 Ping 命令測一下,上面的幾個根服務器的延遲都在 50ms 左右,一看就是在國內,不然不會這么快。
-
編碼
+關注
關注
6文章
946瀏覽量
54869 -
DNS
+關注
關注
0文章
218瀏覽量
19871 -
報文
+關注
關注
0文章
38瀏覽量
4056 -
根服務器
+關注
關注
1文章
7瀏覽量
3219
原文標題:為什么 DNS 全球只有 13 臺根服務器,中國卻沒有自己的?
文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論