抓包理解 DNS 流程和 CDN 原理

DNS (Domain Name System)是我們每天都用到的協議,CDN (Content Delivery Network)也經常會接觸到,但你能說出它們的原理麼?

能說出原理的話,有抓包看過它們真實的數據包麼?

今天我們就一起通過抓包來深入下 DNS 流程和 CDN 原理吧。

DNS 實現原理

DNS 的流程可以看這張圖:

瀏覽器訪問了某個域名,首先會查找瀏覽器緩存、本地 hosts 文件、DNS 緩存,沒有找到的話再去請求本地 DNS 服務器,由它負責完成域名的解析。

本地 DNS 會依次請求根域名服務器拿到對應的頂級域名服務器的地址,然後請求頂級域名服務器,拿到權威域名服務器的地址,之後權威域名服務器會返回最終的 IP 給本地 DNS 服務器,由它再返給瀏覽器。

比如說 baidu.com 這個域名,根域名是 .,頂級域名(也叫一級域名)是 com,而二級域名是 baidu.com,那會先向根域名服務器查找 com 的頂級域名服務器的地址,然後再向 com 的頂級域名服務器查找 baidu.com 的權威域名服務器的地址。

有的同學可能會問,那 image.baidu.com 或者 xx.yy.zz.baidu.com 呢?

二級域名和更多級的域名都在權威域名服務器解析,域名服務器只有三級。

因爲域名服務器之所以這樣分級是爲了通過負載均衡來分散壓力,具體的域名解析都是由各自的權威域名服務器來處理的,根域名和頂級域名服務器只是做了個轉發。

三級就已經能達成目的了,更多級可以自己分,比如後面會講的 CDN 服務就是自己做了更多級的負載均衡。

說到了 CDN,那 CDN 與 DNS 是啥關係呢?

CDN 的實現原理

CDN 不是一種協議,只是基於 DNS 協議實現的一種分佈式網絡。

前面說到根域名和頂級域名服務器只是做了轉發,最終域名解析都是在權威域名服務器做的。

那權威域名服務器是不是可以再做一層轉發呢?

比如下面是百度雲 CDN 的原理圖:

權威 DNS 服務器通過 CNAME 的配置(DNS 協議裏指定別名的方式)把請求轉發到了 baidu 的 DNS 服務器,baidu 的 DNS 服務器再根據 IP 返回用戶所在區域的一臺機器的 IP。

這樣用戶從這個域名下載內容的時候,就找到了最近的一臺機器,那速度自然快很多。

這就是 CDN 的原理。

大概介紹了 DNS 和 CDN 的實現原理,下面我們通過抓包來驗證下。

抓包驗證上述結論

我們一步步來,首先,前面講到這三級查找是對的麼?

瀏覽器緩存和 DNS 緩存真的存在麼?真的會查 hosts 文件麼?

我們用抓包工具來驗證下:

這種網絡包需要用 wireshark 來抓。

抓取網卡的數據包,過濾 DNS 的包:

刷新頁面就可以看到所有 DNS 數據包了:

然後你可以打開 chrome://net-internals/#dns ,查詢某個域名的瀏覽器 DNS 緩存:

點擊按鈕可以清掉瀏覽器 DNS 緩存:

這證明了瀏覽器緩存的存在。

我們再往下驗證,hosts 真的會生效麼?

修改下 hosts 文件,加個配置:

用 ping 命令試了下,真的生效了,這說明 DNS 確實會查詢 hosts 文件。

然後繼續驗證下系統的 DNS 緩存真的存在麼?

我 ping 了幾次 www.baidu.com,都沒有新的 DNS 數據包,說明確實是有緩存的。

可以執行這個命令清掉系統 DNS 緩存:sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

我 ping 了兩次 www.baidu.com 都沒有 DNS 數據包,但是我一清空緩存,再 ping 就有了:

這驗證了系統級別的 DNS 緩存確實存在。

也就是說瀏覽器 DNS 緩存、hosts 文件、系統 DNS 緩存這三步確實都是會經歷的:

繼續往下看,本地 DNS 服務是啥?

這個可以在 “系統偏好設置> 網絡 > 高級” 裏看到:

確實是有本地 DNS 服務器的地址的,這個一般是運營商提供的,可能每個城市都有一些公共的。這一級也有緩存。

通過這層層緩存加上域名系統本身就是分佈式的,這種設計極大的減輕了 DNS 服務器的壓力,實現了高併發,這是我們每天都在用的高併發系統。

繼續往後看,這三級域名服務怎麼驗證呢?

可以 ping 一個不存在的域名,比如 ddd1111.com

這時候可以看到請求了 com 的域名服務器,地址是 a.gtld-server.net,沒錯,這個就是一個頂級域名服務器的域名。

但你再請求一個別的域名,你會發現它並沒有從根域名頂級域名開始查,而是直接從權威域名服務器開始的:

沒錯,這也是緩存,本地 DNS 服務器會把域名對應的權威域名服務器的 IP 緩存下來,直接去那裏查。

你會發現有的返回結果是 CNAME,值爲一個域名,這個 CNAME 是一種記錄類型,別名的意思。之後會再去這裏查,最後查到 A 的記錄類型,值就是 IP 了。

CDN 就是這麼實現的,我們來看一個真實的 CDN 的 DNS 查詢的例子:

這是 www.baidu.com 的 DNS 查詢結果:

你會發現先通過 CNAME 指向了另一個域名,然後這個域名又給了兩條 IP 的結果。

對照下 CDN 的原理圖,就知道這倆 IP 都是離用戶最近的服務器的 IP 了:

這就是 CDN 的原理。

再來看個 www.juejin.cn 的,他也是用了 CDN 的:

也是同樣 CNAME 指向了 CDN 的 DNS 服務器,然後返回了就近的一些服務器的 IP,只不過它的負載均衡的機器更多一些。

總結

我們通過 wireshark 抓包的方式,驗證了 DNS 的流程和 CDN 的實現原理。

DNS 的流程是會先查找瀏覽器 DNS 緩存、hosts 文件、系統 DNS 緩存,然後請求本地 DNS 服務器,由它去一級級查詢最終的 IP:

CDN 是基於 DNS 的,在權威域名服務器做了 CNAME 的轉發,然後根據請求 IP 的所在地來返回就近區域的服務器的 IP。

這個流程是有一層層的緩存的,而且還是分佈式的,是我們接觸最多的高併發系統了。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ywg7J8sZm6elkuNQ7WKfJw