「計算機網絡」| DNS & HTTPDNS

點贊關注,不再迷路,你的支持對我意義重大!

🔥 Hi,我是醜醜。本文「計算機網絡」| 導讀 —— 跬步千里,始於足下 已收錄,這裏有 Android 進階成長路線筆記 & 博客,歡迎跟着彭醜醜一起成長。(聯繫方式在 GitHub)

前言

  • DNS 往往是網絡請求的第一步,在計算機網絡面試中,DNS 也是除 HTTP、TCP 之外較重點考察的知識,其重要性可想而知。
  • 在這篇文章裏,我將梳理圖解 DNS & HTTPDNS 的原理知識。如果能幫上忙,請務必點贊加關注,這真的對我非常重要。

目錄


1. DNS 原理

1.1 DNS 簡介

域名(Domain Name,Domain) 是一個在互聯網上標識主機或主機組的名稱,相當於 IP 地址的別名,相對於晦澀難記的 IP 地址,域名更顯得易於記憶。

域名系統(Domain Name System,DNS) 則是將域名解析 IP 地址的一項互聯網基礎服務,提供該服務的服務器稱爲 域名服務器(Domain Name Server)

1.2 DNS 解析過程

互聯網上的域名系統是一個分佈式的系統,結構上是一個四層的樹狀層次結構,如下圖所示:

  • 本地域名服務器(Local Name Server,local DNS):如果通過 DHCP 配置,local DNS 由互聯網服務提供商(ISP,如聯通、電信)提供;

  • 根域名服務器(Root Name Server):當 local DNS 查詢不到解析結果時,第一步會向它進行查詢,並獲取頂級域名服務器的IP地址。全球一共有 13 個根域名服務器(除了它們的鏡像),它們並不直接用於域名解析,僅用於指出可查詢的頂級域名服務器。這個網站記錄了現有的 13 個根域名服務器:https://www.internic.net/domain/named.root

  • 頂級域名服務器(Top-level Name Server):負責管理在該頂級域名服務器下注冊的二級域名,例如.com 頂級域名服務器,而 baidu.com 權威服務器是註冊在 .com 的權威域名服務器;

  • 權威域名服務器(Authoritative Name Server):在特定區域內具有唯一性,負責維護該區域內的域名與 IP 地址的映射關係。在 DNS 應答報文中,標誌位 AA 標識本次 DNS 記錄是否來自權威域名服務器,否則可能來自緩存。

DNS 解析分爲 遞歸查詢迭代查詢 兩種方式。其中,客戶端與 Local DNS 之間一般採用遞歸查詢,而 DNS 服務器之間一般採用迭代查詢。

提示:如果 DNS 服務器之間使用遞歸查詢,對根域名服務器的負擔就太重了,而如果客戶端與本地域名服務器之間使用迭代查詢,DNS 服務對於客戶端就顯得不透明瞭。

  • 遞歸查詢:

所謂遞歸查詢,與我們經常提及的遞歸函數的思想是一致的,即:如果 DNS 服務器查不到該域名,那麼它將重新以客戶端的身份向其他 DNS 服務器發送查詢請求報文,客戶端只要等待最終結果即可。用僞代碼呈現可能比較好理解,類似這樣:

fun dns(client: String, server: String, domain: String): String {
    if (server 查詢 domain 成功) {
        return "ip"
    }
    // server 以客戶端身份遞歸查詢
    return dns(server, "其他 DNS 服務器", domain)
}
  • 迭代查詢:

所謂迭代查詢,即:如果 DNS 服務器查不到該域名,它不會替客戶端完成後續的查詢工作,而是回覆下一步應當向哪一個域名服務器進行查詢,隨後客戶端重新向這個新的 DNS 服務器發送查詢請求。用僞代碼呈現可能比較好理解,類似這樣:

fun dns(client: String, server: String, domain: String): String {
    while (true) {
        if (server 查詢 domain 成功) {
            return "ip"
        } else {
            // client 繼續以客戶端身份迭代查詢
            server = "其他 DNS 服務器"
        }
    }
}

