一. 什么是DNS?

DNS (Domain Name System) 指的是域名系统,总的来说它负责将域名映射成IP地址。

因为IP地址是一串数字,我们希望更方便记忆,因此通过某个特定名称代替这串IP,这就需要DNS服务器去映射。

我们 ping baidu.com

1
2
3
(base) ➜  ~ ping baidu.com
PING baidu.com (39.156.66.10): 56 data bytes
64 bytes from 39.156.66.10: icmp_seq=0 ttl=49 time=52.265 ms

可以看到,baidu.com 这个域名解析对应的IP为:39.156.66.10,我们平时访问百度就会访问这个IP地址(由于现在互联网服务大部分是分布式的,所以解析结果可能不止1个IP,复杂情况在此暂时不讨论)。

二. DNS解析流程

现在开始我们的DNS解析奇妙之旅!下面以访问 gtiit.edu.cn 为例。

2.1 访问游览器DNS缓存

查找当前使用的游览器的DNS缓存中是否有 gtiit.edu.cn 的记录,如果没有则跳转到 2.2 步骤。

Tips:如果使用的是Chrome游览器,可以访问 chrome://net-internals/#dns 清除DNS缓存。如果需要查看,要先访问 chrome://net-export/ 开始记录日志,停止记录后将文件上传到 https://netlog-viewer.appspot.com/ 进行解析,选择DNS选项,如下图所示。

Chrome中的DNS缓存

TTL (Time To Live) 指的是生存时间,这里单位是毫秒,即该缓存在 Expires 指定的时间会失效,需要重新获取。

2.2 访问操作系统DNS缓存

查找当前操作系统DNS缓存中是否有 gtiit.edu.cn 的记录,如果没有则跳转到 2.3 步骤。

Windows上查看系统DNS缓存:ipconfig /displaydns

Windows系统上清除DNS缓存:ipconfig /flushdns

Mac系统上清除DNS缓存:sudo killall -HUP mDNSResponder

2.3 访问操作系统本机hosts文件

在本地计算机上存在一个hosts文件,它是一个域名到IP的映射文件。如果在hosts文件中找不到 gtiit.edu.cn 的记录,则继续 2.4 步骤。

Windows上的hosts文件路径:C:\Windows\System32\drivers\etc\hosts

Mac上的hosts文件路径:/etc/hosts

文件示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##
127.0.0.1 localhost
255.255.255.255 broadcasthost
::1 localhost
# Added by Docker Desktop
# To allow the same kube context to work on the host and the container:
127.0.0.1 kubernetes.docker.internal
# End of section

172.19.0.2 hadoop-master
172.19.0.3 hadoop-slave1
172.19.0.4 hadoop-slave2

2.4 访问本地DNS服务器

查找本地DNS服务器是否有 gtiit.edu.cn 的记录,如果没有则跳转到 2.5 步骤。

有些人可能会疑问本地 DNS 服务器是什么?

可以理解为企业或学校为了方便访问其内网服务,会自己搭建一些 DNS 服务器,这些服务器自然会对应一些 IP 地址。当我们连接上企业/校园网络后,DHCP 会告诉我们应该去请求哪些本地 DNS 服务器。

本地DNS服务器也可以理解为:递归DNS服务器,例如谷歌的8.8.8.8(包括家用网络没有本地DNS服务器的情况下,某些路由器自带的DNS功能)

在 Windows 系统的 CMD 中,通过 ipconfig /all 来查看当前配置的 DNS 服务器 IP。

在 MacOS 系统的终端中,通过 cat /etc/resolv.conf 来查看当前配置的 DNS 服务器 IP。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(base) ➜  ~ cat /etc/resolv.conf
#
# macOS Notice
#
# This file is not consulted for DNS hostname resolution, address
# resolution, or the DNS query routing mechanism used by most
# processes on this system.
#
# To view the DNS configuration used by this system, use:
# scutil --dns
#
# SEE ALSO
# dns-sd(1), scutil(8)
#
# This file is automatically generated.
#
nameserver 10.150.4.13
nameserver 10.103.4.10
nameserver 10.103.4.45

以我的Mac为例,我连接上 GTIIT 的校园网后,DHCP 会告诉我应该请求这三个本地 DNS 服务器。

2.5 访问根DNS服务器

本地DNS服务器将会向根DNS服务器发送请求。根DNS服务器告知 .cn(或者.com等)顶级域名服务器地址。

Tips:《流浪地球2》影片中要重启的3台根服务器分别位于中国北京,日本东京和美国杜勒斯。现实中,全球共有13台IPv4根服务器,命名分别为A到M,1台为主根服务器在美国,其余12台均为辅根服务器,其中9台在美国,2台在欧洲(英国和瑞典),1台在亚洲(日本)。

2.6 访问顶级DNS服务器

本地DNS服务器(或递归DNS服务器)向 .cn 顶级 DNS 服务器发起请求,.cn 顶级服务器告知 edu.cn 所属权威域名服务器地址。

2.7 访问权威DNS服务器

本地DNS服务器(或递归DNS服务器)向 edu.cn 的权威域名服务器地址发起请求,权威DNS服务器告知 gtiit.edu.cn 所对应的IP地址。

最后,本地DNS服务器会将解析最终结果告知客户端,整个DNS解析流程结束。

三. 相关命令

查看某域名解析对应的IP地址(默认DNS)

1
2
3
4
5
6
7
8
9
10
11
12
13
(base) ➜  ~ nslookup gtiit.edu.cn                    
Server: 10.150.4.13
Address: 10.150.4.13#53

