網路協議之:Domain name service DNS詳解

flydean發表於2022-04-29

簡介

現在是網際網路的世界,大家從各種網站中獲取各類資源和資訊,通常我們只需要牢記一個網站地址即可,至於這個網站後臺的伺服器在什麼地方,我們並不需要關心。當我們的請求指向這個網址之後,接下來就只需要等待請求被轉發到該網址的後端伺服器上,得到返回的處理結果即可。

這個將網站名稱解析成為服務IP地址的服務就是DNS服務,它的全稱是Domain Name System,也就是域名解析服務。

那麼DNS到底是怎麼工作的呢?

有聰明的小夥伴可能會說了,那還不簡單,搞一個統一的伺服器,把世界上所有的域名對應的IP都存起來,每次需要解析的時候從這個服務去取就行了。確實,在網際網路的初期就是這麼幹的,那時候網站還不多,域名維護的成本還不高,並且最開始還沒有域名系統。

作為網際網路的技術基礎的ARPANET(The Advanced Research Projects Agency Network)是第一個具有分散式控制的廣域分組交換網路,也是最早應用 TCP/IP 協議的網路設施。

在ARPANET網路中,每個主機都有一個數字地址,但是這個數字地址明顯是反人類記憶模式的,所以科學家們希望能夠給這些主機起一些好記的名字,那麼就需要維護這些名字和主機之間的對映關係,在這個時候史丹佛研究所(現在被稱為SRI International)接下了這個任務,他們維護了一個HOSTS.TXT 的文字檔案,在這個檔案中描述了主機地址和主機名字之間的對映關係。

如果有人想要更新這個HOST檔案,那麼需要在工作時間打電話給SRI網路資訊中心,由資訊中心的工作人員將主機名和地址新增到HOSTS.TXT檔案中。當然這樣的操作對少量的資料更新來說還可以,但是如果資料量太大的情況下就有問題了。

後面一個叫做Elizabeth Feinler的人在SRI網路資訊中心的基礎上搭建了WHOIS目錄,用於檢索有關資源、聯絡人和實體的資訊,並且提出了域名的概念.

最開始的維護都是在一個單一的伺服器上進行集中式管理,但是這種維護方式已經不能夠滿足日益增長的網路需求,於是在1983年Paul Mockapetris在南加州大學建立了DNS系統,並在1983年11月於RFC 882 和 RFC 883釋出了相關的原始規範。

後面DNS經過一系列的發展,於1987年11月,RFC 1034和 RFC 1035取代了1983年的DNS規範。

DNS的功能

前面我們也提過了,DNS最基本的作用就是將使用者提供的域名轉換成為伺服器的地址。

比如我們現在有個域名叫做www.flydean.com,它對應的伺服器IPv4地址是42.138.111.201,對應的IPv6地址是fe40::1024:ff:fe10:123f,DNS要做的工作就是將www.flydean.com根據需要快速的轉換成為IPv4或者IPv6地址。這是DNS的第一個功能也是最重要的功能:提供域名的解析服務。

另外,在具體的應用場景中,域名背後對應的伺服器IP可能是會變化的,那麼就需要DNS有快速更新的功能,可以快速反映網路的變化情況,而不影響具體使用者的訪問。

這種操作對用使用者來說是友好的,因為使用者不需要知道底層伺服器的變化,他們只需要知道要訪問的域名即可。

最後,現代的網路應用一般都是分散式的,可能會有多個工作節點,不同的工作節點可能會被部署在不同的地方。使用者在訪問一個域名的時候,為了提升訪問速度,應該優先訪問離使用者最近的那個節點。這時候DNS又承擔了優化網路訪問的任務,它負責向使用者提供最近的伺服器節點,所以在現代網路架構中,DNS的作用越來越大。

DNS的組成

講解完DNS的功能之後,讓我們來看看DNS的組成,作為一個域名服務,DNS是由域名空間和Name servers兩部分組成的。

域名空間描述的是域名的結構和命令規則,而Name servers則是對域名進行解析的服務。接下來我們分別進行講解。

域名空間Domain name space

域名空間,也叫做Domain name space,它是所有域名的集合。下面是維基百科上的域名空間的示意圖:

網路協議之:Domain name service DNS詳解

