很多朋友可能會發現,在添加 CNAME、MX、NS 等記錄的時候,記錄值後面通常會自動補充一個”.”(如下圖),那為甚麼會自動添加這個”.”呢?
DNSPod控制台

為甚麼會自動添加”.”呢?

DNS 命名空間結構

要知到答案,那首先我們應該了解一下 DNS 的層次結構,域名空間實際上是一個樹狀結構(大概像下圖),在這個“樹”中任何一個節點完整的域名都是從root到該節點路徑上所有標籤的逆序組合,或從該節點到root路徑上所有標籤的順序組合,中間以”.”分隔。
域名空間
以本站首頁域名為例,從”r2wind”到根域名”root”,所以該節點完整的域名則為”r2wind.com.”(最後面的”.”代表 root,實際上是以”.”和一個空標籤結尾的),但為了方便通常寫成一個單獨的”.”這種寫法也被稱為完全限定域名 (FQDN) 。

只不過平時在訪問的時候,我們通常不會寫成”r2wind.com.”這種形式,而是直接寫成”r2wind.com”,但是在解析系統中這個點是不允許被省略的,不然可能會出現一些奇奇怪怪的問題,當然最重要的是要符合RFC的相關規範。

有關 RFC 的詳細訊息,可訪問互聯網工程工作組 (IETF) 的官網查看:IETF | Internet Engineering Task Force

遞歸 DNS 解析過程

估計到現在大家可能還可能有點懵,那我們再來看看遞歸 DNS 解析過程,來幫助大家的理解:
下面是一個完整的遞歸 DNS 解析過程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
rttw@Kincaid:~$ dig www.r2wind.com +trace

; <<>> DiG 9.19.4-1+0~20220818.83+debian11~1.gbp3f0f1b-Debian <<>> www.r2wind.com +trace
;; global options: +cmd
. 0 IN NS f.root-servers.net.
. 0 IN NS e.root-servers.net.
. 0 IN NS j.root-servers.net.
. 0 IN NS i.root-servers.net.
. 0 IN NS g.root-servers.net.
. 0 IN NS b.root-servers.net.
. 0 IN NS d.root-servers.net.
. 0 IN NS h.root-servers.net.
. 0 IN NS c.root-servers.net.
. 0 IN NS k.root-servers.net.
. 0 IN NS l.root-servers.net.
. 0 IN NS m.root-servers.net.
. 0 IN NS a.root-servers.net.
;; Received 432 bytes from 192.168.192.1#53(192.168.192.1) in 859 ms
# 遞歸返回根域名伺服器的 NS 記錄

cn. 172800 IN NS a.dns.cn.
cn. 172800 IN NS d.dns.cn.
cn. 172800 IN NS e.dns.cn.
cn. 172800 IN NS c.dns.cn.
cn. 172800 IN NS b.dns.cn.
cn. 172800 IN NS ns.cernet.net.
cn. 172800 IN NS g.dns.cn.
cn. 172800 IN NS f.dns.cn.
cn. 86400 IN DS 57724 8 2 5D0423633EB24A499BE78AA22D1C0C9BA36218FF49FD95A4CDF1A4AD 97C67044
cn. 86400 IN RRSIG DS 8 1 86400 20220920040000 20220907030000 20826 . Pir1xOUL//xWJtc9ey7zZJDmwSPnXHGGLTHpxxuOKwxchQkQvoSYGtCG L6YrRWEpFputpuFpK3DvPCbtPZQMje1Mr2H4vT7nZ47ht0Xr2brWSDlR maELk8iKsuNYwoJ3fL75yn1N0jEABxnYFfo9r4Pp0nfN0XVAIHvAiGE8 nhEFSmmmEZidrLfPT84+QKeXOc8fotDme/Byi5F3Uc3IRu8mq7BE/N/+ 4nXAVgXbWhO9/ULnlAK76bFqoz0qZmvrcrmSB08K//QVG4io+4nbpFyl dUlziRCAiT6h7L6WwK9XDBeWNhSMptvYJRVS01rC2X7OWqKvnU2fL/Bs FYzCSg==
;; Received 708 bytes from 202.12.27.33#53(m.root-servers.net) in 99 ms
# 根域名伺服器返回 cn 域名的 NS 記錄

