
1. DNS 是什么?
DNS (Domain Name System 的縮寫)的作用非常簡單,就是根據域名查出IP地址,你可以把它想象成一本巨大的電話本,
舉例來說,如果你要訪問域名math.stackexchange.com,首先要通過DNS查出它的IP地址是151.101.129.69,
2. 域名的層級
由于后面我會講到 DNS 的決議程序,因此需要你對域名的層級有一些了解
- 根域名 :
.root或者.,通常是省略的 - 頂級域名,如
.com,.cn等 - 次級域名,如
baidu.com里的baidu,這個用戶是可以注冊購買的 - 主機域名,比如
baike.baidu.com里的baike,這個用戶是可分配的
主機名.次級域名.頂級域名.根域名
baike.baidu.com.root
3. DNS 決議程序
咱們以訪問 www.163.com 這個域名為例,來看一看當你訪問 www.163.com 時,會發生哪些事:
- 先查找本地 DNS 快取(自己的電腦上),有則回傳,沒有則進入下一步
- 查看本地 hosts 檔案有沒有相應的映射記錄,有則回傳,沒有則進入下一步
- 向本地 DNS 服務器(一般都是你的網路接入服務器商提供,比如中國電信,中國移動)發送請求進行查詢,本地DNS服務器收到請求后,會先查下自己的快取記錄,如果查到了直接回傳就結束了,如果沒有查到,本地DNS服務器就會向DNS的根域名服務器發起查詢請求:請問老大,
www.163.com的ip是啥? - 根域名服務器收到請求后,看到這是個
.com的域名,就回信說:這個域名是由.com老弟管理的,你去問他好了,這是.com老弟的聯系方式(ip1), - 本地 DNS 服務器接收到回信后,照著老大哥給的聯系方式(ip1),馬上給
.com這個頂級域名服務器發起請求:請問.com大大,www.163.com的ip 是啥? .com頂級域名服務器接收到請求后,看到這是163.com的域名,就回信說:這個域名是.163.com老弟管理的,你就去問他就行了,這是他的聯系方式(ip2)- 本地 DNS 服務器接收到回信后,按照前輩的指引(ip2),又向
.163.com這個權威域名服務器發起請求:請問163.com大大,請問www.163.com的ip是啥? 163.com權威域名服務器接收到請求后,確認了是自己管理的域名,馬上查了下自己的小本本,把www.163.com的ip告訴了 本地DNS服務器,- 本地DNS服務器接收到回信后,非常地開心,這下總算拿到了
www.163.com的ip了,馬上把這個訊息告訴了要求查詢的客戶(就是你的電腦),由于這個程序比較漫長,本地DNS服務器為了節省時間,也為了盡量不去打擾各位老大哥,就把這個查詢結果偷偷地記在了自己的小本本上,方便下次有人來查詢時,可以快速回應,
總結起來就是三句話
- 從"根域名服務器"查到"頂級域名服務器"的NS記錄和A記錄(IP地址)
- 從"頂級域名服務器"查到"次級域名服務器"的NS記錄和A記錄(IP地址)
- 從"次級域名服務器"查出"主機名"的IP地址

4. DNS的快取時間
上面的幾個步驟里,可以看到有兩個地方會快取 DNS 的查詢記錄,有了快取,在一定程度上會提高查詢效率,但同時在準確率上會有所損失,
因此我們在配置 DNS 決議的時候,會有一個 TTL 引數(Time To Live),意思就是這個快取可以存活多長時間,過了這個時間,本地 DNS 就會洗掉這條記錄,洗掉了快取后,你再訪問,就要重新走一遍上面的流程,獲取最新的地址,

5. DNS 的記錄型別
當我們在阿里云買了一個域名后,可以配置我們主機域名決議規則,也就是 記錄,

常見的 DNS 記錄型別如下
-
A:地址記錄(Address),回傳域名指向的IP地址, -
NS:域名服務器記錄(Name Server),回傳保存下一級域名資訊的服務器地址,該記錄只能設定為域名,不能設定為IP地址, -
MX:郵件記錄(Mail eXchange),回傳接收電子郵件的服務器地址, -
CNAME:規范名稱記錄(Canonical Name),回傳另一個域名,即當前查詢的域名是另一個域名的跳轉,詳見下文, -
PTR:逆向查詢記錄(Pointer Record),只用于從IP地址查詢域名,詳見下文,
6. DNS 報文結構
后面我將使用 wireshark 抓取 DNS 的資料包,但是在開始之前 ,得先了解一下 DNS 的報文結構

- 事務 ID:DNS 報文的 ID 標識,對于請求報文和其對應的應答報文,該欄位的值是相同的,通過它可以區分 DNS 應答報文是對哪個請求進行回應的,
- 標志:DNS 報文中的標志欄位,
- 問題計數:DNS 查詢請求的數目,
- 回答資源記錄數:DNS 回應的數目,
- 權威名稱服務器計數:權威名稱服務器的數目,
- 附加資源記錄數:額外的記錄數目(權威名稱服務器對應 IP 地址的數目),
7. Wireshark抓包實戰
打開 Wireshark 后,使用 ping 163.com 來發起 DNS 決議請求,使用 DNS 關鍵字在Wireshark 過濾,
從抓取的報文整體來看,我們可以粗略獲取幾個資訊
- DNS 是應用層協議,傳輸層協議使用的是 UDP
- DNS 默認埠是 53

請求和應答的報文的截圖我放在了下面,接下來我將逐個分析,
請求

應答

