作者:LeanCloud 豐俊文

互聯網中的地址是數字的 IP 地址,例如 61.135.169.125 就是百度的官網地址之一,如果每次訪問百度都需要輸入 IP 的話,估計到今天互聯網都還沒有走出鴻蒙階段。

在網路發展歷史上,最開始確實就是直接使用 IP 地址來訪問遠程主機的。早期聯網的每台計算機都是採用主機文件(即我們俗稱的 hosts 文件)來進行地址配置和解析的,後來聯網機器越來越多,主機文件的更新和同步就成了很大的問題。於是,1983 年保羅·莫卡派喬斯發明了域名解析服務和域名系統,在 1985 年 1 月 1 日,世界上第一個域名 nordu.net 才被註冊成功。

域名比 IP 地址更容易記憶,本質上只是為數字化的互聯網資源提供了易於記憶的別名,就像在北京提起「故宮博物院

」就都知道指的是「東城區景山前街 4 號」的那個大院子一樣。如果把 IP 地址看成電話號碼,那域名系統就是通訊錄。我們在通訊錄里保存了朋友和家人的信息,每次通過名字找到某人打電話的時候,通訊錄就會查出與之關聯的電話號碼,然後撥號過去。我們可能記不下多少完整的電話號碼,但是聯繫人的名字卻是一定記得的。

既然「域名」只是一個別名,單憑這一個名字我們並不能訪問到正確的地址,只有能將域名解析成實際的網路地址,網路訪問才能成功。這種解析工作由專門的「域名系統」(Domain Name System,簡稱 DNS)完成,DNS 也是互聯網的核心基礎服務之一。

域名解析是怎麼完成的

DNS 解析的過程是什麼樣子的呢?在開始這個問題之前,我們先看一看域名的層次結構。

域名的層級結構

在討論域名的時候,我們經常聽到有人說「頂級域名」、「一級域名」、「二級域名」等概念,域名級別究竟是怎麼劃分的呢?

  • 根域名。還是以百度為例,通過一些域名解析工具,我們可以看到百度官網域名顯示為 www.baidu.com.,細心的人會注意到,這裡最後有一個 .,這不是 bug,而是所有域名的尾部都有一個根域名。www.baidu.com 真正的域名是 www.baidu.com.root,簡寫為www.baidu.com.,又因為根域名 .root 對於所有域名都是一樣的,所以平時是省略的,最終就變成了我們常見的樣子。
  • 根域名的下一級叫做頂級域名(top-level domain,縮寫為 TLD),也叫做一級域名,常見的如 .com / .net / .org / .cn 等等,他們就是頂級域名。
  • 再下一級叫做二級域名(second-level domain,縮寫為 SLD),比如 baidu.com。這是我們能夠購買和註冊的最高級域名。
  • 次級域名之下,就是主機名(host),也可以稱為三級域名,比如 baidu.com,由此往下,基本上 N 級域名就是在 N-1 級域名前追加一級。

總結一下,常見的域名層級結構如下:

主機名.次級域名.頂級域名.根域名
# ie
www.baidu.com.root

一般來說我們購買一個域名就是購買一個二級域名(SLD)的管理權(如 leancloud.cn),有了這個管理權我們就可以隨意設置三級、四級域名了。

域名解析的過程

與域名的分級結構對應,DNS 系統也是一個樹狀結構,不同級別的域名由不同的域名伺服器來解析,整個過程是一個「層級式」的。

層級式域名解析體系的第一層就是根域名伺服器,全世界 IPv4 根域名伺服器只有 13 台(名字分別為 A 至 M),1 個為主根伺服器在美國,其餘 12 個均為輔根伺服器,它們負責管理世界各國的域名信息。在根伺服器下面是頂級域名伺服器,即相關國家域名管理機構的資料庫,如中國互聯網路信息中心(CNNIC)。然後是再下一級的權威域名伺服器和 ISP 的緩存伺服器。

一個域名必須首先經過根資料庫的解析後,才能轉到頂級域名伺服器進行解析,這一點與生活中問路的情形有幾分相似。

假設北京市設立了一個專門的「道路諮詢局」,裡面設置了局長、部長、處長、科員好幾個級別的公務員,不同的部門、科室、人員負責解答不同區域的道路問題。這裡的人都有一個共同特點,信奉「好記性不如爛筆頭」的哲理,喜歡將自己了解到的信息記錄到筆記本上。但是有一點遺憾的是,他們寫字用的墨水只有一種,叫「魔術墨水」,初寫字跡濃厚,之後會慢慢變淡,1 小時之後則會完全消失。道路諮詢局門口還有一個門衛大爺,所有的人要問路都需要通過他來傳達和回復,市民並不能進入辦公樓。