;; UDP setup with 2001:dc7::1#53(2001:dc7::1) for www.r2wind.com failed: network unreachable.
;; UDP setup with 2001:dc7::1#53(2001:dc7::1) for www.r2wind.com failed: network unreachable.
;; UDP setup with 2001:dc7::1#53(2001:dc7::1) for www.r2wind.com failed: network unreachable.
r2wind.com. 86400 IN NS ns3.dnsv4.com.
r2wind.com. 86400 IN NS ns4.dnsv4.com.
3QDAQA092EE5BELP64A74EBNB8J53D7E.cn. 21600 IN NSEC3 1 1 10 AEF123AB 3QHKTF6LTFG8AAFUUAJSR8RVAJP99SFU NS SOA RRSIG DNSKEY NSEC3PARAM
3QDAQA092EE5BELP64A74EBNB8J53D7E.cn. 21600 IN RRSIG NSEC3 8 2 21600 20220929034902 20220830024902 38388 cn. nQpTOptIW40mn9r1uPSO/yIvyEcdfV/zhfXVU/nZptRs+gDk8MYnqO7c i3yXB2XYzZFXM3ofDWXIJHgHq42agy02zSkDKN3XabB0Y6F2Oy3FhFBP O5fNM97I5Nu1NEE2ZZ5XyGAfMZyNhjsOry66+56C4s/Dlu1LcE151vey ecY=
8TF4MEBDESE2OSVH717D9VC1F7BFN1VI.cn. 21600 IN NSEC3 1 1 10 AEF123AB 8TKMCNJ923RR3GI4UAK4FF8RHB788CNF CNAME RRSIG
8TF4MEBDESE2OSVH717D9VC1F7BFN1VI.cn. 21600 IN RRSIG NSEC3 8 2 21600 20220929034902 20220830024902 38388 cn. MgMG/eoy7e3ugs4TjsTxf5Ji9mvFsYYJpM+e4LayayDIMzs3JpkdKgEn ba3BmaaKclE6aDe8iL0uYSNiUMRgfMJb10yg066tDn+6bQH7BHl0paNY REZMB/+idFumyB3icj+JjCxrQe7j2fPp6aQUv3VBaEVLrp22XbnWZsbx scI=
;; Received 608 bytes from 202.112.0.44#53(ns.cernet.net) in 29 ms
# cn 域名伺服器返回 r2wind.com. 的 NS 記錄

www.r2wind.com. 600 IN A 120.78.190.225
r2wind.com. 86400 IN NS ns4.dnsv4.com.
r2wind.com. 86400 IN NS ns3.dnsv4.com.
;; Received 112 bytes from 1.12.0.25#53(ns3.dnsv4.com) in 39 ms
# r2wind.com 域名伺服器返回 www.r2wind.com. 的 A 記錄

由上面一大串的流程中可以看到查詢是從根開始進行查詢的,然後根據返回的各個域名 NS 記錄進行查詢,直到查詢到最終的 A 記錄。

可能你會好奇,為甚麼要有根?

根的主要作用是管理互聯網的主目錄。可以設想一下,如果沒有根,以查詢 tencent.com 為例,在查詢解析的時候你得先找到 com 的 NS 記錄及其對應的 IP 地址,然後才能獲取到 tencent.com 的 NS記錄 繼續進行遞歸查詢。

不知道這裏會不會有人說那我挨個獲取就好了,何必需要根呢?
不得不說這是個好問題,但理想很豐滿,現實很骨感,目前全球共有1591個 TLD ,你可以試想一下,你獲取這些 TLD 的 NS 記錄需要多長時間,而且這些 TLD 的 NS 記錄是不斷變化的,如果你要想自己維護的話,頭大不說,還可能會有很多隱患。交給根他不香嘛?

