關於DNS,你應該知道這些

在互聯網時代中,如果要問哪個應用層協議最重要的話,我想答案無疑是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.(注意最後的點),

根域名

根域名通過根服務器進行解析, 根服務器對於每個請求告知頂級域名服務器的地址. 目前全世界一共有十三臺根服務器,
由於不同國家或機構管理維護,分別坐落在如下的地方:

root-servers

可以看到其中沒有一臺是在中國境內的,不知道這是好事還是壞事呢? 呵呵.

頂級域名

頂級域名, 英文名爲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協議是我們日常直接或者間接所接觸到的最多的協議, 花上幾個小時瞭解一下它的
工作機制,我想應該也是挺有趣的吧.

參考文章

博客地址:

歡迎交流,文章轉載請註明出處.

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