如果市民 A 先生來找門衛大爺詢問「北海公園」的地址,門衛大爺會先看一下自己的筆記本,找找看之前有沒有人問過北海公園,如果沒有,他就會撥打內線去找局長求助。局長說北海是西城區,你去問負責西城區道路信息的趙部長吧。門衛大爺又去問趙部長,趙部長查了一下,說這個地址你去問負責核心區的錢處長吧。門衛大爺又給錢處長打過去電話,錢處長說這個地址我也不掌握啊,你去問一下負責景山片區的科員小孫吧。門衛大爺從小孫那裡終於知道了北海公園地址,他趕緊記到自己的小本本上,然後把結果告訴了市民 A 先生。接下來一小時內,如果還有市民 B 先生再來問北海公園的話,門衛大爺就直接用筆記本上記載的結果回復了。當然,如果市民 C 女士過來問別的地址的話,門衛大爺就要把處理 A 先生問詢的流程再走一遍了。

分級查詢的實例

現在我們來看一個實際的例子。如果我們在瀏覽器中輸入 https://news.qq.com,那瀏覽器會從接收到的 URL 中抽取出域名欄位(news.qq.com),然後將它傳給 DNS 客戶端(操作系統提供)來解析。

首先我們說明一下本機 DNS 配置(就是 /etc/resolv.conf 文件,裡面指定了本地 DNS 伺服器的地址,Windows 系統可能會有所不同):

$ cat /etc/resolv.conf
nameserver 202.106.0.20
nameserver 202.106.196.115

然後我們用 dig 這個工具查看一下 news.qq.com 的解析結果(其中中文部分是解釋說明):

$ dig news.qq.com

; <<>> DiG 9.10.6 <<>> news.qq.com
這是 dig 程序的版本號與要查詢的域名

;; global options: +cmd
;; Got answer:
以下是要獲取的內容。

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 47559
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
這個是返回應答的頭部信息:
1. opcode:操作碼,QUERY 代表查詢操作;
2. status: 狀態,NOERROR 代表沒有錯誤;
3. id:編號,在 DNS 協議中通過編號匹配返回和查詢;
4. flags: 標誌,含義如下:
- qr:query,查詢標誌,代表是查詢操作
- rd:recursion desired,代表希望進行遞歸查詢操作;
- ra:recursive available,代表查詢的伺服器支持遞歸查詢操作;
5. QUERY 查詢數,與下面 QUESTION SECTION 的記錄數一一對應;
6. ANSWER 結果數,與下面的 ANSWER SECTION 的記錄數一一對應;
7. AUTHORITY 權威回複數,如果查詢結果由管理域名的域名伺服器而不是緩存伺服器提供的,則稱為權威回復。
0 表示所有結果都不是權威回復;
8. ADDITIONAL 額外記錄數;

;; QUESTION SECTION:
;news.qq.com. IN A
查詢部分,從左到右部分意義如下:
1、要查詢的域名;
2、要查詢信息的類別,IN 代表類別為 IP 協議,即 Internet。
3、查詢的記錄類型,A 記錄(Address)代表要查詢 IPv4 地址。

;; ANSWER SECTION:
news.qq.com. 136 IN CNAME https.qq.com.
https.qq.com. 476 IN A 125.39.52.26
回應部分,從左到右各部分意義:
1、對應的域名
2、TTL,time to live,緩存時間,單位秒,代表緩存域名伺服器可以在緩存中保存的期限。
3、查詢信息的類別
4、查詢的記錄類型,CNAME 表示別名記錄,A 記錄(Address)代表 IPv4 地址。
5、域名對應的 ip 地址。

;; Query time: 56 msec
;; SERVER: 202.106.0.20#53(202.106.0.20)
查詢使用的伺服器地址和埠,其實就是本地 DNS 域名伺服器
;; WHEN: Thu Jul 11 15:59:37 CST 2019
;; MSG SIZE rcvd: 65
查詢的時間與回應的大小,收到 65 位元組的應答數據。

從這個應答可以看到,我們得到的結果不是權威回復,只是本地 DNS 伺服器從緩存中給了應答。

接下來我們在 dig 命令中增加一個參數 +trace,看看完整的分級查詢過程:

$ dig +trace news.qq.com

; <<>> DiG 9.10.6 <<>> +trace news.qq.com
;; global options: +cmd
. 432944 IN NS g.root-servers.net.
. 432944 IN NS k.root-servers.net.
. 432944 IN NS b.root-servers.net.
. 432944 IN NS h.root-servers.net.
. 432944 IN NS i.root-servers.net.
. 432944 IN NS f.root-servers.net.
. 432944 IN NS d.root-servers.net.
. 432944 IN NS e.root-servers.net.
. 432944 IN NS j.root-servers.net.
. 432944 IN NS l.root-servers.net.
. 432944 IN NS c.root-servers.net.
. 432944 IN NS m.root-servers.net.
. 432944 IN NS a.root-servers.net.
;; Received 228 bytes from 202.106.0.20#53(202.106.0.20) in 45 ms
這些就是神秘的根域名伺服器,由本地 DNS 伺服器返回了所有根域名伺服器地址。