從上圖可以看出,域名空間其實是一個樹形結構,每個節點或者葉子節點都有一個label和RR(esource records記載著和域名相關的有用資訊),域名本身由label組成,右邊是其父節點的名稱,用點分隔。

域名空間可以被劃分為多個子空間,每個子空間可以單獨進行管理,這樣的子空間叫做一個域(zone)。

每個DNS域又可以被劃分為一個域,也可能包含許多域和子域,具體取決於域管理器的管理選擇。

大家對域名都很熟悉了,但是大家可能不是很明白域名的構成。

事實上域名是由label組成的,各個label是以點連線起來的,比如:www.flydean.com。

每個label都可以看做是域的一個層級,最右邊是頂級域名com,左邊的是右邊域名的子域名,比如flydean是com的子域名,www是flydean.com的子域名,以此類推,總共可以有127個層級結構。

每個label可以包含0到63個字元,總共的域名長度不能超過253個字元。為什麼是253個字元而不是255個字元呢?那是因為有2個字元是用來儲存長度值的。

一般來說域名的標籤是以ASCII字元表示的,通常使用a-z,A-Z,0-9和連字元來表示,這種規則簡稱為LDH(letters, digits, hyphen)規則。

在域名中,字串是大小寫不敏感的,這就意味著www.flydean.com和WWW.FLYDEAN.COM是等價的。

注意,標籤不能以連字元開頭或者結尾,並且頂級域名不能全為數字。

有朋友可能會問了,不對呀,為什麼我聽過中文域名呢?

這是因為為了解決域名只能使用ASCII編碼的問題,ICANN通過了一個叫做IDNA國際化域名的系統,通過這個系統,使用者應用程式(例如Web瀏覽器)可以使用Punycode將Unicode字串對映到有效的DNS字符集。

什麼是Punycode呢?Punycode是一種使用ASCII字符集來表示Unicode的編碼方式。感興趣的同學可以自行探索,這裡就不細講了。

Name servers

name servers也被稱為名稱伺服器,是用來解析域名的伺服器。名稱伺服器是一種客戶端-伺服器的架構,每個名稱伺服器用於釋出有關該域的資訊以及管理從屬於它的任何域的名稱伺服器。

這樣的名稱管理器就構成了層級結構。為了提升域名解析的效率,通常會需要使用快取來儲存域名和伺服器地址的對應關係,但是有時候我們需要時效性更高的場景和服務,於是出現了一種特殊的名稱伺服器,這種伺服器叫做權威名稱伺服器。

為什麼叫權威名稱伺服器呢?這是因為權威名稱伺服器僅從由原始來源配置的資料中給出DNS查詢的答案,而不是通過對另一個名稱伺服器的查詢獲得的結果。它是域名伺服器查詢中的最後一站,如果權威名稱伺服器中儲存有請求的記錄,則其會將已請求主機名的IP地址返回到發出初始請求的DNS解析器.

DNS的工作流程

上面講了那麼多概念性的東西,大家可能會有些懵。 沒關係,這裡我們舉一個具體的例子來觀察一下DNS查詢的整個流程。

假如使用者在瀏覽器中輸入www.flydean.com想訪問這個網站,因為使用者輸入的是一個域名,所以需要將域名解析成為IP地址,從而傳送後續的資料請求包。

因為DNS本身是一個名稱服務,所以需要一個客戶端來請求DNS,這個客戶端就叫做DNS解析器。

一般來說DNS解析器是嵌入在瀏覽器中的,當使用者輸入URL來訪問網路資源的時候,瀏覽器會自動呼叫DNS解析器去對這個URL進行解析。

那麼域名解析的第一站是哪裡呢?域名解析的第一站就是根伺服器,也叫root伺服器。

域名解析的請求由root伺服器首先響應,但是root伺服器並不會直接返回使用者要解析的域名地址,而是根據使用者訪問的域名中的頂級域名的不同,返回頂級域名伺服器(TLD)的地址。

比如這裡我們要訪問的定義域名是.com,那麼root伺服器會返回.com的頂級域名伺服器的地址。

root伺服器有多少個呢?世界上的root伺服器IP地址只有13個,這是由於早期技術原因的限制導致的。這13個root伺服器的IP地址中,1個為主root地址,這個地址是由ICANN負責管理的,其他12地址中9個在美國,2個在歐洲,1個在日本。