下面以查詢www.baidu.com爲例,闡述一次 DNS 解析過程:

  • 0、首先檢查 DNS 緩存,下一節我們會講,如果緩存老化或未命中,客戶端需要向 local DNS 發送查詢請求報文

  • 1、客戶端local DNS 發送查詢報文 query www.baidu.comlocal DNS 首先檢查自身緩存,如果存在記錄則直接返回結果,查詢結束;如果緩存老化或未命中,則:

  • 2、local DNS根域名服務器發送查詢報文 query www.baidu.com,返回 .com 頂級域名服務器的地址(如果查無記錄)

  • 3、local DNS.com 頂級域名服務器發送查詢報文 query www.baidu.com,返回baidu.com所在的權威域名服務器的地址(如果查無記錄)

  • 4、local DNSbaidu.com 權威域名服務器發送查詢報文 query www.baidu.com,得到 ip 地址,存入自身緩存並返回給客戶端

1.3 DNS 報文

由於下一節我們將實戰抓取 DNS 包,所以這一節我們先介紹 DNS 報文格式。DNS 協議定義了三種報文,查詢報文 & 應答報文 & 更新報文,它們的總體上結構是一致的。

  • 報文首部(Header)
    • 1、事務 ID(Transaction ID):用來關聯 DNS 查詢與應答,DNS客戶端每次發送查詢請求都會使用不同的 ID,而服務器在響應中重複這個 ID
    • 2、標誌(Flags):報文的標誌字段,詳見下圖
    • 3、問題數(Question Count):指定問題部分條目數
    • 4、回答資源記錄數(Answer Resource Record count):指定應答部分中回答資源條目數
    • 5、權威資源記錄數(Authority Resource Record count):指定權威資源記錄數
    • 6、附加資源記錄數(Additional Resource Record count):指定附加資源記錄數
  • 問題(Question)

問題用於表達具體查詢的問題,問題個數與報文首部中的 問題數(Question Count)字段一致。需要注意的是,按照 DNS 查詢的目的,DNS 解析可以分爲 正向解析反向解析 兩種,正向解析將域名解析爲 IP 地址,而反向解析則恰恰相反,用於將 IP 地址解析域名。問題條目中 查詢類型 是比較重要的字段,這裏僅列出 5 個比較常用的類型:

QTYPE 描述
A(1) 將域名解析爲 IPv4 地址
NS(2) 查詢域名服務
CNAME(5) 規範名稱
PTR(12) IP 地址解析爲域名
AAAA(28) 將域名解析爲 IPv6 地址

NSCNAME 不好理解,這裏解釋下:

CNAME(Canonical NAME) 是規範名稱或別名,用於將一個域名指向另一個域名。具體方法是:將一個域名作爲 A 記錄 指向 IP 地址,而其他域名作爲別名指向 A 記錄的域名,此時如果需要更改 IP 地址,就不需要更改每個域名的映射了,只需要修改 A 記錄 ,而 CNAME 記錄將自動指向新的 IP 地址。在 第 1.4 節 DNS 解析實戰 中你將直接看到 CNAME 的應用。

NS(Name Server) :域名服務器記錄,用來指定該域名由哪個 DNS 服務器來進行解析

  • 資源記錄(Resource Record)

回答資源記錄、權威資源記錄和附加資源記錄的格式相同,其中 TTL(Time to Live,單位秒) 表示資源記錄的生存時間,也就是允許緩存的時間。0 表示該記錄只能用於當前響應,不允許被緩存。

1.4 DNS 報文的傳輸協議

DNS 協議在傳輸層同時使用 TCP 和 UDP 協議,佔用的是 53 端口,那麼在什麼情況下使用這兩種協議?

  • 在區域傳輸時使用 TCP 協議

主輔域名服務器在進行區域傳送時(主輔域名服務器用於平衡負載),需要傳送的數據比簡單的查詢 & 應答報文的數據量要大得多了。使用 UDP 傳輸不可靠,所以採用應用於傳輸大量數據,可靠性更高的 TCP 協議。

  • 在域名解析時使用 UDP 協議