com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
;; Received 1171 bytes from 192.36.148.17#53(i.root-servers.net) in 57 ms
這裡顯示的是 .com 域名的 13 條 NS 記錄,本地 DNS 伺服器向這些頂級域名伺服器發出查詢請求,
詢問 qq.com 的 NS 記錄。

qq.com. 172800 IN NS ns1.qq.com.
qq.com. 172800 IN NS ns2.qq.com.
qq.com. 172800 IN NS ns3.qq.com.
qq.com. 172800 IN NS ns4.qq.com.
;; Received 805 bytes from 192.48.79.30#53(j.gtld-servers.net) in 331 ms
這裡顯示的是 qq.com 的 4 條 NS 記錄,由 j.gtld-servers.net 這台伺服器最先返回。
然後本地 DNS 伺服器向這四台伺服器查詢下一級域名 news.qq.com 的 NS 記錄。

news.qq.com. 86400 IN NS ns-cnc1.qq.com.
news.qq.com. 86400 IN NS ns-cnc2.qq.com.
;; Received 180 bytes from 58.144.154.100#53(ns4.qq.com) in 37 ms
這裡顯示的是 news.qq.com 的 NS 記錄,它們是由上面的 ns4.qq.com 域名伺服器返回的。
然後本地 DNS 伺服器向這兩台機器查詢 news.qq.com 的主機名。

news.qq.com. 600 IN CNAME https.qq.com.
https.qq.com. 600 IN A 125.39.52.26
;; Received 76 bytes from 223.167.83.104#53(ns-cnc2.qq.com) in 29 ms
這是上面的 ns-cnc2.qq.com 返回的最終查詢結果:
news.qq.com 是 https.qq.com 的別名,而 https.qq.com 的 A 記錄地址是 125.39.52.26

實際的流程裡面,本地 DNS 伺服器相當於門衛大爺,根域名伺服器相當於局長同志,其餘以此類推。客戶端與本地 DNS 伺服器之間的查詢叫遞歸查詢,本地 DNS 伺服器與其他域名伺服器之間的查詢就叫迭代查詢。

域名記錄的類型

域名伺服器之所以能知道域名與 IP 地址的映射信息,是因為我們在域名服務商那裡提交了域名記錄。購買了一個域名之後,我們需要在域名服務商那裡設置域名解析的記錄,域名服務商把這些記錄推送到權威域名伺服器,這樣我們的域名才能正式生效。

在設置域名記錄的時候,會遇到「A 記錄」、「CNAME」 等不同類型,這正是前面做域名解析的時候我們碰到的結果。這些類型是什麼意思,它們之間有什麼區別呢?接下來我們看看常見的記錄類型。

  • A 記錄。A (Address) 記錄用來直接指定主機名(或域名)對應的 IP 地址。主機名就是域名前綴,常見有如下幾種:

www:解析後的域名為 www.yourdomain.com,一般用於網站地址。

@:直接解析主域名。

*:泛解析,指將 .yourdomain.com 解析到同一 IP。

  • CNAME 記錄。CNAME 的全稱是 Canonical Name,通常稱別名記錄。如果需要將域名指向另一個域名,再由另一個域名提供 IP 地址,就需要添加 CNAME 記錄。
  • MX 記錄。郵件交換記錄,用於將以該域名為結尾的電子郵件指向對應的郵件伺服器以進行處理。
  • NS 記錄。域名伺服器記錄,如果需要把子域名交給其他 DNS 伺服器解析,就需要添加 NS 記錄。
  • AAAA 記錄。用來指定主機名(或域名)對應的 IPv6 地址,不常用。
  • TXT 記錄。可以填寫任何東西,長度限制 255。絕大多數的 TXT 記錄是用來做 SPF 記錄(反垃圾郵件),MX 記錄的作用是給寄信者指明某個域名的郵件伺服器有哪些。SPF 的作用跟 MX 相反,它向收信者表明,哪些郵件伺服器是經過某個域名認可會發送郵件的。
  • 顯性 URL。從一個地址 301 重定向(也叫「永久性轉移」)到另一個地址的時候,就需要添加顯性 URL 記錄。

  • 隱性 URL。從一個地址 302 跳轉(也叫「臨時跳轉」)到另一個地址,需要添加隱性 URL 記錄。它類似於顯性 URL,區別在於隱性 URL 不會改變地址欄中的域名。