雖然root根伺服器IP只有13個,但是基於這13個IP地址構建了一個伺服器叢集,可以有效的保證根伺服器的執行穩定性。從而不至於出現根伺服器不能訪問導致的大規模網路錯誤。

回到我們的解析過程,root伺服器把.com頂級域名伺服器的地址返回給了DNS解析器,DNS解析會再次向.com TLD發起解析查詢。

.com TLD會再次返回flydean.com的域名伺服器地址給DNS解析器。

DNS解析器再次傳送請求給flydean.com的域名伺服器,這裡的域名伺服器是一個權威域名伺服器,因為這裡是域名解析的最後一站,存放著域名的真實IP地址,權威域名伺服器經過查詢得到www.flydean.com的真實IP地址,並返回給DNS解析器。

最後DNS解析器將這個IP地址返回給瀏覽器,供後續的瀏覽請求使用。

可以看到DNS解析是一個不斷遞迴解析的過程,所以這樣的解析器又被稱為DNS遞迴解析器。

從上面的流程可以看到,每次域名的請求都需要經過root域名伺服器,那麼這樣root域名伺服器的壓力會很大,為了解決這個問題,事實上我們在使用的過程中引入了DNS快取。

快取的目的就是將DNS資料放到離自己最近的地方,從而提示資料的處理速度和展示效率。

常見的DNS快取有瀏覽器快取和作業系統DNS快取。

瀏覽器快取就是由瀏覽器負責維護的DNS快取,而作業系統DNS快取是作業系統級的DNS快取。

如果這兩個快取都不存在的話,那麼本地的DNS客戶端會將DNS查詢發生到ISP(Internet 服務提供商)內部的DNS遞迴解析器,對於ISP來說,它也會存在DNS快取,所以如果新增一個域名或者更改一個IP地址,並不是馬上生效的,而是需要等待一定的時間來讓快取失效或者快取重新整理。

DNS資源記錄

前面我們提到了DNS名稱空間中每個節點都是有label和resource records (RR)組成的,RR儲存著資源的描述資訊,會在收到DNS查詢之後返回。

DNS RR是由一條條的record構成的,下面是一條record的結構:

欄位名 描述 長度 [octets]
NAME 此記錄所屬的節點的名稱 可變
TYPE RR型別 2
CLASS Class程式碼 2
TTL RR 保持有效的秒數 4
RDLENGTH RDATA 欄位的長度 2
RDATA 附加資料欄位 可變

其中NAME是樹中節點的完全限定域名。

TYPE是記錄型別。它表示資料的格式和用途,比如A表示用於將域名轉換為IPv4地址,NS表示列出了哪些名稱伺服器可以響應DNS的域查詢,MX表示指定用於處理指定域的郵件的郵件伺服器在電子郵件地址中。

RDATA是特定型別相關的資料,例如地址記錄的IP地址,或MX記錄的優先順序和主機名。

DNS訊息的結構

既然有DNS查詢,那麼就會有DNS查詢的訊息結構,DNS訊息可以分為兩種,分別是查詢訊息和回覆訊息。

每一個message都包含了一個訊息頭和四個其他部分:question, answer, authority和額外空間。

header負責控制其他的4個部分,header包含了這樣幾個欄位: Identification, Flags, Number of questions, Number of answers, Number of authority resource records (RRs)和 Number of additional RRs, 如下表所示:

欄位名 描述 長度[bits]
QR 訊息是 query (0) 還是 reply (1) 1
OPCODE 查詢的型別 QUERY (標準查詢, 0), IQUERY (遞迴查詢, 1), 或者 STATUS (伺服器狀態請求, 2) 4
AA 是否是權威伺服器響應 1
TC 表示此訊息因長度過長而被截斷 1
RD 是否遞迴查詢 1
RA DNS 伺服器是否支援遞迴 1
Z 保留欄位 3
RCODE 響應碼,可以是NOERROR(0),FORMERR(1,格式錯誤),SERVFAIL(2),NXDOMAIN(3,不存在的域名) 4

整個頭的標記欄位長度是16bits,緊跟著4個16bits,分別表示4個其他部分的長度。

總結

以上就是DNS的結構和DNS工作的基本流程。

本文已收錄於 http://www.flydean.com/19-domain-name-service/

最通俗的解讀,最深刻的乾貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!

相關文章