DNS 原理入門,你學(xué)會了嗎?
概述
DNS 是互聯(lián)網(wǎng)核心協(xié)議之一。不管是上網(wǎng)瀏覽,還是編程開發(fā),都需要了解一點它的知識。
本文詳細介紹 DNS 的原理,以及如何運用工具軟件觀察它的運作。我的目標(biāo)是,讀完此文后,你就能完全理解 DNS。
一、DNS 是什么?
DNS(Domain Name System 的縮寫)的作用非常簡單,就是根據(jù)域名查出IP地址。你可以把它想象成一本巨大的電話本。
舉例來說,如果你要訪問域名 math.stackexchange.com,首先要通過 DNS 查出它的IP地址是 151.101.129.69。
如果你不清楚為什么一定要查出IP地址,才能進行網(wǎng)絡(luò)通信,建議先閱讀我寫的 《互聯(lián)網(wǎng)協(xié)議入門》[1]。
二、查詢過程
雖然只需要返回一個IP地址,但是 DNS 的查詢過程非常復(fù)雜,分成多個步驟。
工具軟件 dig 可以顯示整個查詢過程。
上面的命令會輸出 6 段信息。
如果不想看到這么多內(nèi)容,可以使用 +short 參數(shù)
上面命令只返回 math.stackexchange.com 對應(yīng)的 4 個 IP 地址(即A記錄)。
三、DNS服務(wù)器
下面我們根據(jù)前面這個例子,一步步還原,本機到底怎么得到域名 math.stackexchange.com 的IP地址。
首先,本機一定要知道 DNS 服務(wù)器的IP地址,否則上不了網(wǎng)。通過DNS服務(wù)器,才能知道某個域名的IP地址到底是什么。
查看 DNS 服務(wù)器配置
DNS 服務(wù)器的IP地址,有可能是動態(tài)的,每次上網(wǎng)時由網(wǎng)關(guān)分配,這叫做 DHCP 機制;也有可能是事先指定的固定地址。 Linux系統(tǒng)里面,DNS 服務(wù)器的 IP 地址保存在 /etc/resolv.conf 文件。
上例的 DNS 服務(wù)器是 192.168.1.253,這是一個內(nèi)網(wǎng)地址。有一些公網(wǎng)的DNS服務(wù)器,也可以使用,其中最有名的就是 Google 的 8.8.8.8 和 Level 3 的 4.2.2.2。
本機只向自己的 DNS 服務(wù)器查詢,dig 命令有一個@參數(shù),顯示向其他 DNS 服務(wù)器查詢的結(jié)果。
上面命令指定向 DNS 服務(wù)器 4.2.2.2 查詢。
四、域名的層級
DNS 服務(wù)器怎么會知道每個域名的 IP 地址呢?答案是分級查詢。
請仔細看前面的例子,每個域名的尾部都多了一個點。
比如,域名 math.stackexchange.com 顯示為 math.stackexchange.com.。這不是疏忽,而是所有域名的尾部,實際上都有一個根域名。
舉例來說,www.example.com 真正的域名是 www.example.com.root ,簡寫為 www.example.com. 。因為,根域名.root 對于所有域名都是一樣的, 所以平時是省略的。
根域名的下一級,叫做 頂級域名(top-level domain,縮寫為 TLD),比如 .com、.net;再下一級叫做 次級域名(second-level domain,縮寫為 SLD), 比如 www.example.com 里面的 .example,這一級域名是用戶可以注冊的;再下一級是 主機名(host),比如 www.example.com 里面的 www,又稱為 三級域名, 這是用戶在自己的域里面為服務(wù)器分配的名稱,是用戶可以任意分配的。
總結(jié)一下,域名的層級結(jié)構(gòu)如下。
主機名.次級域名.頂級域名.根域名
五、根域名服務(wù)器
DNS 服務(wù)器根據(jù)域名的層級,進行分級查詢。
需要明確的是,每一級域名都有自己的 NS 記錄,NS 記錄指向該級域名的域名服務(wù)器。這些服務(wù)器知道下一級域名的各種記錄。
所謂 分級查詢,就是從根域名開始,依次查詢每一級域名的 NS 記錄,直到查到最終的 IP 地址,過程大致如下。
1. 從 "根域名服務(wù)器" 查到 "頂級域名服務(wù)器"的 NS 記錄和 A 記錄(IP 地址)
2. 從 "頂級域名服務(wù)器" 查到 "次級域名服務(wù)器"的 NS 記錄和 A 記錄(IP 地址)
3. 從 "次級域名服務(wù)器" 查到 "主機名"的 IP 地址
仔細看上面的過程,你可能發(fā)現(xiàn)了,沒有提到 DNS 服務(wù)器怎么知道 "根域名服務(wù)器" 的 IP 地址。 回答是 "根域名服務(wù)器" 的 NS 記錄和 IP 地址一般是不會變化的, 所以內(nèi)置在 DNS 服務(wù)器里面。
下面是內(nèi)置的根域名服務(wù)器 IP 地址的一個 例子 [2]
上面列表中,列出了根域名(.root)的三條 NS 記錄 A.ROOT-SERVERS.NET、B.ROOT-SERVERS.NET 和 C.ROOT-SERVERS.NET, 以及它們的 IP 地址(即 A 記錄)198.41.0.4、192.228.79.201、192.33.4.12。
另外,可以看到所有記錄的 TTL 值是 3600000 秒,相當(dāng)于 1000 小時。也就是說,每 1000 小時才查詢一次根域名服務(wù)器的列表。
目前,世界上一共有 13 組根域名服務(wù)器,從 A.ROOT-SERVERS.NET 一直到 M.ROOT-SERVERS.NET。
六、分級查詢的實例
dig 命令的 +trace 參數(shù)可以顯示 DNS 的整個分級查詢過程。
上面命令的第一段列出根域名.的所有 NS 記錄,即所有根域名服務(wù)器。
根據(jù)內(nèi)置的根域名服務(wù)器 IP 地址,DNS 服務(wù)器向所有這些 IP 地址發(fā)出查詢請求,詢問 math.stackexchange.com 的頂級域名服務(wù)器 com.的 NS 記錄。 最先回復(fù)的根域名服務(wù)器將被緩存,以后只向這臺服務(wù)器發(fā)請求。
接著是第二段。
上面結(jié)果顯示.com 域名的 13 條 NS 記錄,同時返回的還有每一條記錄對應(yīng)的 IP 地址。
然后,DNS 服務(wù)器向這些頂級域名服務(wù)器發(fā)出查詢請求,詢問 math.stackexchange.com 的次級域名 stackexchange.com 的 NS 記錄。
上面結(jié)果顯示 stackexchange.com 有四條 NS 記錄,同時返回的還有每一條 NS 記錄對應(yīng)的 IP 地址。
然后,DNS 服務(wù)器向上面這四臺 NS 服務(wù)器查詢 math.stackexchange.com 的主機名。
上面結(jié)果顯示,math.stackexchange.com 有 4 條 A 記錄,即這四個 IP 地址都可以訪問到網(wǎng)站。并且還顯示, 最先返回結(jié)果的 NS 服務(wù)器是 ns-cloud-d2.googledomains.com,IP 地址為 216.239.34.109。
七、NS 記錄的查詢
dig 命令可以單獨查看每一級域名的 NS 記錄。
+short 參數(shù)可以顯示簡化的結(jié)果
八、DNS 的記錄類型
域名與 IP 之間的對應(yīng)關(guān)系,稱為 "記錄"(record)。根據(jù)使用場景,"記錄"可以分成不同的類型(type),前面已經(jīng)看到了有 A 記錄和 NS 記錄。
常見的 DNS 記錄類型如下。
- ? A:地址記錄(Address),返回域名指向的 IP 地址。
- ? AAAA: 記錄是域名到 IPV6 地址。
- ? NS:域名服務(wù)器記錄(Name Server),返回保存下一級域名信息的服務(wù)器地址。該記錄只能設(shè)置為域名,不能設(shè)置為 IP 地址。
- ? MX:郵件記錄(Mail eXchange),返回接收電子郵件的服務(wù)器地址。
- ? CNAME:規(guī)范名稱記錄(Canonical Name),返回另一個域名,即當(dāng)前查詢的域名是另一個域名的跳轉(zhuǎn),詳見下文。
- ? PTR:逆向查詢記錄(Pointer Record),只用于從 IP 地址查詢域名,詳見下文。
一般來說,為了服務(wù)的安全可靠,至少應(yīng)該有兩條 NS 記錄,而 A 記錄和 MX 記錄也可以有多條,這樣就提供了服務(wù)的冗余性,防止出現(xiàn)單點失敗。
CNAME 記錄主要用于域名的內(nèi)部跳轉(zhuǎn),為服務(wù)器配置提供靈活性,用戶感知不到。舉例來說,facebook.github.io 這個域名就是一個 CNAME 記錄。
上面結(jié)果顯示,facebook.github.io 的 CNAME 記錄指向 github.map.fastly.net。也就是說,用戶查詢 facebook.github.io 的時候, 實際上返回的是 github.map.fastly.net 的 IP 地址。這樣的好處是,變更服務(wù)器 IP 地址的時候,只要修改 github.map.fastly.net 這個域名就可以了, 用戶的 facebook.github.io 域名不用修改。
由于 CNAME 記錄就是一個替換,所以域名一旦設(shè)置 CNAME 記錄以后,就不能再設(shè)置其他記錄了(比如 A 記錄和 MX 記錄),這是為了防止產(chǎn)生沖突。 舉例來說,foo.com 指向 bar.com,而兩個域名各有自己的 MX 記錄,如果兩者不一致,就會產(chǎn)生問題。由于頂級域名通常要設(shè)置 MX 記錄, 所以一般不允許用戶對頂級域名設(shè)置 CNAME 記錄。
PTR 記錄用于從 IP 地址反查域名。dig 命令的 -x 參數(shù)用于查詢 PTR 記錄。
上面結(jié)果顯示,192.30.252.153 這臺服務(wù)器的域名是 pages.github.com。
逆向查詢的一個應(yīng)用,是可以防止垃圾郵件,即驗證發(fā)送郵件的 IP 地址,是否真的有它所聲稱的域名。
dig 命令可以查看指定的記錄類型。
九、其他 DNS 工具
除了 dig,還有一些其他小工具也可以使用。
(1)host 命令
host 命令可以看作 dig 命令的簡化版本,返回當(dāng)前請求域名的各種記錄。
host 命令也可以用于逆向查詢,即從 IP 地址查詢域名,等同于 dig -x 。
(2)nslookup 命令
nslookup 命令用于互動式地查詢域名記錄。
(3)whois 命令
whois 命令用來查看域名的注冊情況。
十、參考鏈接
- ? DNS: The Good Parts, by Pete Keen[3]
- ? DNS 101, by Mark McDonnell[4]
轉(zhuǎn)載聲明
本文轉(zhuǎn)載自 DNS 原理入門[5],筆者在文字描述和圖片排版上略作修改。
小結(jié)
下面是筆者補充的部分,簡述下 DNS 的流程。
圖片來源: https://aws.amazon.com/cn/route53/what-is-dns/
- ? 瀏覽器輸入域名,如 www.example.com
- ? 查詢當(dāng)前硬件的緩存(host 文件 或瀏覽器緩存)中是否存在該域名對應(yīng)的記錄,如果存在直接使用,如果不存在則進入后續(xù)流程
- ? 向運營商的 DNS 服務(wù)器發(fā)起 DNS 解析的請求,一般稱運營商的 DNS 服務(wù)器為 Local DNS
- ? Local DNS 會查詢緩存記錄 (內(nèi)部實現(xiàn)對請求端來說是透明的)
- ? Local DNS 如果沒有緩存,會把域名從右往左掃描,依次請求對應(yīng)的服務(wù)器
- ? 對于域名 www.example.com,先去請求根域名服務(wù)器,假設(shè)根域名服務(wù)器返回了管理 .com 域的服務(wù)器,名字為 TLD
- ? Local DNS 請求管理 TLD 服務(wù)器
- ? 一般來說,TLD 返回的記錄是一條 CNAME 記錄,這里假設(shè)域名的 CNAME 解析到了 Amazon
- ? Local DNS 請求 Amazon 的 DNS 服務(wù)器 (一般稱之為權(quán)威服務(wù)器,權(quán)威服務(wù)器是 Amazon 自己構(gòu)建的)
- ? Amazon 返回 www.example.com 對應(yīng)的服務(wù)器 IP 地址
- ? Local DNS 緩存這個 IP 地址,并且返回給瀏覽器
- ? 瀏覽器和返回的 IP 地址建立 TCP 連接,發(fā)送 HTTP 報文
如何自建 DNS 服務(wù)器
- ? 在自己的服務(wù)器上 (例如 10.0.0.1) 構(gòu)建一個 DNS 服務(wù) (可以理解為一個軟件,支持 DNS 協(xié)議,就像 Nginx 支持 HTTP 協(xié)議)
- ? 在域名系統(tǒng)管理后臺,新增一條 CNAME 記錄,將域名的解析轉(zhuǎn)交給 10.0.0.1
- ? 10.0.0.1 可以自定義返回各個域名對應(yīng)的 IP 地址,實現(xiàn)自定義 DNS 服務(wù)器
擴展閱讀
- ? 為什么 DNS 同時使用 TCP 和 UDP[6]
- ? what-is-dns[7]
引用鏈接
[1]? 《互聯(lián)網(wǎng)協(xié)議入門》: ??https://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html??
[2]? 例子 : ??http://www.cyberciti.biz/faq/unix-linux-update-root-hints-data-file/??
[3]? DNS: The Good Parts, by Pete Keen: ??https://www.petekeen.net/dns-the-good-parts??
[4]? DNS 101, by Mark McDonnell: http://www.integralist.co.uk/posts/dnsbasics.html
[5] DNS 原理入門: ??http://www.ruanyifeng.com/blog/2016/06/dns.html??
[6] 為什么 DNS 同時使用 TCP 和 UDP: https://scoolor.github.io/2018/11/10/dns-udp-tcp/
[7] what-is-dns: https://www.cloudflare.com/zh-cn/learning/dns/what-is-dns/