# DNS 查询原理详解

作者: 阮一峰

通过 DNS 查询,得到域名的 IP 地址,才能访问网站。

那么,DNS 查询到底是怎么完成的?本文通过实例,详细介绍背后的步骤。

# 一、DNS 服务器

域名对应的 IP 地址,都保存在 DNS 服务器。

我们输入域名,浏览器就会在后台,自动向 DNS 服务器发出请求,获取对应的 IP 地址。这就是 DNS 查询。

举例来说,我输入 es6.ruanyifeng.com 这个域名,浏览器就要向 DNS 服务器查询,它的 IP 地址是什么,然后向该 IP 发出访问请求。

网上有很多公用的 DNS 服务器,这篇文章选择 Cloudflare 公司提供的 1.1.1.1 进行演示。

# 二、dig 命令

命令行工具 dig 可以跟 DNS 服务器互动,我们就用它演示 DNS 查询。如果你还没有安装,可以搜一下安装方法,在 Linux 系统下是非常容易的。

它的查询语法如下(美元符号$是命令行提示符)。

$ dig @[DNS 服务器] [域名]

向 1.1.1.1 查询域名,就执行下面的命令。

$ dig @1.1.1.1 es6.ruanyifeng.com

正常情况下,它会输出一大堆内容。

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> @1.1.1.1 es6.ruanyifeng.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45348
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;es6.ruanyifeng.com.		IN	A

;; ANSWER SECTION:
es6.ruanyifeng.com.	300	IN	A	104.198.14.52

;; Query time: 175 msec
;; SERVER: 1.1.1.1#53(1.1.1.1)
;; WHEN: Thu Jul 27 00:58:55 CST 2023
;; MSG SIZE  rcvd: 63

在其中找到 ANSWER SECTION 这个部分,它给出了查询的答案,域名对应的 IP 地址是 104.198.14.52。

# 三、域名的树状结构

你可能会问,难道 DNS 服务器(比如 1.1.1.1)保存了世界上所有域名(包括二级域名、三级域名)的 IP 地址?

当然不是。DNS 是一个分布式系统,1.1.1.1 只是用户查询入口,它也需要再向其他 DNS 服务器查询,才能获得最终的 IP 地址。

要说清楚 DNS 完整的查询过程,就必须了解 域名是一个树状结构。

最顶层的域名是根域名(root),然后是顶级域名(top-level domain,简写 TLD),再是一级域名、二级域名、三级域名。

(1)根域名