Non-authoritative answer:
Name: gtiit.edu.cn
Address: 10.103.4.32
Name: gtiit.edu.cn
Address: 10.103.4.45
Name: gtiit.edu.cn
Address: 10.103.4.58
Name: gtiit.edu.cn
Address: 10.103.4.10

查看某域名解析对应的IP地址(指定DNS,例如8.8.8.8)

1
2
3
4
5
6
(base) ➜  ~ nslookup gtiit.edu.cn 8.8.8.8
Server: 8.8.8.8
Address: 8.8.8.8#53

Non-authoritative answer:
*** Can't find gtiit.edu.cn: No answer

查看完整解析流程(+trace参数)

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
(base) ➜  ~ dig @10.150.4.13 +trace  moodle.gtiit.edu.cn

; <<>> DiG 9.10.6 <<>> @10.150.4.13 +trace moodle.gtiit.edu.cn
; (1 server found)
;; global options: +cmd
. 63554 IN NS b.root-servers.net.
. 63554 IN NS a.root-servers.net.
. 63554 IN NS c.root-servers.net.
. 63554 IN NS j.root-servers.net.
. 63554 IN NS m.root-servers.net.
. 63554 IN NS h.root-servers.net.
. 63554 IN NS l.root-servers.net.
. 63554 IN NS d.root-servers.net.
. 63554 IN NS f.root-servers.net.
. 63554 IN NS g.root-servers.net.
. 63554 IN NS k.root-servers.net.
. 63554 IN NS e.root-servers.net.
. 63554 IN NS i.root-servers.net.
;; Received 692 bytes from 10.150.4.13#53(10.150.4.13) in 71 ms

cn. 172800 IN NS a.dns.cn.
cn. 172800 IN NS b.dns.cn.
cn. 172800 IN NS c.dns.cn.
cn. 172800 IN NS d.dns.cn.
cn. 172800 IN NS e.dns.cn.
cn. 172800 IN NS ns.cernet.net.
cn. 86400 IN DS 57724 8 2 5D0423633EB24A499BE78AA22D1C0C9BA36218FF49FD95A4CDF1A4AD 97C67044
cn. 86400 IN RRSIG DS 8 1 86400 20230828050000 20230815040000 11019 . LGkYzH66K84M7FmNlTfzE5TetLECmWi+yW0Pl+uL2z0CJgcmuOqHqhtI HaIHuttDYDX996TYUvS/ER7JNcnZ3kX8hI5/UVKtK0cFTexcMHmaza/I 8JvsI8l44f1Lz0qq+XgCa73H9Zj5HqM8qttcfRtY2wcVXDyIgrFQ20hL TUpdL5H9KoJpJVE0xEkJDfVfxaHRgm1Y4sRYGZ0ky/3O899drI7wnjrt qMIxJFP9b18r4ubh7YX9cUjbzL027T/0HOADXk1pGZ8rDjrnrYjXttL9 6CE7liEVNnnEGGyavVN8eGtzI2y+fPl8gv7zjd2OIS6KnsZ80qzvAO+w ZxPP5g==
;; Received 646 bytes from 199.7.83.42#53(l.root-servers.net) in 64 ms

gtiit.edu.cn. 172800 IN NS ns1.service.edu.cn.
gtiit.edu.cn. 172800 IN NS ns2.service.edu.cn.
70R541957QDDOQL3HNPDDTF75P3VV706.edu.cn. 21600 IN NSEC3 1 0 10 AFFF 70UK3LB5DE16L5VPVCL3KMP5J1K3UQ8A NS
70R541957QDDOQL3HNPDDTF75P3VV706.edu.cn. 21600 IN RRSIG NSEC3 8 3 21600 20230827040707 20230728035719 21204 edu.cn. C3+GMYA1YmJoLo8cRmCouEH5NzvKKgOmoSeNJ2uOwP47eO1zj9bntjT2 2QXJ9/1lE5Y7Iydyx//kFl2SNQd33d80KK7OQMuhQb2fdl9LnWEXprLb VX3htlltt8Ek9wq+vHc8YRFaTGXYJe5dO0Ocskxv7u0eeu1p0VvLlTSl X+0=
;; Received 422 bytes from 103.137.60.44#53(ns.cernet.net) in 63 ms

moodle.gtiit.edu.cn. 86400 IN A 116.6.38.28
gtiit.edu.cn. 86400 IN NS ns1.service.edu.cn.
gtiit.edu.cn. 86400 IN NS ns2.service.edu.cn.
;; Received 114 bytes from 202.112.5.49#53(ns1.service.edu.cn) in 52 ms

可以看到,本地DNS服务器首先访问了root-servers根DNS服务器然后访问了dns.cn顶级DNS服务器,然后访问了edu.cn的权威DNS服务器,最后得到 gtiit.edu.cn 的IP地址。

要注意,添加 +trace 参数后,所有迭代工作就由本机完成,而不是由递归服务器完成了(这意味着本地DNS服务器存在的解析记录会被忽略,可能导致直接dig @10.150.4.13 moodle.gtiit.edu.cn返回的IP不一致)。

在macOS上快速查看本机IP / DNS / DHCP

1
2
3
4
ipconfig getifaddr en0 # en0一般为无线网卡接口,或者使用ifconfig查看全部接口
cat /etc/resolv.conf

ipconfig getpacket en0 # yiaddr为本机IP,siaddr为DHCP