2017-01-07 整理
這個東東也是今年博主參見校招的時候被很多公司問過的,雖然理論性比較強,但是作為一個程序員,個人認為熟悉DNS是非常重要的,要理解它並能幫助解決一些實際問題。
雖然當時回答了,但是還是感覺得系統總結下,備忘。
Domain Name System = DNS(域名系統)其實是一個數據庫,是用於 TCP/IP 程序的分布式數據庫,同時也是一種重要的網絡協議。DNS儲存了網絡中的 IP 地址與對應主機的信息,郵件路由信息和其他網絡應用方面的信息,用戶通過詢問解決庫(解決庫發送詢問並對DNS回應進行說明)在 DNS 上查詢信息。
DNS是網絡分層裡的應用層協議,事實上他是為其他應用層協議工作的,簡單說就是把域名,或者說主機名轉化為IP地址(同時也提供反向域名查詢的功能),類似字典,比如訪問 www.baidu.com,實際訪問的是它的IP地址,因為機器識別的是擁有固定格式和含義的IP地址,而域名可以千奇百怪,甚至是中文,不利於識別。還有比如公司內部的域驗證,通過分配給員工的域賬號登錄內網就必須通過DNS來找到域名權限服務器,來認證身份,故有些書上說:DNS是因特網世界裡不可缺少的東西。
host命令用來做DNS查詢。如果命令參數是域名,命令會輸出關聯的IP;如果命令參數是IP,命令則輸出關聯的域名。host
人和人要互相識別和記憶,需要名字作為輔助,而對於網絡世界,在因特網內也需要一種命名系統來做類似的事情,該系統使用了域來劃分,任何一個網絡裡的主機(或者路由器)都有獨一無二的域名(類似國家代碼),域又能繼續劃分為子域(類似每個國家有不同的省份代碼),子域還能繼續劃分(每個省都有自己的各個城市的代碼)……在因特網內對應的就是頂級域名(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反向解析主要應用到郵件服務器中來阻攔垃圾郵件,比如用 [email protected] 給郵箱 [email protected] 發了一封信。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字節
從左到右為:QR,操作代碼op,AA,TC,RD,RA,Z,響應代碼 QR(query,response)1位,0代表查詢,1代表響應 操作代碼4位,0代表標准查詢,1代表反向查詢 AA(authoritative answer)1位,如果響應數據報設定,說明響應是由域內權限域名服務器發出 TC(truncation)1位,1代表報文被截斷,如果DNS響應報文超過了512字節,只返回這512個字節,0代表沒有截斷 RD(recursion desired)1位,遞歸期望,請求報文設定,在響應報文返回,1代表名字服務器必須遞歸處理該查詢。如 果該位為0,且被請求的名字服務器沒有一個授權回答,它就返回一個能解答該查詢的其他名字服務器列表,也就是迭代查詢。 RA(recurision available)1位,遞歸可用,響應報文設定,說明域名服務器支持遞歸查詢 Z代表保留字,3位。必須為0 響應碼是4位,類似HTTP響應碼 0 - 無差錯 1 - 格式錯誤 2 - 域名服務器出現錯誤 3 - 域參照問題 4 - 查詢類型不支持 5 - 被禁止 6 ~ 15 保留View Code
Quetions(問題數) ,通常為1。Answer RRs(資源記錄數),Authority RRs(授權資源記錄數),Additional RRs(額外資源記錄數)通常都為0。View Code
以上是12字節的DNS包頭
+---------------------+
| 報文頭 |
+---------------------+
| 問題 | 向服務器提出的查詢記錄
+---------------------+
| 回答 | 服務器回復的資源記錄
+---------------------+
| 授權 | 權威的資源記錄
+---------------------+
| 格外的 | 格外的資源記錄
+---------------------+
Queries為查詢或者響應的正文,如下是請求報文裡的問題部分
每個問題對應一個查詢類型,響應報文裡的資源記錄部分裡每個響應(資源記錄)也對應一個資源類型。PS:資源記錄也叫響應,如下
分為 Name Type Class Name(查詢名稱):域名 Type(查詢類型):2字節,這裡是A記錄. Class類,2字節,IN表示Internet數據,一般為1 大約有20多種查詢記錄類型,最常用的查詢類型是A記錄類型,例子裡DNS查詢報文查詢A記錄,從域名www.baiodu.com解析到IP地址,PTR記錄類型(反向查詢IP地址的PTR記錄,也叫指針記錄),CNAME記錄類型等。 其中cname就是別名,一般用在SEO中,可以使得多個域名指向同一個IP地址。 還有NS記錄,也就是名字服務器name serverView Code
大體和查詢報文一致,響應包就是多出了一個Answers字段
響應報文的answer字段,第一個是請求的域名,然後cname記錄表示出別名為www.a.shifen.com,這個別名的地址看下面具體的回答
Answers字段每項為一個資源記錄 除了上面提到過的Name,Type,Class之外,還有Time to Live,Data length,addr Time to Live(生存時間TTL):表示該資源記錄的生命周期,從取出記錄到抹掉DNS記錄緩存的時間,以秒為單位 Data length(資源數據長度):以字節為單位 Addr:返回的查詢結果 ip地址View Code
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,客戶端和服務器都是使用的一台機器
########安裝BIND軟件 sudo apt-get install bind9 bind9utils bind9-doc ########設置 BIND 為 IPv4 Mode,把 "-4" 添加到 OPTIONS 變量 dashuai@ubuntu:/etc$ sudo vim /etc/default/bind9 ########如下 1 # run resolvconf? 2 RESOLVCONF=no 3 4 # startup options for the server 5 OPTIONS="-4 -u bind" ########解決只讀問題 ####1、確認文件屬於自己 ####2、權限為可讀可寫 ####3、如果還是不行,就sudo vim ……打開即可View Code
########查看本機IP,保證ping通 192.168.124.8 ########編輯BIND軟件的配置文件 來配置環境 ####配置ACL ##添加一個新的 ACL 塊,把內網 ip 添加到信任名單,意思是只允許它查詢 DNS 服務器 ,提高安全性。 dashuai@ubuntu:/etc/bind$ sudo vim named.conf.options ##如下 acl "trusted" { 192.168.124.8; # ns1 只有信任的主機才能查詢 DNS 服務器,其他主機不能。 }; 16 recursion yes; 17 allow-recursion { 18 trusted; 19 }; 20 listen-on {192.168.124.8}; 21 allow-transfer {none;}; 22 23 forwarders { 24 114.114.114.114; 25 }; ##添加解析域 dashuai@ubuntu:/etc/bind$ sudo mkdir zones ####添加正向解析和反向解析文件的位置參數 dashuai@ubuntu:/etc/bind$ sudo vim named.conf.local ##如下 zone "dashuaiBlog.com" { type master; file "/etc/bind/zones/db.dashuaiBlog.com"; }; zone "168.192.in-addr.arpa" { type master; file "/etc/bind/zones/db.192.168"; }; ####在解析域裡編寫正向解析域文件 dashuai@ubuntu:/etc/bind$ cd zones/ dashuai@ubuntu:/etc/bind/zones$ ls dashuai@ubuntu:/etc/bind/zones$ touch db.dashuaiBlog.com touch: cannot touch ‘db.dashuaiBlog.com’: Permission denied dashuai@ubuntu:/etc/bind/zones$ sudo touch db.dashuaiBlog.com dashuai@ubuntu:/etc/bind/zones$ ll total 8 drwxr-sr-x 2 root bind 4096 1月 14 16:50 ./ drwxr-sr-x 3 root bind 4096 1月 14 16:41 ../ -rw-r--r-- 1 root bind 0 1月 14 16:50 db.dashuaiBlog.com dashuai@ubuntu:/etc/bind/zones$ sudo vim db.dashuaiBlog.com ##如下 ; ; BIND data file for local loopback interface $TTL 604800 @ IN SOA ns1.dashuaiBlog.com. admin.dashuaiBlog.com. ( ; Serial ; Refresh ; Retry ; Expire ) ; Negative Cache TTL ; ; ; name servers - NS records IN NS ns1.dashuaiBlog.com. ; name servers - A records ns1.dashuaiBlog.com. IN A 192.168.124.8 host1.dashuaiBlog.com. IN A 192.168.124.8 ####編寫反向解析域文件 dashuai@ubuntu:/etc/bind/zones$ sudo vim db.192.168 ##如下 $TTL 604800 @ IN SOA dashuaiBlog.com. admin.dashuaiBlog.com. ( ; Serial ; Refresh ; Retry ; Expire ) ; Negative Cache TTL ; name servers IN NS ns1.dashuaiBlog.com. ; PTR Records 2.42 IN PTR ns1.dashuaiBlog.com. ; 192.168.124.8 1.42 IN PTR host1.dashuaiBlog.com. ; 192.168.124.8View Code
ACL_百度百科
########檢驗 BIND 配置文件有沒有語法錯誤 dashuai@ubuntu:/etc/bind/zones$ sudo named-checkconf dashuai@ubuntu:/etc/bind/zones$ ########查看正向解析和反向解析文件編寫語法是否正確。 dashuai@ubuntu:/etc/bind/zones$ sudo named-checkzone dashuaiBlog.com db.dashuaiBlog.com zone dashuaiBlog.com/IN: loaded serial 3 OK dashuai@ubuntu:/etc/bind/zones$ sudo named-checkzone 168.192.in-addr.arpa db.192.168 zone 168.192.in-addr.arpa/IN: loaded serial 3 OKView Code
dashuai@ubuntu:/etc/bind/zones$ sudo service bind9 restart * Stopping domain name service... bind9 waiting for pid 4106 to die ...done. * Starting domain name service... bind9 ...done.View Code
找一台機器作為DNS客戶端,將客戶端的 DNS 修改為剛剛搭建的DNS服務器的 ip 地址
########這是修改的本地DNS配置的真實文件 sudo vim /etc/resolvconf/resolv.conf.d/head ####如下 nameserver 192.168.124.8 ########修改本地DNS配置文件的link sudo vim /etc/resolv.conf ####如下 options timeout:1 attempts:1 rotate nameserver 192.168.124.8 ########運行 resolvconf 更新 sudo resolvconf -uView Code
使用nslookup來查詢服務器(若使用其他的客戶端, ip 地址 需要加入到 "trusted" ACL 裡面)。
dashuai@ubuntu:~$ nslookup dashuaiBlog.com Server: 192.168.124.8 Address: 192.168.124.8#53 Non-authoritative answer: Name: dashuaiBlog.com Address: 192.168.124.8 dashuai@ubuntu:~$ nslookup 192.168.124.8 Server: 192.168.124.8 Address: 192.168.124.8#53 Non-authoritative answer: 8.124.168.192.in-addr.arpa name = host1.dashuaiBlog.comView Code
nslookup_百度百科