所有域名的起点都是根域名,它写作一个点``.,放在域名的结尾。因为这部分对于所有域名都是相同的,所以就省略不写了,比如example.com等同于example.com.`(结尾多一个点)。

你可以试试,任何一个域名结尾加一个点,浏览器都可以正常解读。

(2)顶级域名

根域名的下一级是顶级域名。它分成两种:通用顶级域名(gTLD,比如 .com 和 .net)和国别顶级域名(ccTLD,比如 .cn 和 .us)。

顶级域名由国际域名管理机构 ICANN 控制,它委托商业公司管理 gTLD,委托各国管理自己的国别域名。

(3)一级域名

一级域名就是你在某个顶级域名下面,自己注册的域名。比如,ruanyifeng.com就是我在顶级域名.com下面注册的。

(4)二级域名

二级域名是一级域名的子域名,是域名拥有者自行设置的,不用得到许可。比如,es6.ruanyifeng.com 就是 ruanyifeng.com 的二级域名。

# 四、域名的逐级查询

这种树状结构的意义在于,只有上级域名,才知道下一级域名的 IP 地址,需要逐级查询。

每一级域名都有自己的 DNS 服务器,存放下级域名的 IP 地址。

所以,如果想要查询二级域名 es6.ruanyifeng.com 的 IP 地址,需要三个步骤。

  • 第一步,查询根域名服务器,获得顶级域名服务器.com(又称 TLD 服务器)的 IP 地址。

  • 第二步,查询 TLD 服务器 .com,获得一级域名服务器 ruanyifeng.com 的 IP 地址。

  • 第三步,查询一级域名服务器 ruanyifeng.com,获得二级域名 es6 的 IP 地址。

下面依次演示这三个步骤。

# 五、根域名服务器

根域名服务器全世界一共有13台(都是服务器集群)。它们的域名和 IP 地址如下。

根域名服务器的 IP 地址是不变的,集成在操作系统里面。

操作系统会选其中一台,查询 TLD 服务器的 IP 地址。

$ dig @192.33.4.12 es6.ruanyifeng.com

上面示例中,我们选择192.33.4.12,向它发出查询,询问es6.ruanyifeng.com的 TLD 服务器的 IP 地址。

dig 命令的输出结果如下。

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> @192.33.4.12 es6.ruanyifeng.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46954
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 8c0f5d976fc419c00100000064c150fb57cf3f145cfc1faf (good)
;; QUESTION SECTION:
;es6.ruanyifeng.com.		IN	A

;; AUTHORITY SECTION:
com.			172800	IN	NS	l.gtld-servers.net.
com.			172800	IN	NS	c.gtld-servers.net.
com.			172800	IN	NS	a.gtld-servers.net.
com.			172800	IN	NS	e.gtld-servers.net.
com.			172800	IN	NS	i.gtld-servers.net.
com.			172800	IN	NS	g.gtld-servers.net.
com.			172800	IN	NS	j.gtld-servers.net.
com.			172800	IN	NS	d.gtld-servers.net.
com.			172800	IN	NS	f.gtld-servers.net.
com.			172800	IN	NS	k.gtld-servers.net.
com.			172800	IN	NS	b.gtld-servers.net.
com.			172800	IN	NS	m.gtld-servers.net.
com.			172800	IN	NS	h.gtld-servers.net.

;; ADDITIONAL SECTION:
m.gtld-servers.net.	172800	IN	A	192.55.83.30
l.gtld-servers.net.	172800	IN	A	192.41.162.30
k.gtld-servers.net.	172800	IN	A	192.52.178.30
j.gtld-servers.net.	172800	IN	A	192.48.79.30
i.gtld-servers.net.	172800	IN	A	192.43.172.30
h.gtld-servers.net.	172800	IN	A	192.54.112.30
g.gtld-servers.net.	172800	IN	A	192.42.93.30
f.gtld-servers.net.	172800	IN	A	192.35.51.30
e.gtld-servers.net.	172800	IN	A	192.12.94.30
d.gtld-servers.net.	172800	IN	A	192.31.80.30
c.gtld-servers.net.	172800	IN	A	192.26.92.30
b.gtld-servers.net.	172800	IN	A	192.33.14.30
a.gtld-servers.net.	172800	IN	A	192.5.6.30
m.gtld-servers.net.	172800	IN	AAAA	2001:501:b1f9::30
l.gtld-servers.net.	172800	IN	AAAA	2001:500:d937::30
k.gtld-servers.net.	172800	IN	AAAA	2001:503:d2d::30
j.gtld-servers.net.	172800	IN	AAAA	2001:502:7094::30
i.gtld-servers.net.	172800	IN	AAAA	2001:503:39c1::30
h.gtld-servers.net.	172800	IN	AAAA	2001:502:8cc::30
g.gtld-servers.net.	172800	IN	AAAA	2001:503:eea3::30
f.gtld-servers.net.	172800	IN	AAAA	2001:503:d414::30
e.gtld-servers.net.	172800	IN	AAAA	2001:502:1ca1::30
d.gtld-servers.net.	172800	IN	AAAA	2001:500:856e::30
c.gtld-servers.net.	172800	IN	AAAA	2001:503:83eb::30
b.gtld-servers.net.	172800	IN	AAAA	2001:503:231d::2:30
a.gtld-servers.net.	172800	IN	AAAA	2001:503:a83e::2:30

;; Query time: 199 msec
;; SERVER: 192.33.4.12#53(192.33.4.12)
;; WHEN: Thu Jul 27 00:59:37 CST 2023
;; MSG SIZE  rcvd: 874

因为它给不了 es6.ruanyifeng.com 的 IP 地址,所以输出结果中没有 ANSWER SECTION,只有一个 AUTHORITY SECTION,给出了com.的13台 TLD 服务器的域名。

下面还有一个 ADDITIONAL SECTION,给出了这13台 TLD 服务器的 IP 地址(包含 IPv4 和 IPv6 两个地址)。

# 六、TLD 服务器

有了 TLD 服务器的 IP 地址以后,我们再选一台接着查询。

$ dig @192.41.162.30 es6.ruanyifeng.com

上面示例中,192.41.162.30 是随便选的一台 .com 的 TLD 服务器,我们向它询问 es6.ruanyifeng.com 的 IP 地址。

返回结果如下。

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> @192.41.162.30 es6.ruanyifeng.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24608
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 13
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;es6.ruanyifeng.com.		IN	A

;; AUTHORITY SECTION:
ruanyifeng.com.		172800	IN	NS	kara.ns.cloudflare.com.
ruanyifeng.com.		172800	IN	NS	norman.ns.cloudflare.com.

;; ADDITIONAL SECTION:
kara.ns.cloudflare.com.	172800	IN	A	108.162.192.123
kara.ns.cloudflare.com.	172800	IN	A	172.64.32.123
kara.ns.cloudflare.com.	172800	IN	A	173.245.58.123
kara.ns.cloudflare.com.	172800	IN	AAAA	2606:4700:50::adf5:3a7b
kara.ns.cloudflare.com.	172800	IN	AAAA	2803:f800:50::6ca2:c07b
kara.ns.cloudflare.com.	172800	IN	AAAA	2a06:98c1:50::ac40:207b
norman.ns.cloudflare.com. 172800 IN	A	108.162.193.217
norman.ns.cloudflare.com. 172800 IN	A	172.64.33.217
norman.ns.cloudflare.com. 172800 IN	A	173.245.59.217
norman.ns.cloudflare.com. 172800 IN	AAAA	2606:4700:58::adf5:3bd9
norman.ns.cloudflare.com. 172800 IN	AAAA	2803:f800:50::6ca2:c1d9
norman.ns.cloudflare.com. 172800 IN	AAAA	2a06:98c1:50::ac40:21d9

;; Query time: 204 msec
;; SERVER: 192.41.162.30#53(192.41.162.30)
;; WHEN: Thu Jul 27 01:00:50 CST 2023
;; MSG SIZE  rcvd: 365

它依然没有 ANSWER SECTION 的部分,只有 AUTHORITY SECTION,给出了一级域名 ruanyifeng.com 的两台 DNS 服务器。

下面的 ADDITIONAL SECTION 就是这两台 DNS 服务器对应的 IP 地址。

# 七、一级域名的 DNS 服务器

第三步,再向一级域名的 DNS 服务器查询二级域名的 IP 地址。

$ dig @172.64.32.123 es6.ruanyifeng.com

返回结果如下。

; <<>> DiG 9.11.3-1ubuntu1.12-Ubuntu <<>> @172.64.32.123 es6.ruanyifeng.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31767
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;es6.ruanyifeng.com.		IN	A

;; ANSWER SECTION:
es6.ruanyifeng.com.	300	IN	A	104.198.14.52

;; Query time: 178 msec
;; SERVER: 172.64.32.123#53(172.64.32.123)
;; WHEN: Thu Jul 27 01:02:50 CST 2023
;; MSG SIZE  rcvd: 63

这次终于有了 ANSWER SECTION,得到了最终的二级域名的 IP 地址。

至此,三个步骤的 DNS 查询全部完成。

# 八、DNS 服务器的种类

总结一下,上面一共提到了四种服务器。

  • 1.1.1.1
  • 根域名服务器
  • TLD 服务器
  • 一级域名服务器

它们都属于 DNS 服务器,都用来接受 DNS 查询。但是作用不一样,属于不同的类别。

# 8.1 递归 DNS 服务器

后三种服务器只用来查询下一级域名的 IP 地址,而 1.1.1.1 则把分步骤的查询过程自动化,方便用户一次性得到结果,所以它称为递归 DNS 服务器(recursive DNS server),即可以自动递归查询。

我们平常说的 DNS 服务器,一般都是指递归 DNS 服务器。它把 DNS 查询自动化了,只要向它查询就可以了。

它内部有缓存,可以保存以前查询的结果,下次再有人查询,就直接返回缓存里面的结果。所以它能加快查询,减轻源头 DNS 服务器的负担。

# 8.2 权威 DNS 服务器

一级域名服务器的正式名称叫做权威域名服务器(Authoritative Name Server)。

"权威"的意思是域名的 IP 地址由它给定,不像递归服务器自己做不了主。我们购买域名后,设置 DNS 服务器就是在设置该域名的权威服务器。

# 8.3 四种 DNS 服务器

综上所述,DNS 服务器可以分成四种:

  • 根域名服务器
  • TLD 服务器
  • 权威域名服务器
  • 递归域名服务器

它们的关系如下图。

知道了 DNS 查询的原理,完全可以自己写一个 DNS 的递归服务器,这是不难的。网上有很多参考资料,有兴趣的话,大家可以试试看。

# 九、参考网址

Building a Recursive DNS Resolver, Timothy Andrew (opens new window)

Authoritative Vs Recursive DNS: What You Need To Know, Serena Raymond (opens new window)

DNS 服务器类型,Cloudflare (opens new window)