在網際網路時代中,如果要問哪個應用層協議最重要的話,我想答案無疑是DNS.雖然我們每天都享受著DNS服務帶來的便利,
卻對它往往知之甚少.因此本文就來介紹一下DNS協議的工作流程,真正認識一下這個支撐著龐大網際網路絡的基礎服務.
前言
DNS協議,全稱為Domain Name System,即域名服務, 其功能描述起來很簡單,就是將域名(網址)轉換為IP地址.
可以想象為一個儲存了全世界域名到IP的對映的伺服器, 通過DNS請求查詢獲得IP地址. 然而事實上域名的
數量繁多,如果全部存放在一臺伺服器之上顯然不合適. 因此對不同層級的域名往往需要在不同的域名伺服器上查詢,
直至找到最終的IP地址或者下一層級的域名伺服器,是一個多次查詢的過程.
域名的分級
我們日常上網所輸入的網址,格式例子為http://www.pppan.net
,其中www.pppan.net
就可以看作是域名.
實際上,域名是從右到左分級的,格式如下所示:
主機名.次級域名.頂級域名.根域名
即:
host.sld.tld.root
以www.pppan.net
為例,其完整的域名應該是‵www.pppan.net.root‵,由於全球的根域名都是root
,因此根域名
部分常常忽略,因此可以寫成www.pppan.net.
(注意最後的點),
根域名
根域名通過根伺服器進行解析, 根伺服器對於每個請求告知頂級域名伺服器的地址. 目前全世界一共有十三臺根伺服器,
由於不同國家或機構管理維護,分別坐落在如下的地方:
可以看到其中沒有一臺是在中國境內的,不知道這是好事還是壞事呢? 呵呵.
頂級域名
頂級域名, 英文名為TLD(Top-Level Domains). 根據用途不同被分為兩部分. 一部分稱為通用頂級域名gTLD(generic TLD)
,
如.com, .net, .org, .biz, .info
等都是常見的通用頂級域名; 另一部分稱為國別頂級域名ccTLD(country side TLD)
,
ccTLD對應的國家擁有對應域名進行任何限制的權力,有的國家只允許本國公民註冊ccTLD域名,不過其他國家的機構可以通過"租"
的方式來獲得對應國家的ccTLD域名, 常見的ccTLD型別域名有.cn, .us, .ru
等,還有些國家國別頂級域名因為有特殊的含義
而被批量租用的,如.tv, .ws, .tk
等.
次級域名
次級域名, 英文名為SLD(Sub-Level Domains), 通常又被稱為二級域名. 這一級別的域名是使用者可以向域名代理商進行註冊的,
我們通常說的購買域名,就是買的次級域名.
主機名
主機名(hostname), 為使用者在自己的域中為伺服器所分配的不同的名稱. 常見的www就是一個主機名.
域名查詢
當我們知道一個用名稱表示的資源時,為了訪問這個資源,我們就需要知道其地址, 這個地址通常也稱為記錄(records).
這個根據資源名稱(域名)來查詢地址的過程, 就稱為DNS, DNS查詢通常會經過下面四步:
- 詢問Resolver
- 詢問根伺服器
- 詢問頂級域名伺服器
- 詢問次級域名伺服器
Resolver
resolver
就是我們常說的DNS伺服器, 其作用是為我們提供域名伺服器的地址. resolver的地址一般在我們接入網路的時候,
通過DHCP獲得, 也可以手動指定resolver地址. 在Linux系統中可以檢視/etc/resolv.conf
檔案檢視resolver地址,
Windows則可以通過控制皮膚檢視.
resolver通常有個root-hints
檔案, 其中硬編碼了十三個根域名伺服器的地址. 當我們向resolver發起DNS請求時,
resolver會同時向所有根域名伺服器發出查詢請求,並以最快返回的響應為結果執行下一步的操作. 實際上,
resolver會根據響應速度獲得一個優先查詢的根伺服器,並將隨後的查詢都只向此根伺服器進行請求. 當然,
優先伺服器也有自己的更新機制,不過這是題外話了.
resolver獲得根伺服器的地址之後,通常還需要進行下一步的查詢. 如果我們要查詢的域名為www.example.com
,
則還需要向根伺服器查詢com的頂級域名伺服器,然後再查詢次級域名伺服器和主機名等.
詢問根伺服器
上面也說了,全球一共是三個根域名伺服器,其中每一個都知道可以處理此次DNS請求的次級域名伺服器的地址,
或者至少知道可以處理請求的下級的域名伺服器地址.
一般來說,根伺服器處理DNS請求,並且告訴resolver下一步應該去詢問哪個頂級伺服器. 不過如果根伺服器識別出了
次級伺服器的地址,就會把這個地址返回給resolver的.
詢問頂級域名伺服器
如果上一步根伺服器沒有識別出次級域名伺服器的地址,那麼就會給resolver返回頂級伺服器的地址,從而resolver
需要再次向頂級域名伺服器發起查詢.
頂級域名伺服器收到查詢請求後,會將可以真正解析此請求的次級域名伺服器地址返回給resolver.
詢問次級域名伺服器
上一步resolver請求頂級域名伺服器後,會收到返回,內容是下一步要查詢的域名伺服器的地址,
也就是次級域名伺服器的地址. 於是resolver向次級域名伺服器發起DNS查詢請求, 次級域名
伺服器接收到請求後即返回對應次級域名的IP地址.
值得一提的是,次級域名還有如下的別名:
- 使用者DNS名稱伺服器(User DNS name server)
- 權威名稱伺服器(Authoritative name server)
其中後者更廣為人知一些,因為SLD是查詢到對應域名IP地址的最後一步(如果有的話), 而且這個域名伺服器也負責
對應資源的DNS設定,如新增不同主機地址的記錄等.
resolver從次級域名伺服器獲得了域名的IP地址,並將其返回給使用者,只此便完成了一次DNS查詢.
域名查詢例項
紙上得來終覺淺,絕知此事要躬行. 上面介紹了域名查詢的一般流程之後, 我們就可以通過一次真實的DNS查詢來
驗證上述的過程. 在Linux環境下,有預設的dig
命令可以進行DNS的查詢和除錯, 這裡以域名test.pppan.net
為例.
輸入命令dig +trace test.pppan.net
可以看到詳細的查詢過程.
Step 1
首先, 向使用者的DNS伺服器(resolver,這裡是10.0.20.166)查詢根域名伺服器的地址(std query A a-m.root-servers.net),
其中A表示查詢ipv4地址記錄,AAAA表示查詢ipv6地址, 在下一節詳細介紹. 返回結果如下:
. 318381 IN NS j.root-servers.net.
. 318381 IN NS k.root-servers.net.
. 318381 IN NS l.root-servers.net.
. 318381 IN NS m.root-servers.net.
. 318381 IN NS a.root-servers.net.
. 318381 IN NS b.root-servers.net.
. 318381 IN NS c.root-servers.net.
. 318381 IN NS d.root-servers.net.
. 318381 IN NS e.root-servers.net.
. 318381 IN NS f.root-servers.net.
. 318381 IN NS g.root-servers.net.
. 318381 IN NS h.root-servers.net.
. 318381 IN NS i.root-servers.net.
;; Received 811 bytes from 10.0.20.166#53(10.0.20.166) in 247 ms
可以看到,一共有13個根域名伺服器,地址分別是a-m.root-servers.net.
, 其中響應最快的根域名伺服器是
j.root-servers.net.
Step 2
然後, 向j-root-servers.net(192.58.128.30)發起查詢請求(standard query A test.pppan.net),
得到的返回如下:
net. 172800 IN NS a.gtld-servers.net.
net. 172800 IN NS b.gtld-servers.net.
net. 172800 IN NS c.gtld-servers.net.
net. 172800 IN NS d.gtld-servers.net.
net. 172800 IN NS e.gtld-servers.net.
net. 172800 IN NS f.gtld-servers.net.
net. 172800 IN NS g.gtld-servers.net.
net. 172800 IN NS h.gtld-servers.net.
net. 172800 IN NS i.gtld-servers.net.
net. 172800 IN NS j.gtld-servers.net.
net. 172800 IN NS k.gtld-servers.net.
net. 172800 IN NS l.gtld-servers.net.
net. 172800 IN NS m.gtld-servers.net.
net. 86400 IN DS 35886 8 2 7862B27F5F516EBE19680444D4CE5E762981931842C465F00236401D 8BD973EE
net. 86400 IN RRSIG DS 8 1 86400 20170121050000 20170108040000 61045 . Y6+Td6BUfPw5RgC2aWX/pvC6OgEl8rVd3SCPtg+/qdwHxRa4TM8ppZWU +nTSRNTwgXX1VWxJ8D7MNu4q8gLZZWxO1U+3Viw8WNSRdIou+s2fVwon IQVF9y0GGpLaKt8mwlOaeHO3O1HiGGpR50GTlNhxyx6eGYHu5581ugFm NTjogYmrcTy5Es70WH6NhQ1z7+rO8rcuo5ES7fJoZWr4Bekd7YntSxXx +WCwOcpf3muLGPC9yshNprA/c9Fam3WDpJLYPjmCp2l96GyrJcv4o9z9 gov5IV69HWQnCD9IGRIj/XG/JZerp6YIRGH8cnrVe3F87Hy95SkNWnYR lC5fIg==
;; Received 863 bytes from 192.58.128.30#53(j.root-servers.net) in 524 ms
並沒有返回IP,而是返回了可以解析該域名的頂級域名地址, 由於是.net因此屬於gTLD,
可以看到返回了多個頂級域名伺服器(a-m.gtld-servers.net.)的地址.
Step 3
接著, 我們應該向返回的地址再次發起查詢(standard query A test.pppan.net),
這次返回了次級域名伺服器的地址,如下:
pppan.net. 172800 IN NS ns01.freenom.com.
pppan.net. 172800 IN NS ns02.freenom.com.
pppan.net. 172800 IN NS ns03.freenom.com.
pppan.net. 172800 IN NS ns04.freenom.com.
A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - A1RUUFFJKCT2Q54P78F8EJGJ8JBK7I8B NS SOA RRSIG DNSKEY NSEC3PARAM
A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20170113060849 20170106045849 43880 net. WTfL5/hHBUsV2D5vusIP5KNSoiyfG4sG0GZQuBUqppWEY/WgZJ2wnnpk jjjfN5BlIExTuDyHclY2bXbiIqebcd1aVGp1ELUI7E5t3z7iCZmajPsT TLuLohKJmLC7b/OVdxoAuFoaIqj+GDsp2yDkXsem1IrfSOCbQlvJE9Ya xbQ=
OKR8BNVHVTI8CTK5KIDNJN546MJM5M16.net. 86400 IN NSEC3 1 1 0 - OKSF929IG7A7E1KLTJD5CF495DR06C54 NS DS RRSIG
OKR8BNVHVTI8CTK5KIDNJN546MJM5M16.net. 86400 IN RRSIG NSEC3 8 2 86400 20170113060546 20170106045546 43880 net. BGw3/vY9GzViJNHllwJkC1WB5XBtV9jzjy3LSA9I0zovOpVFHivHE01S r3YUtqAUuJ0LOJ4wrxBPwDRB0wTgbQdIO7dol2nQWuYujbxEbJ6AOWtR 7MTRhiG8BDn9LP06UWpUcWlsyywivKR70xCnamq3ZKeeI48dluRkVy9f lig=
;; Received 679 bytes from 192.33.14.30#53(b.gtld-servers.net) in 1813 ms
這一步返回可以看到, pppan.net所屬的次級域名伺服器是ns01-ns04.freenom.com, 因為我配置的就是這個地址.
但實際上可以自己在公網搭建這樣一個次級域名伺服器,只要可以解析出對應的hostname即可.
Step 4
最後,向ns01.freenom.com發起查詢,便可以從響應中看到,已經找到了test.pppan.net的一條地址記錄:
test.pppan.net. 14440 IN A 233.233.233.233
;; Received 59 bytes from 54.171.131.39#53(ns01.freenom.com) in 464 ms
因此便能得到本次DNS查詢的結果, 即test.pppan.net的ip地址為233.233.233.233.
注: 對於使用者而言,其實只進行一次DNS查詢,即向resolver的查詢,中間的過程由resolver進行按級查詢,
並將最後查詢到的結果返回給使用者(如果有的話). 上面的查詢由dig命令發起,因此和實際的查詢過程還是有點小差別的.
記錄型別
從上面的示例中我們可以看到, 我們查詢的記錄型別為A
或者AAAA
, 返回的結果型別有NS
,DS
或者A
等.
這些記錄的型別在DNS協議中都有詳細介紹,這裡只解釋幾個常見的型別:
A
A記錄(Address Mapping records), 指示了對應名稱的IPv4地址, A記錄用來將域名轉換為ip地址.
AAAA
AAAA記錄類似於A記錄, 只不過指示的是IPv6的地址.
NS
NS記錄(Name Server records), 用來指定對應名稱的可信名稱伺服器(authoritative name server).
PTR
PTR記錄(Reverse-lookup Pointer records), 和正向DNS解析(A/AAAA記錄)相反, 主要用來根據IP地址查詢對應的域名.
CNAME
CNAME記錄即Canonical Name records, 用來指定一個新的域名用以完成本次查詢.
當resolver查詢過程中遇到一個CNAME記錄時, 則會重新開始本次查詢, 但是查詢的域名會改為CNAME指定的域名.
舉例來說,假如某次級域名伺服器上有如下記錄:
NAME TYPE VALUE
--------------------------------------------------
bar.example.com. CNAME foo.example.com.
foo.example.com. A 192.0.2.23
則查詢bar.example.com的時候, 會在resolver端轉而查詢foo.example.com,從而得到查詢的地址為192.0.2.23,
可以看到其實CNAME就是一個別名, 但是增加了查詢的步驟. 不過這在當我們想要把自己的某個域名當作某個外部
域名的別稱時還是很有用的. CNAME也有使用限制, 比如記錄值不可以是IP, 以及不可同時有其他同名的A記錄等,
具體可以參考這裡.
MX
MX記錄(Mail Exchanger records)為某個DNS域名指定了郵件交換的伺服器. 這個記錄資訊由SMTP協議使用來將
郵件傳送到正確的主機上. 通常對於一個域名有多個郵件交換伺服器,並且他們之間都有對應的優先順序.
TXT
TXT記錄(text records)可以包含任意非格式化的文字資訊, 通常這項記錄被SPF框架(Sender Policy Framework)
用來防止傳送給你的虛假郵件.
當然還有許多其他的記錄型別, 不過相對而言沒有那麼常見. 需要了解的可以再深入查閱DNS協議的白皮書即可.
後記
經過上面對於DNS服務的解釋, 我們應該就能解決大部分日常遇到的DNS問題. 比如為什麼電腦能上QQ卻打不開網頁啦,
為什麼我的網站突然解析不出來啦; 或者有獨立域名的還能實現一些好玩的功能, 比如建立惡作劇的查詢記錄,或者
搭建個人郵件伺服器等. 畢竟DNS協議是我們日常直接或者間接所接觸到的最多的協議, 花上幾個小時瞭解一下它的
工作機制,我想應該也是挺有趣的吧.
參考文章
部落格地址:
歡迎交流,文章轉載請註明出處.