一文搞清楚 DNS 的來龍去脈

想象下面的對話:

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

“去問 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 臺。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章