爲了得到一個域名的 IP 地址,往往會向多個域名服務器查詢,如果使用 TCP 協議,那麼每次請求都會存在三次握手連接時延,這樣使 DNS 服務變得很慢。

需要注意的是,DNS 協議規定 UDP 報文段的最大長度爲 512 字節,如果 DNS 報文段過長時會被截斷(此時 DNS 報文頭中標誌位 TC(Truncation)置爲 1),多餘的數據會直接丟棄。這是因爲 UDP 是無連接的,無法確定哪幾個 UDP 包是屬於同一個 DNS 報文段的。

1.5 DNS 解析實戰

計算機網絡是在實踐中發展起來的學科,僅停留在學習理論知識的層面是不夠的,下面我們將在實踐中學習 DNS 解析。在這裏,我們是用 WireShark 抓取查詢www.baidu.com的 DNS 請求,具體步驟如下:

  • 步驟一:設置 WireShark 過濾條件

在過濾條件欄輸入條件:icmp || dns,如下圖:

在終端輸入ping www.baidu.com,如下圖:

  • 步驟三:查看 DNS 查詢 & 應答報文

返回 WireShark,查看抓取的消息,可以看到兩條 DNS 報文消息,一條爲查詢報文,另一條爲應答報文,如下圖:

現在我們具體查看這兩條 DNS 報文消息,有了上一節的鋪墊,相信閱讀這兩段報文已經很簡單了。先看 DNS 協議的報文段部分,下層協議的報文段後面講:

  • 查詢報文:

在這個報文裏提出了一個問題,即:查詢 www.baidu.com 的 IPv4 地址(A 記錄),標記位指出以下信息:這是一個查詢報文;這是一次正向解析;報文未截斷;要求服務器執行遞歸查詢;

  • 應答報文:
  • 傳輸層 & 網絡層:

從圖中還驗證了 DNS 在進行域名解析時使用 UDP 協議,端口號爲 53,與上一小節的分析一致。另外,還可以看出 IP 包的第一跳是發送給局域網路由器,而不是直接發送給 local DNS 服務器,這也合理。

1.6 DNS 緩存

一次完整的 DNS 查詢過程需要訪問多臺 DNS 服務器才能得到最終的結果,這肯定會帶來一定的時延。爲了改善時延,DNS 服務並不是每次請求都要去訪問 DNS 服務器,而是訪問過一次後將 DNS 記錄緩存在本地。具體來說,DNS 服務是一個多級的緩存:

瀏覽器緩存 -> 操作系統緩存 -> 路由器緩存 -> local DNS 緩存 -> DNS 查詢

緩存並不是永久有效的,前面提到過 DNS 應答報文中的 TTL(Time to Live)值,它決定了 DNS 記錄在緩存中的有效時間。需要注意的是,TTL 只是一個參考值,實際使用的緩存有效時間不一定等於該值,甚至是固定值。這也引發 DNS 緩存也存在一些“副作用”,我後文再說。


2. DNS 存在的問題

經過上一節的 DNS 理論知識學習和實踐探索,相信大家對 DNS 已經建立起了一定的認識。那麼,DNS 是一個完備的服務嗎,在實踐中它有存在什麼問題呢?這一節我們來討論這個問題。

2.1 DNS 查詢時延

從第一節的分析可以看出,一次完整的 DNS 查詢過程需要訪問多臺 DNS 服務器才能得到最終的結果,這肯定會帶來一定的時延。從實踐來看,這個時間還不容小覷。

提示: 有贊技術團隊指出,DNS 解析時延的波動較大,好的情況幾毫秒、十幾毫秒就完成了,差的時候,可能需要花很多時間:《有贊webview加速平臺探索與建設》 —— 有贊移動組

2.2 緩存一致性

DNS 緩存的存在雖然減少了時延,卻是以犧牲一致性(consistency)爲代價的。具體來說:Local DNS 是分地區、分運營商的,在域名解析緩存的處理上,實現策略就不統一了。有時候 Local DNS 的解析結果 可能不是最近、最優的節點,有的時候並不會遵從 TTL 的限制,而是設置一個固定時間。這就會導致域名指向新的 IP 地址後,一些客戶端依然訪問了緩存中 舊的 IP 地址。

