文/朱季謙
本文主要想通過動手實際分析一下是如何通過DNS伺服器來解析域名獲取對應IP地址的,畢竟,紙上得來終覺淺,絕知此事要躬行。
域名與IP地址
當在瀏覽器上敲下“www.baidu.com”時,一鍵回車,很快,瀏覽器上就會重新整理出熟悉的百度搜尋頁面。以前剛接觸網路時,總以為這個過程是通過域名www.baidu.com來訪問遠端伺服器,其實不然,本質上,還是通過IP去遠端訪問伺服器獲取資源。
這時,聰明的小夥伴就會出現一個疑問,為啥不直接通過域名去尋找到相應的伺服器主機呢?
其實,若要實現通過域名的方式去尋找伺服器主機,也不是不行,但沒這個必要。
先來對比一下域名方式與IP地址方式兩者的最關鍵差異在哪裡,就知道為啥沒這個必要了。
我們日常工作接觸的IPv4地址一般都是以十進位制的方式表示,例如,192.168.200.111,但在計算機當中,它其實是以二進位制形式存在,192.168.200.111的二進位制為1100 0000 1010 1000 1100 1000 0110 1111,總共32位,也就是32位元。眾所周知,1個位元組佔了8位元,那麼就意味著,一個32位元的IP地址長度也就4個位元組。
在網路傳輸過程中,4個位元組的長度,可以說,微不足道,但,若換成域名呢?
目前,域名最大長度可達:63個字元,每個char字元就佔了2位元組,63字元佔了126位元組,可見,若要用域名當成傳輸的地址,是多麼耗效能,但若用IP地址就不一樣了,32位也就只佔4位元組。
事實上,在瀏覽器上通過IP同樣可以訪問到對應域名的網址,但IP地址是一長串數字,難以記住,更難以理解這一堆數字代表了啥,但域名就不一樣了,像百度的域名www.baidu.com,很直觀就知道,這是訪問百度的網址。
按照百度百科的說法,設計域名的作用,就是為了讓使用者更好理解。
當在瀏覽器上敲下“www.baidu.com”,在這個過程當中,會做一步域名解析成IP地址的操作,這裡就涉及到一個叫做DNS的概念。DNS,全稱Domain Name System,即域名系統,它提供的作用是將域名和IP地址相互對映。最通俗的理解,它就像是Java裡key-value形式的Map,key是域名,value是對應對映的IP地址,通過map.get(域名),可得到域名對應的IP地址。
這裡值得多提一點是,與DNS相反的另一個相似概念,是ARP(Address Resolution Protocol,地址解析協議),它是根據已知的IP地址,可獲得MAC地址,當然,MAC這塊已是資料鏈路層的知識,DNS則是應用層的東西了。
域名解析IP的步驟
域名解析出其對映的IP地址,主要有以下幾個步驟:
首先,會根據域名從瀏覽器快取當中獲取,若能獲取到,直接返回對應的IP地址;若獲取失敗,會嘗試獲取作業系統本地的域名解析系統,即在hosts檔案檢查是否有對應的域名對映,若能找到,直接獲取其對映的IP地址返回。其中,關於這一步,作為程式設計師,可能多少都做過相關操作。例如,網上有一些關於Windows系統如何加快訪問Github網站的教程,其中有一個方式,就是將Github的域名與對應的IP地址,新增到Windows的C:\Windows\System32\drivers\etc\hosts檔案當中,隨後再瀏覽Github,發現速度確實快了不少。這是因為,直接本地DNS解析出IP地址,可以減少遠端網路方式去DNS伺服器上獲取域名對應的IP地址操作,也就意味著,域名解析IP速度將更快。
在hosts檔案裡儲存的域名與IP地址對映,一般都是針對IP比較穩定且經常用的,例如工作當中的一些線上開發環境或者測試環境等域名,如果是IP變化比較頻繁或者是根本就不知道IP是啥的,這類情況就無法通過hosts檔案進行配置獲取,只能通過網路訪問DNS伺服器去獲取。
首先,會先去本地區域的DNS伺服器找,我們可以在系統的網路配置上檢視,究竟哪個是屬於所在網路的本地區域DNS伺服器,在命令列提示視窗輸入,ipconfig /all,然後按Enter鍵,可以找到“DNS伺服器”一欄——
例如,我所在網路的DNS伺服器IP是192.168.31.1,當瀏覽器訪問某個域名時,就會向這個DNS伺服器傳送查詢訊息。
可以使用Wireshark抓包軟體驗證一下,還是以www.baidu.com域名來做實驗,我們先看一下該域名對應的IP是啥,直接在命令視窗ping一下,就可以知道了,其IPv4地址是14.215.177.38
通過Wireshark分析域名解析網路傳輸
這時,先開啟Wireshark抓包軟體。
接著,在谷歌瀏覽器上輸入www.baidu.com,回車,可以看到,本機IP會向本區域DNS伺服器192.168.31.1傳送了一個DNS協議的訊息,該訊息包含了域名www.baidu.com,A,還有一個0x1515這幾個資料,然後,DNS伺服器response返回了 以下資訊:response 0x1515 A www.baidu.com CNAME www.a.shifen.com A 14.215.177.38 A 14.215.177.39 ......
這些資訊當中,正好包含了域名www.baidu.com對映的IP地址(不止一個),其中就有一個是前面ping返回的14.215.177.38。
理論上,若在最近的DNS伺服器上,無法解析到域名對應的IP地址時,那麼最近的DNS伺服器就會類似充當一箇中介角色,幫助客戶端去其他DNS伺服器尋找,看看哪臺DNS伺服器上可以找到該域名對應的IP。同時,需要理解一個知識點是,任何一臺DNS伺服器,都儲存了根域名的IP地址。在www.baidu.com域名這個案例當中,加入無法從192.168.31.1這條最近的DNS伺服器上解析到對應IP地址時,該DNS伺服器就會將客戶端的查詢請求傳送給根域名伺服器去詢問www.baidu.com域名在哪裡可以解析。根域名伺服器不做解析,更像是一位指路人,告知去com域對應的DNS伺服器查詢。com域所在的DNS伺服器同樣無法解析,繼續充當一位指路人,告知把請求轉發去baidu.com所在的DNS伺服器,層層轉發下去,最後找的目標DNS伺服器,解析出域名對應的IP地址,然後返回給客戶端,這時,客戶端就可以通過IP地址獲取到相應的伺服器資源了。
在《網路是怎樣連線的》一書當中,有一個關於DNS伺服器解析流程的插圖,覺得比較直觀地表達出從最近DNS域名如何轉發到目標DNS域名的流程,這裡直接引用了——
當然,這只是理論,實際情況其實還是存在一些區別的。
再回到剛剛Wireshark抓包獲取的截圖上分析,可以看到一點是,客戶端傳送給DNS伺服器的訊息,不止域名這一個資訊,還包括了A等書,那麼,問題就來了,DNS協議的查詢請求當中,都包含了哪些引數呢?
在《網路是怎樣連線的》一書當中,有相關一些介紹,客戶端傳送給DNS伺服器的查詢訊息包含了3種資訊:
- 域名:伺服器的域名名稱,例如本文中提到的www.baidu.com這樣的域名;
- Class:Class是用來識別網路的資訊,但目前除了網際網路已經沒有其他網路了,因此,Class只有一個IN值;
- type型別:表示該域名對映對應的型別,當型別為A,表示DNS伺服器上域名對映的是IP地址;當類似是MX時,則表示對映的是郵件服務地址;
針對以上說明,我們可以具體通過Wireshark被選中資料包詳細資訊欄來分析,通過DNS伺服器解析www.baidu.com過程當中,客戶端都傳送了哪些查詢資訊。
可見,該DNS查詢資訊的域名為www.baidu.com,Class為IN,type型別為A,即代表對映的是IP地址。
通過本文,主要是分享一些自己對DNS解析的學習與理解,同時,通過實際Wireshark抓包方式,來深入分析下本機如何傳送DNS協議去DNS伺服器上獲取訪問域名對應的IP地址,希望也能讓您有一些收穫。
歡迎關注微信公眾號——