2017-01-07 整理程序員
這個東東也是今年博主參見校招的時候被不少公司問過的,雖然理論性比較強,可是做爲一個程序員,我的認爲熟悉DNS是很是重要的,要理解它並能幫助解決一些實際問題。面試
雖然當時回答了,可是仍是感受得系統總結下,備忘。數據庫
Domain Name System = DNS(域名系統)實際上是一個數據庫,是用於 TCP/IP 程序的分佈式數據庫,同時也是一種重要的網絡協議。DNS儲存了網絡中的 IP 地址與對應主機的信息,郵件路由信息和其餘網絡應用方面的信息,用戶經過詢問解決庫(解決庫發送詢問並對DNS迴應進行說明)在 DNS 上查詢信息。ubuntu
DNS是網絡分層裏的應用層協議,事實上他是爲其餘應用層協議工做的,簡單說就是把域名,或者說主機名轉化爲IP地址(同時也提供反向域名查詢的功能),相似字典,好比訪問 www.baidu.com,實際訪問的是它的IP地址,由於機器識別的是擁有固定格式和含義的IP地址,而域名能夠千奇百怪,甚至是中文,不利於識別。還有好比公司內部的域驗證,經過分配給員工的域帳號登陸內網就必須經過DNS來找到域名權限服務器,來認證身份,故有些書上說:DNS是因特網世界裏不可缺乏的東西。瀏覽器
人和人要互相識別和記憶,須要名字做爲輔助,而對於網絡世界,在因特網內也須要一種命名系統來作相似的事情,該系統使用了域來劃分,任何一個網絡裏的主機(或者路由器)都有獨一無二的域名(相似國家代碼),域又能繼續劃分爲子域(相似每一個國家有不一樣的省份代碼),子域還能繼續劃分(每一個省都有本身的各個城市的代碼)……在因特網內對應的就是頂級域名(com,net,cn,org等),二級域名……注意這僅僅是一種邏輯的劃分。而這些域名系統在形式上組成了一種樹結構。緩存
名字(也叫標號)組成只能是英文或者數字,目前中文也支持了,長度不大於63個字符,總共完整域名長度不超過255個字符,英文域名不區分大小寫,從右到左,域名級別依次下降。www是表示萬維網,不屬於域名。安全
域名的名字空間是一個樹結構,根沒有名字,各個樹葉是單臺計算機名,不能繼續劃分。服務器
DNS服務器管理範圍的單位是區,不是域,由於區纔是DNS服務器管理的實際範圍,區是域的子集,同一個區裏的主機節點必須互通,它們都有一個統一的訪問權限,該訪問權限在經過一個權限域名服務器管理。好比,公司a,有兩個部門x,y,部門x又有兩個分部q和r,a會設立一個區叫a.com(區和域能夠同名),這是一個大的權限範圍,而後下屬再設立一個區,叫x.a.com,那麼區a.com和x.a.com都屬於域a.com。網絡
DNS服務器也是相似域名空間樹同樣的樹結構,依次分爲根域名服務器(知道全部的頂級域名服務器的域名和IP,最重要,它要是癱瘓,整個DNS就完蛋),而後是頂級域名服務器(管理二級域名),其次是權限域名服務器(負責區的域名服務器)。架構
最後是本地域名服務器(也叫默認域名服務器),本地域名服務器離主機很近(書上說不超過幾個路由器),速度很快,其實本地域名服務器本質不屬於域名服務器架構。
如圖就是Linux的本地域名服務器配置
如圖是Windows下本地DNS服務器配置
由於因特網規模很大,因此整個因特網只使用一個域名服務器是不行的。爲了可靠,使用了分佈式的域名系統,即便單個計算機除了故障,也不會妨礙整個DNS系統的正常運行。並採用c/s方式。DNS使大多數名字都在本地解析(resolve),僅有少許解析須要在因特網上通訊,所以分佈式DNS系統藉助分佈式的主機備份和緩存機制,很是強壯和有足夠的性能。
DNS劫持又稱域名劫持,說白了就是當用戶請求DNS解析的時候,對正常的DNS請求報文進行攔截,偷到請求的域名,而後就能夠作手腳,好比經常遇到訪問某個健康的網址的時候,明明輸入的網址是xxxx.com,結果卻跳轉到了不可描述的網站……即把審查範圍,或者權限範圍之外的請求放行,不然返回假的IP地址或者什麼都不作使請求失去響應,效果就是讓人誤覺得斷網(360網絡診斷裏常常說的,打的開QQ,可是沒法瀏覽網頁的現象),或者獲得了假網址,黑客們常常利用漏洞或者程序的缺陷對用戶的DNS進行篡改,進行釣魚網站的欺詐活動。
解決辦法能夠手動修改本地DNS域名服務器地址,首選DNS服務器:114.114.114.114,是國內第一個、全球第三個開放的DNS服務地址,又稱114DNS,或8.8.8.8(google提供的DNS服務器)等,而後修改寬帶密碼,路由器密碼,主機密碼。
當一個應用須要把主機名解析爲IP地址時,該應用進程就調用地址解析程序,它本身就變爲了DNS的一個客戶,把待解析的域名放在DNS請求報文中,以UDP方式先發給本地域名服務器,本地域名服務器在查找域名後,把對應的IP地址放在回答報文中返回,應用程序得到目的主機的IP地址後便可進行通訊。若本地域名服務器不能回答該請求,則此域名服務器就暫時稱爲DNS的另外一個客戶,並向其餘域名服務器發出查詢請求。這種過程直至找到可以回答該請求的域名服務器爲止。
若是主機所詢問的本地域名服務器不知道被查詢的域名的IP地址,那麼本地域名服務器就以DNS客戶端的身份(遞歸思想),向根域名服務器繼續發出查詢報文(替主機查詢),不讓主機本身進行查詢。遞歸查詢返回的結果或者是IP,或者報錯。這是從上到下的遞歸查詢過程。
當根域名服務器收到本地域名服務器的查詢請求,要麼給出ip,要麼通知本地域名服務器下一步應該去請求哪個頂級域名服務器查詢(並告知本地域名服務器本身知道的頂級域名的IP),讓本地域名服務器繼續查詢,而不是替他查詢。同理,頂級域名服務器沒法返回IP的時候,也會通知本地域名服務器下一步向誰查詢(查詢哪個權限域名服務器)……這是一個迭代過程。
到底採用哪一種查詢,取決於原始查詢報文的設置,不絕對。
DNS中使用了高速緩存,由於域名到地址的映射不常變,故爲提升效率而設,主機在啓動時從本地服務器下載名和地址的所有數據,並維護存放本身最近使用的域名的緩存,而且只在從緩存中找不到名字時才使用根域名服務器發起查詢。實際中,當一個 DNS 服務器接收到一個 DNS 回答後,會將其信息緩存一段時間,當再有一個對相同域名的查詢時,即可直接回復。經過 DNS 緩存,大部分查詢都只須要本地 DNS 服務器即可完成解析。
本地域名服務器在接收到DNS請求時,先查找DNS緩存,若是緩存命中直接返回結果,若是黑客攻入路由器,對部分域名的緩存進行了更改,好比將緩存的結果指向不可描述的頁面,那麼即致使用戶的正常請求被轉移……,此時能夠清除各級緩存(瀏覽器,系統,路由器,DNS緩存)。貌似沒法避免,只能是提升安全意識,即便使用了 HTTPS也不行,由於DNS解析過程發生在HTTPS請求交互前。
Hosts是一個沒有擴展名的系統文件,做用是將一些經常使用的網址域名與其對應的IP地址創建一個關聯「數據庫」, 其實 hosts 文件能夠看做是一個小型的本地 DNS 服務器。
優先順序是:當用戶在地址欄輸入一個URL以後,瀏覽器首先查詢瀏覽器的緩存,找不到就去查詢Hosts文件和本地DNS緩存,若是hosts和本地DNS緩存都沒有找到域名對應的IP,則自動進入路由器的緩存中檢查,以上均爲客服端DNS緩存,若在客戶端DNS緩存仍是沒找到,則進入ISP DNS緩存中查詢,仍是找不到,最終才向 根DNS 服務器發出 DNS 查詢報文,再找不到就報錯……
+---------------------+
| 報文頭 |
+---------------------+
| 問題 | 向服務器提出的查詢記錄
+---------------------+
| 回答 | 服務器回覆的資源記錄
+---------------------+
| 受權 | 權威的資源記錄
+---------------------+
| 格外的 | 格外的資源記錄
+---------------------+
哎,這個報文格式和名字也是醉了,不過不礙事,當在瀏覽器內輸入URL時,便開始了DNS解析過程,最後會把找到後的IP地址告知瀏覽器客戶端,方便它繼續發出 HTTP(s)請求,該過程當中,瀏覽器提出的查詢記錄類型叫A記錄(address)查詢,其餘查詢記錄類型常見的有A(地址)記錄、CNAME(別名)記錄、MX(郵件交換)記錄等。
好比問:www.baidu.com的A記錄是什麼?
是 220.181.110.181
這個A記錄意思是從域名解析獲得IP地址。那麼反過來,從IP地址獲得域名的解析過程也須要一個記錄,叫PTR記錄(和A記錄功能相反),可使用nslookup命令查詢,能夠經過查詢IP地址的PTR記錄來獲得該IP地址指向的域名,達到反查的目的。
IP反向解析主要應用到郵件服務器中來阻攔垃圾郵件,好比用 xxx@xxx.com 給郵箱 xxxxx@qq.com 發了一封信。qq郵件服務器會查看信頭文件,信頭文件顯示信是由哪一個IP地址發出的,而後根據IP地址反向解析,如反向解析到這個IP所對應的域名是xxx.com (不在黑名單)那麼就接受,不然拒絕。
域名系統中,一個IP地址可對應多個域名,在Internet上是不會去傻傻的遍歷整個域名樹的。故DNS的頂級域名提供了一個特別的頂級域——arpa 用來作反向域名解析,也稱爲反向域名。當一個主機加入網絡,得到DNS受權,它的IP地址假設爲192.168.1.1,它也順便得到了對應IP地址的 in-addr.arpa (逆向解析域in-addr.arpa)空間的受權,注意DNS名由樹底部向上組織,故它的DNS名字爲192.168 .1.1.in-addr.arpa。IP地址的第一字節必定位於in-addr的下一級。這樣欲解析的IP地址就會被表達成一種像域名同樣的形式,後綴以反向解析域名"in-addr.arpa"結尾。
本質上:反向域名解析是將IP地址表達成了一個域名,這樣反向解析的很大部分能夠歸入正向解析中。
如上是一般狀況下的DNS報文,基於UDP數據報封裝(同時DNS也支持TCP),而且要知道DNS服務器的默認端口是53
觀察出現的數據包
如圖,第一行是DNS查詢報文,第二行是DNS回答報文。
證明了DNS確實爲應用層的協議,目的端口號確實是53,傳輸層通常狀況下采用UDP也是ok的,網絡層是IP協議,數據鏈路層有以太網幀。
對應的抽象報文格式圖
+---------------------+
| 報文頭 |
+---------------------+
| 問題 | 向服務器提出的查詢記錄
+---------------------+
| 回答 | 服務器回覆的資源記錄
+---------------------+
| 受權 | 權威的資源記錄
+---------------------+
| 格外的 | 格外的資源記錄
+---------------------+
首部12字節
以上是12字節的DNS包頭
+---------------------+
| 報文頭 |
+---------------------+
| 問題 | 向服務器提出的查詢記錄
+---------------------+
| 回答 | 服務器回覆的資源記錄
+---------------------+
| 受權 | 權威的資源記錄
+---------------------+
| 格外的 | 格外的資源記錄
+---------------------+
Queries爲查詢或者響應的正文,以下是請求報文裏的問題部分
每一個問題對應一個查詢類型,響應報文裏的資源記錄部分裏每一個響應(資源記錄)也對應一個資源類型。PS:資源記錄也叫響應,以下
大致和查詢報文一致,響應包就是多出了一個Answers字段
響應報文的answer字段,第一個是請求的域名,而後cname記錄表示出別名爲www.a.shifen.com,這個別名的地址看下面具體的回答
DNS同時支持UDP和TCP訪問,當名字解析器發出一個查詢請求,而且返回響應報文中的TC位設置爲1時,名字解析器一般使用TCP重發原來的查詢請求,TCP能將用戶的數據流分爲一些報文段,用多個報文段來傳送任意長度的用戶數據,即容許返回的響應超過512個字節。
此外,爲了減輕單臺DNS服務器的負載,有時要將同一DNS區域的內容保存在多個DNS服務器中(主從備份,分佈式存儲),這時,就要用到DNS的「區域傳輸」功能。在分佈式的DNS數據庫中,當一個域的輔助名字服務器在啓動時,將從該域的主名字服務器執行區域傳送。輔助服務器將定時(一般是3小時)向主服務器進行查詢以便了解主服務器數據是否發生變更,若是有變更,爲了數據一致性,將執行一次區域傳送,區域傳送將使用TCP,由於傳送的數據遠比一個查詢或響應多。
故DNS主要使用UDP,TCP爲輔,若是是UDP,那麼不管是名字解析器仍是名字服務器都必須本身處理超時和重傳。此外,DNS不像其餘的使用UDP的應用同樣,大部分操做集中在局域網上,DNS查詢和響應一般通過廣域網。分組丟失率和往返時間的不肯定性在廣域網上比局域網上更大。這樣對於DNS客戶程序,一個好的重傳和超時程序就顯得更重要。
DNS服務器使用的熟知端口號不管對UDP仍是TCP都是53
BIND (Berkeley Internet Name Domain)是DNS協議的一個實現,提供了DNS主要功能的開放實現,包括
Bind 是一款開源的 DNS 服務器軟件,由美國加州大學 Berkeley 分校開發和維護的,按照 ISC 的調查報告,BIND 是世界上使用最多最普遍的域名服務系統,經過搭建私有的 DNS 服務器,能夠把國外的一些不可描述的 ip 地址放到本身的 DNS 服務器中暢快瀏覽。
安裝環境本地ubuntu,客戶端和服務器都是使用的一臺機器
找一臺機器做爲DNS客戶端,將客戶端的 DNS 修改成剛剛搭建的DNS服務器的 ip 地址
使用nslookup來查詢服務器(若使用其餘的客戶端, ip 地址 須要加入到 "trusted" ACL 裏面)。