除了運營商的緩存策略外,緩存投毒也是降低 DNS 可用性的原因。攻擊者可以通過 DNS 劫持,利用 DNS 的緩存機制不對應答數據做檢查的漏洞,誘騙 DNS 服務器緩存較大 TTL 的虛假 DNS 記錄,從而長期欺騙客戶端。

2.3 DNS 劫持(中間人攻擊)

由於 DNS 缺乏 加密、認證、完整性保護的安全機制,容易引發網絡完全問題。最常見的域名劫持攻擊是針對 DNS 報文首部的 事務 ID 進行欺騙,由於事務 ID 在查詢報文和應答報文中是匹配的,因此僞裝 DNS 服務器可以提前將事務 ID 相同的僞造報文發送到客戶端,以實現域名劫持(前提是合法的報文還未到達),把目標網站域名解析到錯誤的 IP 地址。

提示: 獲取事務 ID 的方法主要採用 網絡監聽與序列號猜測,具體可翻閱《計算機網路安全原理》 (第 8 章)—— 吳禮發 著

2.4 調度不精準問題

由於存在緩存、轉發、NAT 等問題,權威的 DNS 服務器可能會誤判客戶端所在的位置和運營商,從而導致解析出跨運營商訪問的 IP 地址,用戶的訪問速度降低。


3. HTTPDNS 原理

雖然 DNS 存在不少問題,但也不能因噎廢食放棄整套域名系統,解決方案無非是不走尋常路,換一種方式獲取 IP 地址 —— HTTPDNS。

3.1 HTTPDNS 簡介

與傳統的 DNS 解析不同,HTTPDNS 是自己搭建基於 HTTP 協議的服務器,當客戶端需要 DNS 解析的時候,不再向 local 發送 DNS 查詢報文,而是直接通過請求直接訪問 HTTPDNS 接口。而服務端則根據客戶端的位置和所屬運營商,返回就近的 IP 地址。

當然了,基於容災考慮,當出現 HTTPDNS 不可用時會觸發降級策略,使用運營商 LocalDNS 進行域名解析。

3.2 HTTPDNS 優勢

相對與 DNS,HTTPDNS 的主要優點如下:

  • 降低時延
    縮短了查詢鏈路,不像 DNS 查詢那樣需要訪問多臺 DNS 服務器才能得到最終的結果;

  • 域名防劫持
    域名解析請求直接發送至HTTPDNS服務器,繞過運營商 Local DNS,避免域名劫持問題;

  • 調度精準
    由於 DNS 服務器端獲取的是真實客戶端 IP 而非 Local DNS 的 IP,能夠精確基於客戶端位置、運營商信息,獲得最精準的解析結果,讓客戶端就近接入業務節點

  • 快速生效
    域名解析結果變更時,HTTPDNS 服務沒有傳統DNS 服務多級緩存的影響,域名更新能夠更快地覆蓋到全量客戶端。

3.3 HTTPDNS 正向效益

目前,騰訊、阿里和百度都有自己的 HTTPDNS 解決方案,筆者收集了他們公示的使用效益,具體如下:

  • 騰訊

    • 官方文檔 :覆蓋超4億+用戶,減少了超過60%的由於域名劫持導致的用戶訪問失敗,減少了22%的用戶平均延遲;
    • 官方博客:用戶平均訪問延遲下降超過10%,訪問失敗率下降了超過五分之一;
  • 百度

    • 官方博客:iOS劫持率由0.12%降低到0.0002%,Android劫持率由0.25%降低到0.05%,第二點的收益不明顯,原因在於Feed業務主要目標羣體在國內,百度在國內節點佈局相對豐富,服務整體質量也較高;
  • 阿里
    未查及...


4. 總結

應試方面,建議重點掌握四層 DNS 解析過程 & HTTPDNS 原理、理解知曉 DNS 存在的問題、DNS 報文格式重點理解 TTL、幾種查詢類型。


參考資料

實用資源


創作不易,你的「三連」是醜醜最大的動力,我們下次見!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章