一文搞清楚 DNS 的來龍去脈

林子er發表於2022-01-17

想象下面的對話:

“老大,這個問題怎麼處理?”

“去問 14.215.177.39!”

你是不是一臉懵逼?

計算機只喜歡數字,每臺聯網裝置都有一個用數字表示的唯一編號叫 IP(類似我們的身份證號),聯網的裝置之間就通過這個叫 IP 的編號相互聯絡——比如我們在個人電腦上輸入 http://14.215.177.39 就能訪問百度公司的伺服器。

但人類天生對數字不敏感(想想高中背歷史年代的場景,是不是心裡抖三抖?),IP 對於人類來說毫無意義(你能從 14.215.177.39 想到百度?),需要有種人類可讀可記憶的方式來標記聯網裝置——這玩意就叫域名

於是我們大致可以像這樣訪問百度伺服器了:

域名英文叫 Domain Name,那這個將域名轉換成 IP 的轉換器就叫 Domain Name System(域名系統),簡稱 DNS。域名系統服務(DNS Server)就是一臺裝了相關軟體(一般是用 BIND,即 Berkeley Internet Name Domain,最初是由美國加州大學伯克利分校開發和維護的)的伺服器,本質上就是一個“電話本”,用來查詢某個域名對應哪個IP。

這個域名到 IP 的轉換,想起來很簡單,但要實施起來有很多事情要考慮。

首先一點是,誰來負責域名、IP的分配與轉換呢?我們在瀏覽器輸入 www.baidu.com 後,我們的電腦要去問誰關於這個域名的 IP 呢?

美國霸權

一個直覺是,網際網路屬於全球範圍的網路,應該是有個全球性的機構來負責這件事情(而不能每個公司或國家自己搞自己的)。

如無例外,這個機構應該位於網際網路發源地。

我們知道,網際網路發跡於美國,20 世紀 90 年代之前,網際網路並沒有普及,那時候主要用於軍事和科研,主要是美國政府和大學關注這些——具體來說就是美國政府在掌管著網際網路,也就是說,網際網路具體怎麼玩,全是美國說了算——所謂霸權,就是我的地盤我做主,遊戲規則都是我定的。

美國政府需要解決兩方面的事情:域名(字母地址)的管理IP(數字地址)的管理,即如何給全世界的計算機分配 IP 和域名,以及如何將域名翻譯成對應的 IP。美國政府(美國國家科學基金會)將域名委託給 NSI 公司(Network Solutions)管理,將 IP 地址委託給IANA(The Internet Assigned Numbers Authority,網際網路數字分配機構,從其名字就知道是幹嘛的)管理。

隨著網際網路的發展與普及,其他國家對美國這種獨家壟斷越來越不滿(美國商業部在 1998 年初發布了個綠皮書,說美國政府有對 Internet 的直接管理權,讓其他國家毛炸)。網際網路是世界的,不是你美國的,現在IP由你分配,域名由你解析,哪天你對某個國家不爽,就把那裡來的域名解析請求全給遮蔽了,那還得了?

但一個事實是,當時全世界的根域名解析和 IP 地址分配基本都是美國機構管理的,所以這事離開美國還真玩不轉。所以比較可行的方案是,對這些機構進行改革,讓其成為類似聯合國的國際性組織,脫離美國政府的管轄。

ICANN:網際網路界的聯合國