在填寫各種記錄的時候,我們還會碰到一個特殊的設置項——TTL,生存時間(Time To Live)。

TTL 表示解析記錄在 DNS 伺服器中的緩存時間,時間長度單位是秒,一般為3600秒。比如:在訪問 news.qq.com時,如果在 DNS 伺服器的緩存中沒有該記錄,就會向某個 NS 伺服器發出請求,獲得該記錄後,該記錄會在 DNS 伺服器上保存 TTL 的時間長度,在 TTL 有效期內訪問 news.qq.com,DNS 伺服器會直接緩存中返回剛才的記錄。

DNS 智能解析

DNS 主要的工作就是完成域名到 IP 的映射,但是也不是簡單到查查字典就可以搞定的程度。在設置 DNS 解析的時候,我們還有一些額外的需求,例如:

  • 將一個域名解析到多個 IP

例如我們一個網站有多台前端機,希望用戶訪問的時候,可以隨機分散到這些機器上,以增加網站承載能力。有一種解決的辦法就是對同一個域名設置多條 A 記錄,分別指定到不同的 IP 上。

  • 根據特徵差異將不同請求解析到不同 IP(智能解析)

國內互聯網的架構其實遠比我們想像的複雜,基本上還是根據運營商的不同切割成多個平行網路,只有在固定的幾個節點這些平行網路才會有交叉。例如電信和聯通之間的互聯是通過「國家級互聯網骨幹直聯點」接入的,目前我們一共建設了三批國家級互聯網骨幹直聯點:

1.第一批 2001 年投入使用:北京,上海,廣州

2.第二批 2014 年投入使用:成都,鄭州,武漢,西安,瀋陽,南京,重慶

3.第三批 2017 年投入使用:杭州,貴陽/貴安,福州

教育網目前還只能通過北上廣三個點進行連接。這樣的網路拓撲結構,給 DNS 解析帶來了新的挑戰。

傳統 DNS 解析,不判斷訪問者來源,會隨機選擇其中一個 IP 地址返回給訪問者。如果讓電信用戶使用了聯通 IP 來訪問網站,那結果自然不如使用電信 IP 訪問來的快捷。而智能 DNS 解析,會判斷訪問者的來源特徵,為不同的訪問者返回不同的 IP 地址,能夠減少解析時延,並提升網路訪問速度。例如,國內某著名 DNS 服務商不光可以區分網路運營商,還可以根據訪問者的地理位置來設置不同的解析線路,而且甚至還可以為搜索引擎設置特定的解析地址。

  • CNAME 和 A 記錄區別

按照前面的解釋,A 記錄就是把一個域名解析到一個 IP 地址,而 CNAME 記錄就是把一個域名解析到另外一個域名,其功能差不多。但是 CNAME 相當於將域名和 IP 地址之間加了一個中間層,可以帶來很大的靈活性,特別是當你要使用但是並不擁有那些域名的時候。

例如我們使用 CDN 服務,服務商提供給我們的是一個 CNAME 地址,我們可以把自己的域名綁定到這一個地址上,這樣萬一以後服務商的 IP 地址更換了,我們自己的域名解析是不需要做任何變更的,只要服務商調整一下 CNAME 地址的解析結果,所有使用者都可以無感知的切換。

從 6 月底開始,LeanCloud 新推出了 綁定自定義域名 的功能,全面支持開發者設置自己的 API、文件、雲引擎域名,也正是依賴於 CNAME 記錄的這一特點來實現的。

DNS 污染與安全挑戰

DNS 是最早商用的大型分散式系統,雖然現在看起來已經很完備了,但是實際使用的時候,特別是國內複雜的網路環境,我們還是會遇到很多問題。

作為互聯網早期產物,DNS 使用無連接的 UDP 協議雖然降低了開銷也保證了高效的通信,但是沒有太考慮安全問題。由於它使用目的埠為 53 的 UDP 明文進行通信,DNS 解析器識別是自己發出的數據包的唯一標準就是隨機的源埠號,如果埠號匹配則認為是正確回復,而不會驗證來源。所以也帶來了諸如 DNS 欺騙、DNS Cache 污染、DNS 放大攻擊等問題,同時給一些區域運營商帶來了「商機」。

為此業界提出了 DNSSec(Domain Name System Security Extensions,也叫「DNS安全擴展」)機制,使用密碼學方法,讓客戶端對域名來源身份進行驗證,並且檢查來自 DNS 域名伺服器應答記錄的完整性,以及驗證是否在傳輸過程中被篡改過,等等一系列措施來保證數據通信的安全性。對這方面感興趣的讀者,可以關注我們的後續文章。

Photo byPascal MeieronUnsplash


推薦閱讀:
相关文章