Transaction ID
請求和應答的事務ID應當是一個:0xd0d7
Flags
標志欄位里的內容比較多,每個欄位的含義如下
- QR(Response):查詢請求/回應的標志資訊,查詢請求時,值為 0;回應時,值為 1,
- Opcode:操作碼,其中,0 表示標準查詢;1 表示反向查詢;2 表示服務器狀態請求,
- AA(Authoritative):授權應答,該欄位在回應報文中有效,值為 1 時,表示名稱服務器是權威服務器;值為 0 時,表示不是權威服務器,
- TC(Truncated):表示是否被截斷,值為 1 時,表示回應已超過 512 位元組并已被截斷,只回傳前 512 個位元組,
- RD(Recursion Desired):期望遞回,該欄位能在一個查詢中設定,并在回應中回傳,該標志告訴名稱服務器必須處理這個查詢,這種方式被稱為一個遞回查詢,如果該位為 0,且被請求的名稱服務器沒有一個授權回答,它將回傳一個能解答該查詢的其他名稱服務器串列,這種方式被稱為迭代查詢,
- RA(Recursion Available):可用遞回,該欄位只出現在回應報文中,當值為 1 時,表示服務器支持遞回查詢,
- Z:保留欄位,在所有的請求和應答報文中,它的值必須為 0,
- rcode(Reply code):回傳碼欄位,表示回應的差錯狀態,當值為 0 時,表示沒有錯誤;當值為 1 時,表示報文格式錯誤(Format error),服務器不能理解請求的報文;當值為 2 時,表示域名服務器失敗(Server failure),因為服務器的原因導致沒辦法處理這個請求;當值為 3 時,表示名字錯誤(Name Error),只有對授權域名決議服務器有意義,指出決議的域名不存在;當值為 4 時,表示查詢型別不支持(Not Implemented),即域名服務器不支持查詢型別;當值為 5 時,表示拒絕(Refused),一般是服務器由于設定的策略拒絕給出應答,如服務器不希望對某些請求者給出應答,
Answer RRs
回答資源記錄數,在應答包里為 2,說明回傳了兩條查詢結果,你可以在 Answer 欄位里看到,
Authority RRs
權威名稱服務器計數
Additionnal RRs
附加資源記錄數
Answers
應答的主要內容,這里回傳兩條結果,每條結果里的欄位有
Name: 查詢的域名
Type: A表示IPv4,AAAA 表示IPv6
Class: 表示Internet,幾乎總是它
Time to live: 生存時間
Data length: 資料長度
Address: 查詢到的 IP 地址
8. DNS 劫持 與 HTTP 劫持
通過上面的講解,我們都知道了,DNS 完成了一次域名到 IP 的映射查詢,當你在訪問 www.baidu.com 時,能正確回傳給你 百度首頁的 ip,
但如果此時 DNS 決議出現了一些問題,當你想要訪問 www.baidu.com 時,卻回傳給你 www.google.com 的ip,這就是我們常說的 DNS 劫持,
與之容易混淆的有 HTTP 劫持,
那什么是 HTTP 劫持呢?
你一定見過當你在訪問 某個網站時,右下角也突然彈出了一個扎眼的廣告彈窗,這就是 HTTP 劫持,
借助別人文章里的例子,它們倆的區別就好比是
-
DNS劫持是你想去機場的時候,把你給丟到火車站,
-
HTTP劫持是你去機場途中,有人給你塞小廣告,
那么 DNS劫持 是如何產生的呢?
下面大概說幾種DNS劫持方法:
1.本機DNS劫持
攻擊者通過某些手段使用戶的計算機感染上木馬病毒,或者惡意軟體之后,惡意修改本地DNS配置,比如修改本地hosts檔案,快取等
2. 路由DNS劫持
很多用戶默認路由器的默認密碼,攻擊者可以侵入到路由管理員賬號中,修改路由器的默認配置
3.攻擊DNS服務器
直接攻擊DNS服務器,例如對DNS服務器進行DDOS攻擊,可以是DNS服務器宕機,出現例外請求,還可以利用某些手段感染dns服務器的快取,使給用戶回傳來的是惡意的ip地址
9. 工具的使用
dig 命令
dig是一個在類Unix命令列模式下查詢DNS包括NS記錄,A記錄,MX記錄等相關資訊的工具,
通過 dig (引數:+trace)命令,我們可以看到上面描述的 DNS 決議的詳細程序

從回傳的結果,我們可以看得出幾點資訊
- 我們的本地 DNS 服務器 ip 為 192.168.1.1,埠為53,你可以在 /etc/resolv.conf 里看到這個配置
- 根域名服務器目前全球一共只有十三臺,從a.root-servers.net.
到m.root-servers.net. ,它們對應的ip地址,已經內置在本地DNS服務器中,
如果你只想看到結果,可以使用 +short 引數,可以直接回傳 www.163.com 對應著哪幾個ip

你也可以加個 @ 引數 ,指定從某個 DNS 服務器進行查詢

如果你只想查看指定的記錄型別

host 命令
host 命令 可以看作dig命令的簡化版本,回傳當前請求域名的各種記錄,

whois命令
whois命令用來查看域名的注冊情況,

nslookup命令
nslookup也是常用的一個查詢 DNS 決議結果的工具
$ nslookup [查詢的域名] [指定DNS服務器]

你也可以指定公網的域名服務器進行查詢,比如常見的 114.114.114.114

10. 手動清理本地快取
MacOS
$ sudo dscacheutil -flushcache
$ sudo killall -HUP mDNSResponder
Windows
$ ipconfig /flushdns
Linux
# 使用NSCD的DNS快取
$ sudo /etc/init.d/nscd restart
# 服務器或者路由器使用DNSMASQ
$ sudo dnsmasq restart

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/5013.html
標籤:Go
下一篇:Go語言的執行順序(轉)
