- 鳳凰架構:構建可靠的大型分布式系統
- 周志明
- 2306字
- 2021-06-24 11:30:58
4.2 域名解析
大家都知道DNS的作用是將便于人類理解的域名地址轉換為便于計算機處理的IP地址,也許你會覺得好笑:筆者在接觸計算機網絡的開頭一段不短的時間里面,都把DNS想象成一個部署在全世界某個神秘機房中的大型電話本式的翻譯服務。后來,當筆者第一次了解到DNS的工作原理,并得知世界根域名服務器的ZONE文件只有2MB大小,甚至可以打印出來物理備份的時候,對DNS系統的設計是非常驚嘆的。
域名解析對于大多數信息系統,尤其是對于基于互聯網的系統來說是必不可少的組件,卻屬于沒有太高存在感,通常不會受重點關注的設施,不過DNS本身的工作過程,以及它對系統流量能夠施加的影響,卻還是有許多程序員不太了解;而且DNS本身就是示范性的透明多級分流系統,非常符合本章的主題,值得我們去借鑒。
無論是使用瀏覽器抑或是在程序代碼中訪問某個網址域名,譬如以www.icyfenix.com.cn為例,如果沒有緩存的話,都會先經過DNS服務器的解析翻譯,找到域名對應的IP地址才能開始通信,這項操作是操作系統自動完成的,一般不需要用戶程序介入。不過,DNS服務器并不是一次性將“www.icyfenix.com.cn”直接解析成IP地址,需要經歷一個遞歸的過程。首先DNS會將域名還原為“www.icyfenix.com.cn.”,注意最后多了一個點“.”,它是“.root”的含義。早期的域名必須帶有這個點才能被DNS正確解析,如今幾乎所有的操作系統、DNS服務器都可以自動補上結尾的點號,下面開始按如下步驟解析。
1)客戶端先檢查本地的DNS緩存,查看是否存在存活著的該域名的地址記錄。DNS是以存活時間(Time to Live,TTL)來衡量緩存的有效情況的,所以,如果某個域名改變了IP地址,DNS服務器并沒有任何機制去通知緩存了該地址的機器去更新或者失效掉緩存,只能依靠TTL超期后的重新獲取來保證一致性。后續每一級DNS查詢的過程都會有類似的緩存查詢操作,屆時將不再重復敘述。
2)客戶端將地址發送給本機操作系統中配置的本地DNS(Local DNS),這個本地DNS服務器可以由用戶手工設置,也可以在DHCP分配或者撥號時從PPP服務器中自動獲取到。
3)本地DNS收到查詢請求后,會按照“是否有www.icyfenix.com.cn的權威服務器”→“是否有icyfenix.com.cn的權威服務器”→“是否有com.cn的權威服務器”→“是否有cn的權威服務器”的順序,依次查詢自己的地址記錄,如果都沒有查詢到,就會一直找到最后點號代表的根域名服務器為止。這個步驟里涉及兩個重要名詞。
·權威域名服務器(Authoritative DNS):負責翻譯特定域名的DNS服務器,“權威”意味著域名應該翻譯出怎樣的結果是由這個服務器決定的。DNS翻譯域名時無須像查電話本一樣刻板地一對一翻譯,根據來訪機器、網絡鏈路、服務內容等各種信息,可以玩出很多花樣。權威DNS的靈活應用,在后面的內容分發網絡、服務發現等章節還會有所涉及。
·根域名服務器(Root DNS):固定的、無須查詢的頂級域名(Top-Level Domain)服務器,可以默認它們已內置在操作系統代碼之中。全世界一共有13組根域名服務器(注意并不是13臺),每一組根域名都通過任播[1]的方式建立了一大群鏡像,根據維基百科的數據,迄今已經超過1000臺根域名服務器的鏡像了。選擇13是由于DNS主要采用UDP傳輸協議(在需要穩定性保證的時候也可以采用TCP)來進行數據交換,未分片的UDP數據包在IPv4下的最大有效值為512字節,最多可以存放13組地址記錄。
4)現在假設本地DNS是全新的,上面不存在任何域名的權威服務器記錄,所以當DNS查詢請求按步驟3的順序一直查到根域名服務器之后,它將會得到“cn的權威服務器”的地址記錄,然后通過“cn的權威服務器”,得到“com.cn的權威服務器”的地址記錄,以此類推,最后找到能夠解釋“www.icyfenix.com.cn”的權威服務器地址。
5)通過“www.icyfenix.com.cn的權威服務器”,查詢www.icyfenix.com.cn的地址記錄。地址記錄并不一定就是指IP地址,在RFC規范中有定義的地址記錄類型已經多達數十種,譬如IPv4下的IP地址為A記錄,IPv6下的AAAA記錄、主機別名CNAME記錄,等等。
前面提到過,每種記錄類型中還可以包括多條記錄,以一個域名下配置多條不同的A記錄為例,此時權威服務器可以根據自己的策略來進行選擇,典型的應用是智能線路:根據訪問者所處的不同地區(譬如華北、華南、東北)、不同服務商(譬如電信、聯通、移動)等因素來確定返回最合適的A記錄,將訪問者路由到最合適的數據中心,達到智能加速的目的。
DNS系統多級分流的設計使得DNS系統能夠經受住全球網絡流量不間斷的沖擊,但也并非全無缺點。典型的問題是響應速度,在極端情況下,即各級服務器均無緩存時,域名解析可能導致每個域名都必須遞歸多次才能查詢到結果,明顯影響傳輸的響應速度,譬如圖4-1所示高達310ms的DNS查詢。
有一種“DNS預取”(DNS Prefetching)的前端優化手段可用來避免這類問題:如果網站后續要使用來自其他域的資源,那就在網頁加載時生成一個link請求,促使瀏覽器提前對該域名進行預解釋,譬如下面代碼所示:
<link rel="dns-prefetch" >
而另一種可能更嚴重的缺陷是DNS的分級查詢意味著每一級都有可能受到中間人攻擊的威脅,產生被劫持的風險。要攻陷位于遞歸鏈條頂層的服務器(譬如根域名服務器、cn權威服務器)和鏈路是非常困難的,它們都有很專業的安全防護措施。但很多位于遞歸鏈底層或者來自本地運營商的本地DNS服務器的安全防護則相對松懈,甚至不少地區的運營商自己就會主動劫持,專門返回一個錯的IP,通過在這個IP上代理用戶請求,給特定類型的資源(主要是HTML)注入廣告,以此牟利。