域名分級

提到這裏,那我們再說說域名分級,我們平時能註冊到的域名到底是幾級域名呢?

答案是二級。

那域名究竟是如何分級的?
回到上面的樹狀圖,我們可以看到,root 下面有若干個頂級域名,例如:cn、com、org、edu等等,這些被稱為頂級域名或者一級域名;這些頂級域名下面又分為若干個二級域名,以 cn 為例,下面有若干個二級域名,例如:dnspod、r2wind,而二級域名下面可能又會分為若干個三級域名,以 dnspod 為例,下面又分為了若干個三級域名,例如:www、docs、console 等等,以此類推,這就是域名的分級。

總結一下域名分級規則:

  • 頂級域名(TLD):頂級域是root的子域,例如:com;
  • 一級域名(FLD):一級域也是root的子域(一級域和頂級域是同一個概念);
  • 二級域名(SLD):二級域是一級域的子域,例如:tencent.com是 com 的子域;
  • 依此類推…..

加”.”會影響解析嘛?

仔細看看上面的解析過程,除了一開始輸入命令的時候後面沒有”.”,剩下其他域名哪個後面沒有”.”呢?
在 DNS 中,加”.”不會影響解析,但是不加”.”可能就是另一個故事(事故)啦。所以當你設置相關的紀錄不能解析的時候,別再怪後面自動加了”.”,找找其他的原因吧。

下面是一個有趣的例子,我查詢的是 me,卻返回了 me.r2wind.com的 A 記錄:

1
2
3
4
5
6
7
root@Kincaid:~# nslookup me 8.8.8.8
Server: 8.8.8.8
Address: 8.8.8.8#53

Non-authoritative answer:
Name: me.r2wind.com
Address: 106.52.72.124

這是因為我設置了主機的本地域名,所以系統會自動在後面添加上 r2wind.com,但當我在查詢 me 加了”.”後,可以看到報錯了,如下:

1
2
3
4
5
6
7
root@Kincaid:~# nslookup me. 8.8.8.8
;; communications error to 8.8.8.8#53: timed out
Server: 8.8.8.8
Address: 8.8.8.8#53

Non-authoritative answer:
*** Can't find me: No answer

報錯的原因也很簡單,加”.”系統會認為你查詢的是一個完整的域名,這種情況下系統不會在後面添加本地域名,而是直接進行遞歸查詢,但 me 這個域是沒有解析 A/AAAA 記錄的,所以就會報錯。

這裏不知道會不會有人說頂級域哪有解析 A/AAAA 記錄的,感興趣的話你可以去訪問一下 http://ai./ 這個頂級域。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
root@Kincaid:~# dig ai. @8.8.8.8

; <<>> DiG 9.19.4-1+0~20220818.83+debian11~1.gbp3f0f1b-Debian <<>> ai. @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15833
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;ai. IN A

;; ANSWER SECTION:
ai. 21600 IN A 209.59.119.34

;; Query time: 319 msec
;; SERVER: 8.8.8.8#53(8.8.8.8) (UDP)
;; WHEN: Thu Sep 08 08:29:01 CST 2022
;; MSG SIZE rcvd: 47

是不是有人想問域名 ai 的後綴是甚麼?是根 (root) 。

總結

好像說了好多廢話哈哈哈,總結一下吧:

  • 不要覺得加”.”很奇怪,如果你覺得奇怪,建議抽空了解一下 DNS 相關的知識吧。
  • 加”.”不會影響解析!加”.”不會影響解析!加”.”不會影響解析!——重要的事情說三遍
  • 由於博主的水平有限,文章中可能會有一些錯誤,歡迎各位大佬批評指正。

參考

其他

附上一些區域文件:
https://www.internic.net/domain/db.cache
https://www.internic.net/domain/root.zone
https://www.internic.net/domain/arpa.zone
https://www.internic.net/domain/ip6.arpa.zone