在其他國家一致反對的情況下,美國政府在 1998 年被迫對原來的綠皮書做了修訂(人稱白皮書),提議成立個獨立的民間組織 ICANN(Internet Corporation for Assigned Names and Numbers,網際網路名稱與數字地址分配機構,官網 https://www.icann.org,總部在美國加州),參與管理 Internet 域名及地址資源的分配。起初,雖然 ICANN 參與(注意是參與)網際網路的管理,但仍然是在美國政府的授權框架下行事,受到美國政府(商務部)的監管。直到 2016 年 10 月 1 日,美國政府將網際網路域名管理權完全交給 ICANN,兩者之間的授權管理合同在這一天失效,不再續簽——就是說,從這天起,ICANN才是個名副其實的全球性獨立機構,不再受美國政府的監管(至少在名義上)。

ICAAN 官網介紹如下:

ICANN 的使命在於確保全球網際網路的穩定、安全與統一。要與其他 網際網路使用者聯絡,您必須在自己的電腦或其他裝置中輸入地址 — 可 以是一個名稱或是一串數字。這個地址必須獨一無二,只有這樣電 腦之間才能互相識別。ICANN 則負責協調並支援這些分佈在全球各 地的唯一識別符號。ICANN 成立於 1998 年,是一家非營利公益型機 構,其社群成員遍佈全球各地。

上面說的就是以前美國政府委託 NSI 和 IANA 管的事——現在 IANA 是 ICANN 的一個下設機構,其實上面說的事情主要還是由 IANA 在管,去看下IANA 官網 https://www.iana.org/ 就知道了,其首頁說明:

The global coordination of the DNS Root, IP addressing, and other Internet protocol resources is performed as the Internet Assigned Numbers Authority (IANA) functions.

主要職能:全球的根 DNS、IP 地址以及其它網際網路協議資源的協調。

我們看看 ICANN 的組織架構:

ICANN 的最高權力機構是董事會,其成員由 ICANN 社群選取。ICANN 的日常事務由 ICANN 組織(也就是真正的實體機構)執行,而董事會則負責監督 ICANN 組織的政策制定與執行情況。

做個類比,ICANN 社群就相當於全體中國公民,董事會相當於中國的最高權力機關人民代表大會,而 ICANN 則相當於中國的各級政府機關單位。

ICANN 董事會成員來自美國、中國、澳大利亞、巴西、法國、德國等等全世界各個國家,社群成員則分佈更廣。各國政府則以諮詢委員會的方式參與 ICANN 事務。

IP 地址分配

在說域名解析前要簡單說下 IP 地址的分配,因為域名最終是要被解析成 IP 的,離開 IP 域名玩不轉。

由上一節可知,全球網際網路 IP 資源是由 ICANN 管理的,具體來說是由其下設機構 IANA 管理的。

(這裡需要注意,雖然 IANA 現在是 ICANN 的下設機構,但 IANA 比 ICANN 要早得多,其歷史可追溯到 20 世紀 70 年代——而 ICANN 在 1998 年才成立。可以理解為 ICANN 是對 IANA 等機構組織的改革與重組——IANA 還是那個 IANA,但其上層監管機構由美國政府轉為 ICANN。)

然而,中國的一家公司想要申請個 IP,肯定不是跑到美國找 IANA——IANA 並不管這些雞毛蒜皮的事。IP 資源是以分層組織架構來管理的,IANA 是全球總的 IP 資源管理機構,其在各大洲/區域設立多個區域網際網路序號產生器構(Regional Internet Registry,RIR),IANA 主要做的事就是按照 IETF 制定的相關策略給這些 RIR 分配 IP 資源池(一批 IP),這些 RIR 再將這些 IP 以更小的批次粒度分配給下級機構(如本地網際網路序號產生器構LIR、國家網際網路序號產生器構NIR,也有可能直接分配給 ISP),這些下級機構再以更小的批次粒度分配給轄區的 ISP(Internet Server Provider,網際網路接入服務商,如中國電信),而個體或公司則是從 ISP 那裡申請最終的 IP。

比如中國一家公司要向中國電信申請一個 IP,而中國電信則要向中國網際網路絡資訊中心(China Internet Network Information Center,CNNIC,屬於 NIR)申請,而 CNNIC 要向亞太網際網路絡資訊中心(Asia-Pacific Network Information Center,APNIC,屬於 RIR)申請,APNIC 要向 IANA 申請(說是申請,其實是預先分配)。

目前 IANA 下設的RIR:

這裡是 IPV4 地址分配情況

域名解析架構

現在我們知道誰在管理全世界的域名和 IP 了(ICANN),接下來的問題是:如何將域名解析到指定的 IP?

我們還是回到上面的圖:

很簡單嘛,弄臺電腦,裡面有個資料庫儲存了域名到 IP 的對映目錄,裝個 DNS Server 軟體監聽某個埠(一般是 53 埠)對外提供服務,然後廣而告之讓全世界的主機都來這裡查詢就行了。

這樣的伺服器撐不了一秒鐘。

一個直接的問題是,這樣一臺伺服器如何扛得住每天百萬億次的請求?

更嚴重的問題是,如果這臺伺服器被 DDoS 了,更有甚資料庫被黑了,豈不是全世界斷網摸黑了?

所以,雞蛋不能放一個籃子裡。DNS 這玩意要玩分散式。

分層架構:

現實中的域名結構和 DNS 解析架構跟 IP 一樣,也是分層的——所以域名和 IP 一樣也是用多個“.”隔開的。

全球的 DNS 解析從邏輯上分成三個層次:根 DNS 伺服器(Root DNS)頂級 DNS 伺服器(TLD)權威 DNS 伺服器

dns-06

對應地,我們看看域名的層次結構:

dns-05

圖片來自阿里雲

對比兩張圖我們發現,域名的結構和 DNS 解析架構是一致的——這很好理解,域名終歸是用來解析的嘛,有什麼樣的解析架構決定了有什麼樣的域名結構。所以百度的域名叫 www.baidu.com,而不是我們開始隨便寫的 baidu12345678。

有了這樣的層級結構,現在我們在瀏覽器輸入 www.baidu.com,瀏覽器為了得到這個域名的 IP,就要在這個層級結構中從上往下問——不過實際上不是瀏覽器自己去問,而是有個叫本地 DNS 伺服器(local DNS server,也叫 DNS Resolver)的傢伙代勞,瀏覽器問本地 DNS 伺服器 www.baidu.com 的 IP 是多少,本地 DNS 伺服器說”稍等,我幫你問問“,然後就開始了類似下面的對話:

(下面我們稱本地 DNS 伺服器叫”小助手“)

  • 小助手先問根 DNS 伺服器:”大哥,請問 www.baidu.com 的 IP 是多少?“

    根 DNS 伺服器說:”我不知道,但你可以問問 com 頂級 DNS 伺服器,他知道些 com 的內情。他的 IP 是 192.26.92.30。“

  • 然後小助手跑去問那個 com 頂級 DNS 伺服器:”二哥,請問 www.baidu.com 的 IP 是多少?“

    com 頂級 DNS 伺服器說:”我不知道,但你可以問問權威伺服器 A,他知道些 baidu.com 的內情。他的 IP 是 220.181.33.31。“

  • 然後小助手又屁顛屁顛去問權威伺服器 A:”三哥,請問 www.baidu.com 的 IP 是多少?“

    權威伺服器 A 說:”算你問對人了,www.baidu.com 的 IP 是 14.215.177.38。“

  • 於是小助手終於拿到了 www.baidu.com 的 IP,高高興興地給到瀏覽器。

(注意:實際上 www.baidu.com 做了 CNAME 解析,並且最終 IP 也不止一個。)

即先從域名的根(即”.“,有些場合下 www.baidu.com 會寫成 www.baidu.com.,最後那個”.“就是根域名)開始順藤摸瓜:. -> com -> baidu.com -> www.baidu.com。

上面過程畫成圖就是這樣:

dns-07

DNS 快取:

這個本地 DNS 伺服器雖然最終問到了 IP,但心裡其實很不爽:我為了問個 IP 就周遊了一遍全世界啊。

瀏覽器也不爽:問個 IP 花這麼久,你屬烏龜啊?

另外剛才說通過層級架構解決訪問量問題,但從上面例子也沒發現訪問量降低啊,每層伺服器都被訪問了一遍。

所以在這種分層架構中有個核心要點:DNS 快取(DNS Cache)。

域名和 IP 的對映關係有個重要的事實是,它們不常變化,特別越往上層變動頻率越低(13 臺根 DNS 伺服器的域名和 IP 更是固定不變的),這種資料非常適合做快取。

所以實際上在上面的查詢中,瀏覽器所在的本地電腦和本地 DNS 伺服器都是先查它們自己的快取,查不到才往上查。

具體是,瀏覽器發出 DNS 查詢請求給本地電腦的 DNS 客戶端,DNS 客戶端先查本地 DNS 快取有沒有對應域名的 IP 資訊(且未過期),有則直接返回;沒有則去詢問本地 DNS 伺服器,本地 DNS 伺服器先查本地快取中有沒有對應域名的 IP,有則返回,沒有則往上層查。

本地 DNS 伺服器一般是 ISP 的 DNS Server 或者公共 DNS(如 114DNS),對於一些大量訪問的知名網站,基本都是有快取的。另外,即使沒有快取,它也不一定就是從根 DNS 伺服器開始查,因為多半它也持有 TLD DNS 伺服器以及相應域名權威 DNS 伺服器的快取,所以多數時候它是抄近道查的。

也就是說,對於絕大部分的 DNS 解析請求,在本地電腦和本地 DNS 伺服器兩層已經解決掉了,壓根不會跑到外面那三層體系中——即便這樣,全球 13 臺根 DNS 伺服器每天仍要承接數百億次查詢。

dns-08

根 DNS 伺服器:

全世界一共有 13 臺(邏輯上)根 DNA 伺服器,分別用 a 到 m 命名,如 a.root-servers.net,b.root-servers.net。之所以是 13 臺是有其歷史原因的,根據RFC 791規定,為保證 UDP 資料包傳輸成功率,儘量將資料包控制在 571 位元組以使資料包不會被分片傳輸,所以算來算去這個資料包就只能放 13 個伺服器資訊。

這 13 臺根伺服器中,一臺是主伺服器(就是 a 伺服器),12 臺輔助伺服器,有 10 臺在美國,2 臺在歐洲,1臺在日本。

說 13 臺有點不確切,準確說應該是 13 組,因為 a - m 每個都是全球範圍的分散式叢集,到目前為止,一共有1487 個 ROOT 例項(instance),這麼多叢集節點一方面大大提高請求承載能力和訪問速度(通過 BGP 路由協議分配最近的節點),同時大大提高抗 DDoS 的能力。

這一千多個根例項分佈如下:

dns-09

我們點開中國地區的看看:

dns-10

上面顯示在重慶有個 F 根,貴陽有個 K 根,武漢有兩個 L 根(L 的運營機構就是 ICANN 自己)。當然中國其他地方還有很多不同的 Root 例項。

這不是說現在中國就有 IPV4 根伺服器了,你看武漢那個 Root,他的 Operator 是 ICANN,在美國呢(中國有 IPV6 的根伺服器,後面會說到)。

這 13 臺(我們仍然習慣用”臺“,要知道這是邏輯單位)根伺服器由 ICANN 委託 12 家不同的機構運營管理(當然大部分都是美國的),可以在 https://root-servers.org 看到詳情。我們看其中一個:

dns-11

這是 J 根的情況,它是由 Verisign 公司運營管理的(這家公司在 2000 年收購了 Network Solutions 公司——美國政府曾指派它來管理域名——所以 Verisign 同時還運營主根(A Root)一點不奇怪)。J 根在全球一共有 118 個例項(這個數字未來應該還會增加),這些例項都是用同一個 IP:192.58.128.30,採用一種叫任播(AnyCast)的技術從中選一臺處理請求。

我們看看 J 根一天的訪問量:

dns-12

2022 年 1 月 11 日一天的 UDP 請求(DNS 主要就是 UDP)約 55 億。

從前面 DNS 查詢過程可知,根伺服器的主要作用就是告知查詢者各頂級域名(如com)對應的頂級 DNS 伺服器(TLD)的 IP 是什麼,好讓查詢者繼續往下查。所以根伺服器需要維護一個頂級域名到 TLD 伺服器地址的對映目錄,這個目錄叫 DNS 根區(DNS root zone),可以在這裡檢視完整的根區列表。下面是部分內容:

;; 一共 5 列依次是:域名、有效期、類別(IN 表示網際網路 Internet)、記錄型別(NS 表示 Name Server,A 表示 Address)、DNS 伺服器或者 IP(取決於記錄型別是 NS 還是 A),這些在後面講 DNS 協議裡面詳細說明
cn.			172800	IN	NS	a.dns.cn.
cn.			172800	IN	NS	b.dns.cn.
cn.			172800	IN	NS	c.dns.cn.
cn.			172800	IN	NS	d.dns.cn.
cn.			172800	IN	NS	e.dns.cn.
cn.			172800	IN	NS	f.dns.cn.
cn.			172800	IN	NS	g.dns.cn.
cn.			172800	IN	NS	ns.cernet.net.
......
a.dns.cn.		172800	IN	A	203.119.25.1
a.dns.cn.		172800	IN	AAAA	2001:dc7:0:0:0:0:0:1
b.dns.cn.		172800	IN	A	203.119.26.1
c.dns.cn.		172800	IN	A	203.119.27.1
d.dns.cn.		172800	IN	A	203.119.28.1
d.dns.cn.		172800	IN	AAAA	2001:dc7:1000:0:0:0:0:1

前面是頂級域名 cn. 對應的 DNS 伺服器。cn. 一共有 8 臺 TLD 伺服器,其中 7 臺是 CNNIC (中國網際網路絡資訊中心)的,1 臺是 35 互聯的。注意伺服器也是用域名錶示的,所以後面還需要個 A 記錄列出域名對應的 IP 地址(A 是 IPV4,AAAA 是 IPV6)。

不過,在請求根伺服器獲取 TLD 伺服器資訊之前,我們的本地 DNS 伺服器怎麼知道根伺服器的 IP 呢?

答案是寫死。ICAAN 提供了一份 named.cache 檔案,這個檔案提供了 13 臺根伺服器的 IP 地址,這玩意是不會變的,我們把它 down 下來放入本地 DNS Server 配置檔案中就行了。

頂級 DNS 伺服器(TLD):

本地 DNS 伺服器從根伺服器那裡拿到頂級域名(如 com)對應的 TLD Server 的 IP 後,要訪問 TLD Server 獲取一級域名(如 baidu.com)對應的權威 DNS 伺服器的 IP。

頂級域名分通用頂級域名(gTLD,如 com、org、edu、net)和國家頂級域名(ccTLD,如 cn、jp、uk)。這些頂級域名(以及 TLD Server)由 ICANN 委託不同的機構管理維護,如 .com 和 .net 由 VeriSign 公司維護,.cn 由 CNNIC 維護,還有些不怎麼通用的域名如 ”.google“ 由 google 運營,”.中國“由 CNNIC 運營。所謂委託,就是 ICANN 跟這些機構簽署委託合同(在 ICANN 之前是由美國政府和相關機構籤委託合同),這些機構在合同框架下實際管理維護這些頂級域名和 DNS 伺服器——這其實是一塊肥水,想想我們去萬網註冊個 abc.com 的域名,每年都要交錢給萬網,而這錢很有一部分是交給這些頂級機構的(還有一小部分交給 ICANN 作為管理費)。

可以在 IANA 網站上看到所有的頂級域名以及運營機構:https://www.iana.org/domains/root/db。

我們可以在網站或者命令列用 whois 工具檢視某個頂級域名的詳細資訊,如通過whois com檢視頂級域名 com 的資訊:

% IANA WHOIS server
% for more information on IANA, visit http://www.iana.org
% This query returned 1 object

domain:       COM

organisation: VeriSign Global Registry Services
address:      12061 Bluemont Way
address:      Reston Virginia 20190
address:      United States

......

nserver:      A.GTLD-SERVERS.NET 192.5.6.30 2001:503:a83e:0:0:0:2:30
nserver:      B.GTLD-SERVERS.NET 192.33.14.30 2001:503:231d:0:0:0:2:30
......

whois:        whois.verisign-grs.com

status:       ACTIVE
remarks:      Registration information: http://www.verisigninc.com

created:      1985-01-01
changed:      2017-10-05
source:       IANA

第一行說明域名是歸 IANA 管轄的,具體的運營機構是 VeriSign Global Registry Services,後面是用來解析該頂級域名的 DNS 伺服器資訊,可以看到有 13 組 DNS 伺服器(只擷取了部分),這些 DNS 伺服器同時支援 IPV4 和 IPV6。.com 下面的域名 whois 資訊都是 whois.verisign-grs.com 提供的(一般域名的 whois 資訊都是由相應頂級域名服務商提供的,如如 whois 查 baidu.com 的資訊,該資訊就是來自 Verisign 的資料庫)。最後一部分說明 com 頂級域是在 1985 年 1 月 1 日啟用的。

權威 DNS 伺服器:

TLD 伺服器同樣不能告訴我們 www.baidu.com 的 IP 到底是什麼,它的資料庫裡面只有一級域名 baidu.com 對應的權威 DNS 伺服器的 IP,所以我們還要根據其指示去相應的權威 DNS 伺服器查最終的 IP。

一般來說大公司會搭建自己的權威 DNS 伺服器解析自己的域名,我們可以通過 whois 命令檢視域名對應的權威伺服器。

比如百度的:

# whois baidu.com
......
Name Server: ns3.baidu.com
Name Server: ns7.baidu.com
Name Server: ns4.baidu.com
Name Server: ns2.baidu.com
Name Server: ns1.baidu.com

淘寶的:

# whois taobao.com
......
Name Server: NS4.TAOBAO.COM
Name Server: NS5.TAOBAO.COM
Name Server: NS6.TAOBAO.COM
Name Server: NS7.TAOBAO.COM

新浪的:

# whois sina.com.cn
......
Name Server: ns3.sina.com.cn
Name Server: ns2.sina.com.cn
Name Server: ns4.sina.com.cn
Name Server: ns1.sina.com.cn

一般中小公司會選擇租用某些大型服務商提供的付費權威 DNS(當然也可以自己搭建,但沒必要),比如我們公司域名 weicheche.cn 用的阿里旗下萬網的權威 DNS 伺服器:

# whois weicheche.cn
......
Name Server: dns31.hichina.com
Name Server: dns32.hichina.com

和根伺服器需要知道各 TLD 伺服器的 IP 資訊一樣(上面提到的 DNS 根區),TLD 伺服器也必須事先知道相應的權威伺服器的域名和 IP 資訊。當百度希望用 ns1.baidu.com 作為 baidu.com 的權威 DNS 伺服器時,它必須將該資訊(ns1.baidu.com 域名以及其 IP )寫到 com TLD 伺服器的資料庫中,如果以後百度想換 baidu.com 這個域名的權威 DNS 伺服器(如換成 ns1.xiaodu.com),則必須修改 com TLD 伺服器的那條記錄(一般一個域名的權威 DNS 至少要有兩臺)。

權威 DNS 是可以有多級的。假如有個家政公司其一級域名叫 jiazheng.com,其 DNS 伺服器是 dns.jiazheng.com,該公司想按省份管轄服務,每個省份有自己的域名和 DNS 解析,如湖北省的叫 hb.jiazheng.com,其 DNS 伺服器是 dns-hb.jiazheng.com,廣東的叫 gd.jiazheng.com,其 DNS 伺服器是 dns-gd.jiazheng.com。另外該公司業務分家庭業務和公司業務兩大板塊,也分別有自己的域名,比如湖北的家庭板塊域名叫 jt.hb.jiazheng.com,公司板塊叫 gs.hb.jiazheng.com。

這家公司需要將(而且只需要)將一級域名 jiazheng.com 對應的 DNS 伺服器 dns.jiazheng.com 註冊到 com TLD Server 資料庫中,然後將二級域名 hb.jiazheng.com 的 DNS 伺服器 dns-hb.jiazheng.com 以及 gd.jiazheng.com 的 DNS 伺服器 dns-gd.jiazheng.com 註冊到 dns.jiazheng.com 的資料庫中。

當使用者訪問 jt.hb.jiazheng.com 時,其本地 DNS 伺服器依次查根伺服器、com TLD 伺服器,com TLD 伺服器會告訴說你到 dns.jiazheng.com 這臺伺服器上去查,他的 IP 是 X.X.X.X;當本地 DNS 伺服器去 dns.jiazheng.com 上查時,dns.jiazheng.com 並不能直接告訴其 IP 是多少,只能說你要到 dns-hb.jiazheng.com 上去查,他的 IP 是 Y.Y.Y.Y(具體是返回一個 NS 報文而非 A 報文,後面會說 DNS 報文型別);最終本地 DNS 伺服器從 dns-hb.jiazheng.com 上查到了 jt.hb.jiazheng.com 的 IP 是 Z.Z.Z.Z。

本地 DNS:

本地 DNS 並不在三級層次結構中,但它對 DNS 解析非常重要。一般個人電腦上都不會安裝 DNS Server,瀏覽器也不會去各層 DNS Server 上去查,這個查詢任務是由本地 DNS 伺服器代理完成的,它接收瀏覽器(其實是瀏覽器所在電腦上的 DNS Client)的查詢請求,其間無論查詢道路多麼曲折,最終總要返回該域名的 IP 給到瀏覽器。

一般來說,個人的本地 DNS Server 是 ISP 自動分配的,或者是路由器裡面整合的。公司可能會搭建自己的本地 DNS 伺服器。也可以使用一些公共的 DNS 服務,如 114DNS(114.114.114.114)、google DNS 服務(8.8.8.8)。

Windows 上在”網路和 Internet“中可以看到自己電腦的本地 DNS:

dns-14

Mac 上在”網路偏好設定->高階->DNS“中:

dns-15

DNS 協議

概覽:

DNS 查詢是用 DNS 協議實現的,DNS 協議是應用層協議,其底層主要使用 UDP(某些場景會使用 TCP)。

DNS 伺服器儲存的那些域名到 IP 的對映叫資源記錄(Resource Record,RR),資源記錄(RR)是一個包含下列欄位的 4 元祖:

(Name, Value, Type, TTL)

TTL(Time To Live)大家都熟悉,表示這條資源的快取有效期,前面不是提過 DNS 快取嘛,到底要快取多久就取決於這個 TTL 的值,一般越上層的 TTL 越長。

Type 表示這是個什麼型別的報文,它決定了 Name 和 Value 的具體含義。主要用到的 Type 有 A、AAAA、CNAME、NS、MX:

A:Address 的縮寫,此時 Name 表示域名(一般是二級或多級域名),Value 表示該域名的 IPV4 地址。本地 DNS 伺服器拿到 A 記錄就可以返回給客戶端了;

AAAA:類似 A 記錄,表示的是 IPV6 地址(因為 IPV6 是 16 位元組,是 IPV4 4 位元組長度的 4 倍,所以寫了 4 個 A);

CNAME:別名記錄,表示 Name 域名是 Value 域名的別名。如 www.baidu.com 就 CNAME 到了 www.a.shifen.com,本地伺服器拿到 CNAME 記錄後需要繼續解析 CNAME 過來的新域名,如需要繼續去問 www.a.shifen.com 的 IP 是什麼。CNAME 解析是 CDN 中重要一步;

NS:Name Server 的縮寫,表示 Name 這個域名要去 Value 這個 DNS 伺服器繼續查。整個多層級 DNS 解析架構就靠這玩意——我們看前面的 DNS 根區檔案中有大量的 NS 記錄表示某頂級域名需要去哪個 TLD 伺服器解析;

MX:和 CNAME 類似,都是做別名,不同的是 MX 表示 Value 是郵件伺服器;

一個 DNS 報文結構長這樣:

dns-16

是不是感覺說了等於沒說?下面我們用工具抓包實操下你就明白了。

我們用到兩個工具:dig 和 wireshark,分別用來傳送 DNS 查詢和分析資料包。

dig 一下:

先在命令列用 dig 工具看下 www.baidu.com 的 DNS 解析過程:

# dig +trace www.baidu.com
; +trace 表示檢視 DNS 解析的整個過程
;; 第一階段:從本地 DNS 伺服器拿到根伺服器的資訊(因為 dig 工具自己沒有這些資訊),一共拿到 13 個
.			244973	IN	NS	d.root-servers.net.
.			244973	IN	NS	b.root-servers.net.
.			244973	IN	NS	f.root-servers.net.
;; ...... 這裡省略掉了 10 個
;; Received 811 bytes from 192.168.30.1#53(192.168.30.1) in 35 ms

;; 第二階段:從其中一臺根伺服器(j)獲取頂級域名 com. 對應的解析伺服器(TLD 伺服器),一共拿到 13 個。DS 和 RRSIG 是簽名用的
com.			172800	IN	NS	a.gtld-servers.net.
com.			172800	IN	NS	b.gtld-servers.net.
com.			172800	IN	NS	c.gtld-servers.net.
;; ...... 這裡省略掉了 10 個
com.			86400	IN	DS	30909 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CF C41A5766
com.			86400	IN	RRSIG	DS 8 1 86400 20220126210000 20220113200000 9799 . ......(省略掉一長串簽名資訊)
;; Received 1173 bytes from 192.58.128.30#53(j.root-servers.net) in 241 ms

;; 第三階段:從其中一臺頂級伺服器(h.gtld-servers.net)獲取一級域名 baidu.com. 對應的解析伺服器(權威 DNS 伺服器),一共拿到 5 個
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 761 bytes from 192.54.112.30#53(h.gtld-servers.net) in 228 ms

;; 第四階段:從其中一臺權威伺服器(ns7.baidu.com)拿到二級域名 www.baidu.com. 的資訊,這裡拿到的是 CNAME 記錄,在實際解析中還需要繼續去拿 www.a.shifen.com. 的 IP
www.baidu.com.		1200	IN	CNAME	www.a.shifen.com.
;; Received 72 bytes from 240e:bf:b801:1002:0:ff:b024:26de#53(ns7.baidu.com) in 21 ms

上面的第一階段在實際 DNS 解析中是事先在本地 DNS 伺服器配置檔案中寫好的,不需要另行獲取(因為 dig 的配置檔案沒這些東西,所以必須從本地 DNS 伺服器那裡獲取)。

我們發現各層 DNS 伺服器都有多個,這是為了防止一臺掛了就整個癱瘓。

DNSSEC:如何證明”你媽是你媽“:

上面的資料除了 NS 記錄還有 DS、RRSIG 記錄,這是用於對返回的資料做簽名用的,因為網路是不受信任的環境,我們發出個請求,然後接收到回覆,怎麼能保證這個回覆就是真正的合法伺服器返回的並且資料在途中沒有被其他人修改?比如我們訪問 www.baidu.com,本地 DNS 經過幾輪查詢,從 ns7.baidu.com 拿到了 www.baidu.com 的 CNAME 值 www.a.shifen.com——這過程中你能保證拿到的資料一定是 ns7.baidu.com 給你的?就沒有中間人攔截你的請求然後給你發個偽造的應答包,給你 CNAME 到某個日本動作片網址?

這不是瞎猜的,2014 年 9 月,CMU 的研究人員發現,本應通過 Yahoo!、Hotmail 和 Gmail 伺服器傳送的電子郵件變成通過流氓郵件伺服器傳送。攻擊者就是利用了 DNS 系統接受應答前不會檢查憑據這一漏洞實現的攻擊。

然而為了效能 DNS 底層選擇使用 UDP,而 UDP 是無連線傳輸協議,所以 DNS 並不能學 HTTP 那樣加個 SSL 層變成 DNSS。

IETF 為了 DNS 資料傳輸的安全性搞了個 DNSSEC(Domain Name System Security Extensions,即 DNS 安全擴充套件),具體內容參見 RFC2535。大致是說既然你 UDP 資料包是無連線的,那我就在資料包身上(而不是連線)做文章,為那些資料(A、NS等記錄)生成一個簽名(如 SHA256),然後對這個簽名用非對稱加密演算法(私鑰)加密一下,放在這些記錄後面(Type 叫 RRSIG,就是 Resource Record Signature 資源記錄簽名的意思),客戶端拿到資料包後,用公鑰解密出簽名資訊,並和客戶端自己對這些記錄做的簽名結果比對一下,如果不一樣說明資料就是非法的(當然客戶端用的簽名演算法肯定要和伺服器端一樣的,比如都用 SHA256)。

但問題是,客戶端(本地 DNS 伺服器)怎麼知道公鑰是多少呢?所以客戶端必須再請求伺服器端(如權威 DNS 伺服器)要公鑰。

這是不是很有問題?如果請求被某個賊人攔截了,那拿到的公鑰豈不也是假的?

所以 DNSSEC 設計了個叫做信任鏈的校驗流程,一句話就是:”如果你不信任兒子,就去問老子“——上層伺服器持有下層伺服器的身份驗證資訊。

客戶端不信任這個”權威伺服器“給的公鑰,就去問其上級 TLD 伺服器,TLD 伺服器返回個叫 DS 的記錄告訴客戶端:”他是長這樣的,你檢查下,如果不匹配,就是個 Fake DNS。“

當然 TLD 返回的這條 DS 記錄同樣也要簽名並加密,所以客戶端同樣需要再請求 TLD 伺服器討要公鑰來解密。

問題又來了:客戶端怎麼能相信這個"TLD"就是真 TLD 呢(它提供的公鑰是不是真的)?

答案是:”繼續問他老子!“

TLD 的上層就是根伺服器——那自然的一個問題就是:客戶端如何能相信這個”根伺服器“是真的呢?

根伺服器沒有上層了,自然不能再”問他老子“了——其實也不盡然,根伺服器的老子就是人類啊。根區的公鑰私鑰對是在根區域簽名儀式(Root Signing Ceremony)上由幾個特定的人在嚴格的安保環境下生成並形成記錄的——這裡關鍵的關鍵就是那個私鑰,是一定不能洩露到外面的,否則這個 DNSSEC 體系就如同廢紙。生成完了將公鑰公佈於世,大家就都知道根區的公鑰是 XYZ,誰也偽造不了了。

DNSSEC 出現時間晚於 DNS 本身(RFC2535 草案是 1999 年提的,是對 1997 年一版的修訂案,而 DNS 在 20 世紀 80 年代就有了),另外這種信任鏈機制要求所有層次的 DNS 伺服器都要嚴格實現這個驗證機制(因為這種機制是用上級來驗證下級的合法性,整個鏈條真正能夠相信的只有根服,所以必須能夠從最底層一直追溯到根),哪個環節沒有做,就如同廢紙了,所以至今並非所有 DNS 伺服器都支援 DNSSEC(當然根服和絕大部分 TLD 服都支援),有些 DNS 服務商的 DNSSEC 功能是付費的,所以說,很多域名解析仍然是”裸奔“的。

(這裡只說了大致流程,沒有展示技術細節,感興趣的可以去研究下 RFC2535Cloudflare 官網也有比較詳細的介紹)

DNS 資料包分析:

講了這麼久還不知道 DNS 資料究竟長啥樣有點過意不去,接下來我們就用 wireshark 抓個包玩玩(就是上面 dig www.baidu.com 那個的報文)。

開啟 wireshark,選擇相應的網路卡進入抓包介面,過濾 dns 協議的資料。

先看下概覽:

dns-17

從上往下按時間排列,一共 4 對問答(每對的 ID 相同,如 No.8,9 的 ID 是 0x8a60),編號 8、10、17、19 是請求包(問),9、16、18、20 是響應包(答)。

192.168.30.10 是我電腦的 IP,192.168.30.1 是我電腦的本地 DNS 伺服器。

(注意:dig tace 的資料是 dig 自己向各層 DNS 伺服器發請求,實際中是本地 DNS 伺服器做這些事情。)

解析過程:

  1. No.8,9:本機向本地 DNS 伺服器傳送請求詢問根 DNS 伺服器資訊,本地 DNS 伺服器返回 13 臺根服的域名和 IP。
  2. No.10,16:本機向 192.5.5.241 這臺根伺服器(f.root-servers.net.)詢問 www.baidu.com 的 IP(A 記錄)。根伺服器返回了一組 NS 記錄告訴本機要去這些 TLD 伺服器解析域名。
  3. No.17,18:本機向 192.33.14.30 這臺 TLD 伺服器(b.gtld-servers.net.)詢問 www.baidu.com 的 IP。該 TLD 伺服器返回了一組 NS 記錄告訴本機要去這些權威伺服器解析域名。
  4. No.19,20:本機向 14.215.178.80 這臺權威伺服器(ns4.baidu.com)詢問 www.baidu.com 的 IP。該權威伺服器返回了一條 CNAME 記錄,指向 www.a.shifen.com.。在實際 DNS 解析中,本地 DNS 伺服器要繼續上面的過程解析 www.a.shifen.com. 的 IP。

下面我們用 No.19,20 為例看看請求資料包和響應資料包的具體內容。

dns-18

這是四層網路結構,我們這裡僅關注應用層裡面的東西。

再貼下前那張概要圖對比著看下:

dns-16

dns-19

Queries 之前的都是頭部(一共 12 位元組。另外因為這是個查詢請求,body 部分沒有”回答“和”權威“資訊)。

展開看看各部分長啥樣:

dns-20

應答包結構上和查詢包基本一樣,我們展開 No.20 應答包:

dns-21

上面是百度的權威 DNS 伺服器給出了 CNAME 應答,而對於 TLD 伺服器,它不會給出 CNAME 或 A 應答,只會給出 NS 應答,指示客戶端去以下 DNS 繼續解析。我們看看 No.18 的應答資訊:

dns-22

上面的 Queries 部分都是都是指定想要 A 記錄,其實客戶端也可以指定想要其他型別記錄(如 MX、CNAME 等)。

至此,DNS 基本講得差不多了,下面我們講講一個基於 DNS 的應用:CDN。

CDN

CDN(Content Delivery Network)即內容分發網路,就是個大 Cache,把原本放在你公司伺服器的內容(主要是靜態內容)快取到世界各地,讓使用者能夠就近訪問。

圖片來自阿里雲

如圖所示,CDN 就是一個分層的快取系統(這些 L1、L2 可類比我們平時開發用到的服務本地快取、Redis 快取,源站則相當於資料庫系統),通過 DNS 排程策略為使用者(客戶機)提供一個離他最近的快取伺服器 IP,實現最快下載速度的同時減輕源站的壓力。

我們現在關注的是如何讓 DNS 返回一個離使用者最近的 IP。

CNAME 解析:

前面說過,CNAME 解析是玩 CDN 的重要一步,你去各大 CDN 服務商(阿里雲、騰訊雲、七牛雲等)開通 CDN 服務,他們都會為你生成一個加速域名,讓你把你公司需要加速的域名 CNAME 解析到這個加速域名。

理論上,CNAME 解析並不是 CDN 的必要步驟,你完全可以直接使用服務商提供的那個 URL 嘛。但你想想,你得把網站所有地方的相關域名改成那個域名(而且如果這個域名有被外界使用者或公司使用,外界也要改——這幾乎不現實),而且(更要命的)後面如果你想換 CDN 服務商(如從阿里雲換成騰訊雲),你又得大動干戈去改程式碼裡面的域名。

所以從現實來說,玩 CDN 的第一步就是將公司域名 CNAME 到 CDN 加速域名。

這裡假設公司需要加速的源域名是 www.test.com,公司使用騰訊雲的 CDN,騰訊雲 CDN 提供的加速域名是 www.test.com.cdn.dnsv1.com。

排程 DNS 伺服器:

我們同樣 dig 以下看看 DNS 解析過程(從加速域名開始 dig):

# dig www.test.com.cdn.dnsv1.com +trace
......
dnsv1.com.		172800	IN	NS	ns3.dnsv5.com.
dnsv1.com.		172800	IN	NS	ns4.dnsv5.com.
......
www.test.com.cdn.dnsv1.com. 600	IN	CNAME	www.test.com.tweb.sched.ovscdns.com.
......

發現該域名被 CNAME 到 www.test.com.tweb.sched.ovscdns.com. 了,且從名字看跟排程(sched)有關,我們繼續 dig:

# dig www.test.com.tweb.sched.ovscdns.com. +trace
......
ovscdns.com.		172800	IN	NS	ns1.ovscdns.com.
ovscdns.com.		172800	IN	NS	ns2.ovscdns.com.
ovscdns.com.		172800	IN	NS	ns3.ovscdns.com.
ovscdns.com.		172800	IN	NS	ns4.ovscdns.com.
......
www.test.com.tweb.sched.ovscdns.com. 60	IN A	43.132.83.43
www.test.com.tweb.sched.ovscdns.com. 60	IN A	101.33.27.53
www.test.com.tweb.sched.ovscdns.com. 60	IN A	43.132.83.42
www.test.com.tweb.sched.ovscdns.com. 60	IN A	43.132.83.41
www.test.com.tweb.sched.ovscdns.com. 60	IN A	101.33.27.45
......

終於找到 IP 了,返回了很多。

這裡 ns1.ovscdns.com. 等 DNS 伺服器就是排程伺服器,它是在傳統 DNS 伺服器的基礎上根據來源 IP 歸屬資訊(哪個地區、哪個主幹網)選擇對應最近的 CDN 節點的 IP 返回給客戶端以實現最近訪問(當然我們上面是 dig 的,不是實際場景,裡面返回的有日本的有新加坡的)。

核心原理就是這麼簡單:通過 CNAME 將原始域名解析到加速域名,而該加速域名的權威 DNS 伺服器具有智慧排程的能力(就是說這個加速域名並不是對應哪一臺伺服器的 IP,而是對應該服務商的整個 CDN 節點,可以被排程 DNS 伺服器解析到任何一個結點)。

實際中會複雜很多,為了競爭,各 CDN 服務商的排程能力花樣百出,遠遠不止僅通過來源 IP 排程這麼簡單,一般都會提供應用層排程(HttpDNS),可根據 Http 內容(如 url 引數、Header、path 內容執行排程)執行排程策略。

IPV6 和雪人計劃

雖然說現在全球網際網路的最高監管機構是 ICANN,然而 ICANN 總部在美國(而且雖然 ICANN 名義上不再受美國政府監管,但權力交接仍在進行中),13 臺根伺服器有 10 臺在美國,另外有兩臺分別在英國和日本——這兩家跟美國的關係你我都懂。另外現在網際網路大部分標準也是美國公司/機構制定的,在這種情況下,你敢相信美國政府對網際網路完全沒有監管能力?

前車缺芯之鑑歷歷在目,說好的全球化大分工相互取長補短呢,人家說翻臉就翻臉,不但不讓本國公司跟你玩,還逼著不讓外國公司跟你玩,就問你怕不怕。

如果說中國擔心美國哪天給中國來個大斷網——這種擔心並非杞人憂天。

(有人說這沒關係啊,我們自己搭建個根伺服器,中國所有 DNS 伺服器都指向這個根不就行了嗎?是可以,問題是這樣的網際網路只能在國內自嗨。有人可能覺得我們本來就是被牆在國內嘛,自嗨也沒關係嘛——那是你我這種普通人的感覺,真正重要的東西你我感覺不到,中國的網際網路不可能跟世界其他國家斷開——根伺服器必須是全球性的,一個世界只能有一個網際網路。)

另外 IPv4 地址行將枯竭,IPv6 的推廣勢在必行,而且現在的根服以及 DNS 解析體系存在一些固有缺陷,這個檔口給了後入局者一個機會。

中國是個大國,不僅是說地大人多,而是說這幾年中國的網際網路產業發展得相當迅速,大有趕超美國的勢頭,未來的目標是萬物互聯,那時候聯網的就遠不止電腦和手機了——現在 IP 快沒了,人家不給你分配了,怎麼辦,都玩內網?一群 192.168 在那互通有無?

所以中國將 IPV6 的普及提高到了國家戰略層面,印發了《推進網際網路協議第六版(IPv6)規模部署行動計劃》,提出了明確的階段性推廣指標(所以現在你看到很多網站頁尾都有”某某某支援 IPv6“的字樣,國家戰略得支援啊)。

為啥 IPv6 就不怕地址枯竭啊,因為 IPv4 是 4 個位元組,理論上最多能有 2^32 個地址,也即是不到 43 億個地址。IPv6 是 16 個位元組,理論上最多能有 2^128 個地址,這是個天文數字,可以給地球上每一粒沙子編址。

dns-24

4 位元組的 IPv4

dns-25

16 位元組的 IPv6

設想中國幾經奮鬥終於把 IPv6 普及開來了(這可不是一件簡單的事情,涉及到大量基礎設施的升級改造),全民歡天喜地,你看我們都在用 IPv6 了,多麼先進,比漂亮國還先進——結果關鍵的解析服務還捏在人家手裡,漂亮國一個不高興,一發淫威,照樣給你斷了網,這誰能受得了?

所以光普及 IPv6 還不行,還得在域名解析權上擺脫美國的控制。

所以中國於 2015 年領銜發起了雪人計劃(其他發起人還包括日本的 WIDE 機構——M 根服的運營機構、域名軟體之父保羅·維克西等人),面向全球招募 25 個根伺服器運營志願單位,共同運營 IPv6 根伺服器。

看看大咖們怎麼說的:

"IPv4 MTU(最大傳輸單元)限制導致了現有13個根伺服器的格局,“雪人計劃”將在純IPv6環境下建設,會嘗試更多的可能和DNS協議的改動。"

—— 前歐洲網路中心IPv6主席、下一代網際網路工程中心首席架構師肖恩·科爾

"網際網路是由自治網路組成的,全球域名系統更需要自願合作的精神,在全球網際網路領域推行單邊主義是行不通的,而且長期以來人們都認為現有13個根伺服器就代表了一個命名系統,其實從技術角度更多的根伺服器不會破壞現有的命名系統。”

—— 國際網際網路名人堂入選者保羅·維克西博士 、“雪人計劃”發起人之一

“這是我國爭取根伺服器管理權行動的有意義的切入點!美國政府並不會真正放棄已在全球網際網路事務中確立的優勢地位,利用ICANN管理權變更和向IPv6過渡的機會,從根伺服器組數量擴充套件入手,推動全球網際網路管理邁向多邊共治將是一個良好的開端。”

—— 中國工程院原副院長、院士,國家物聯網標準化專家委員會組長鄔賀銓

到 2016 年 25 個根伺服器已經在 16 個國家架設完畢:

dns-26

資料來自百度百科

這 25 臺中有 3 臺主根(分別在中國、美國、日本),22 臺輔根。從國家分佈看比舊的 13 臺要分散多了,終於不再一家獨大了。

中國部署了 4 臺,是所有國家中部署數量最多的,美國部了 3 臺。


相關文章