圖4-1 首次DNS請求耗時
為此,最近幾年出現了另一種新的DNS工作模式:HTTPDNS(也稱為DNS over HTTPS,DoH)。它將原本的DNS解析服務開放為一個基于HTTPS協議的查詢服務,替代基于UDP傳輸協議的DNS域名解析,通過程序代替操作系統直接從權威DNS或者可靠的本地DNS獲取解析數據,從而繞過傳統本地DNS。這樣做的好處是完全免去了“中間商賺差價”的環節,不再懼怕底層的域名劫持,有效避免本地DNS不可靠導致的域名生效緩慢、來源IP不準確、產生的智能線路切換錯誤等問題。
[1] 任播(Anycast)是一種網絡尋址和路由的策略。
- 樂學Windows操作系統
- Google系統架構解密:構建安全可靠的系統
- 白話區塊鏈
- 嵌入式Linux系統開發:基于Yocto Project
- vSphere Virtual Machine Management
- 嵌入式系統及其應用(第三版)
- Linux內核設計的藝術:圖解Linux操作系統架構設計與實現原理
- Delphi Programming Projects
- INSTANT Galleria Howto
- Linux基礎使用與案例
- Learning Continuous Integration with Jenkins(Second Edition)
- Drupal 7 Cookbook
- Web Penetration Testing with Kali Linux(Third Edition)
- Java EE 8 High Performance
- Linux系統管理初學者指南:基于CentOS 7.6