DNS探秘

什么是DNS

当你流畅使用互联网的过程中,有可能你从来没有注意到过有DNS这个东西。而大部分人也许只是在无法上网时配置各种网络参数的过程中略看到过DNS这三个字母。所以,先解释下DNS是什么:

DNS(Domain Name System),域名名称系统,基本上做的事情就是把大家惯常使用的www.xxxx.com一类的便于记忆的英文(最近还有中文)地址,转换为xxx.xxx.xxx.xxx数字格式的ip地址,供计算机访问使用。

然后,我们先用几个实际的例子解释下我们上网过程中DNS是怎么运行的。

访问网站中的DNS

过程

”咔咔咔……“你用键盘在浏览器的地址栏里输入了”www.miluo.us"这个地址,点了一下回车。浏览器为了能拿到对应的网站ip地址,开始了查找地址的历程。

浏览器先查看了自己的缓存,发现没有之后,找操作系统检查是否有缓存这个地址的ip。操作系统先查看Hosts文件看是否有对应记录,但是很不巧,Hosts文件和两边缓存都没有存下地址对应的ip。所以,操作系统连接到DNS服务器(DNS Resolver)查询这个网址的ip地址。如果使用DHCP在局域网内动态获取IP,DNS服务器的地址是在过程中被网络管理者分配的。一般解析服务器都是ISP(服务商)提供的。

DNS解析服务器收到请求后,依旧会首先查询自己的缓存。如果缓存里没有任何数据,DNS解析服务器会去找根域名服务器(root server)。(根域名服务器目前只有13个,这些地址是被直接记录在DNS服务器里的)

我们的网址,比如www.miluo.us,写全了应该是www.miluo.us.root。由于DNS多级管理的特点,域名解析服务器会依次去找root->us->miluo对应的服务器ip。所以完整的域名层级结构是:主机名.次级域名.顶级域名.根域名

从根域名服务器,我们可以取到.US域名的TLD(Top-Level Domain,顶级域名)服务器的地址记录(NS记录和A记录,具体的记录分类我们下面解释)。取到记录后DNS服务器会将它几记录在缓存之中,避免之后再去请求根域名服务器获取TLD服务器地址。

顶级域名服务器一般由ICANN维护,一般有两字母的国家域名、本国文字域名、三个或多字母的一般顶级域名和用于反向DNS查找的.apra域名(从IP到域名)。

在.US TLD服务器,我们可以拿到miluo.us所对应的次级域名权威服务器记录。(例如ns1.miluo.us,TLD权威服务器会通过glue info将该服务器的ip告知)

最终,在次级域名权威服务器,我们取到www.miluo.us域名对应的ip地址。

实验

使用dig命令可以显示DNS的查询过程。而使用+trace参数则可以看到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
$ dig +trace www.miluo.us
; <<>> DiG 9.10.6 <<>> +trace www.miluo.us
;; global options: +cmd
. 4488 IN NS j.root-servers.net.
. 4488 IN NS f.root-servers.net.
. 4488 IN NS l.root-servers.net.
. 4488 IN NS g.root-servers.net.
. 4488 IN NS e.root-servers.net.
. 4488 IN NS k.root-servers.net.
. 4488 IN NS a.root-servers.net.
. 4488 IN NS i.root-servers.net.
. 4488 IN NS d.root-servers.net.
. 4488 IN NS b.root-servers.net.
. 4488 IN NS m.root-servers.net.
. 4488 IN NS c.root-servers.net.
. 4488 IN NS h.root-servers.net.
;; Received 239 bytes from 172.20.10.1#53(172.20.10.1) in 20 ms

us. 172800 IN NS c.cctld.us.
us. 172800 IN NS k.cctld.us.
us. 172800 IN NS a.cctld.us.
us. 172800 IN NS b.cctld.us.
us. 172800 IN NS f.cctld.us.
us. 172800 IN NS e.cctld.us.
us. 86400 IN DS 39361 8 1 09E0AF18E54225F87A3B10E95C9DA3F1E58E5B59
us. 86400 IN DS 39361 8 2 415D8DAE2299D2C2DAB7458ED4C715268CD2EB3AE3C1C249FF1696BF 62112201
us. 86400 IN RRSIG DS 8 1 86400 20190619050000 20190606040000 25266 . GpWNkjJNIIN9IC0mK0rLuYDog0Y6SbuNGCNO8SFEGZ5PbN4LeVHHLFGn b2iVaaNONfb+GZzem6RO7t40QKVow4iuPuQsWVi04DgWPCixPdw3DjLv SuIKYVT2uZkGAjAxfec/FW2X+Sq+336ib/01uY/mkD6BjomLnuy77Cd9 u93IQJfaSU6RPVkezsKLAJ0KloXyBjT4w3YsKA8ySIrsKTE2wcb8WwjK SmOSRoTGF7cWdu34+iLd13fhGcgMm4Dfnn0vmOeKA6rmRO7pWkYr3LoX KKhcVrb3jCEdi54QOeLCZoQpDkXPmTuSuVNI9FbHc7SyPO/gb080En6y Z8JUUQ==
;; Received 694 bytes from 198.41.0.4#53(a.root-servers.net) in 264 ms

miluo.us. 3600 IN NS eric.ns.cloudflare.com.
miluo.us. 3600 IN NS dora.ns.cloudflare.com.
04mlcpvb7mqd2gpuv2rh2rcgskp50v81.us. 86400 IN NSEC3 1 1 1 5BF34C13 04R1RMKBKJH0J1CFTS2HVM39M35KK2EG NS SOA RRSIG DNSKEY NSEC3PARAM
04mlcpvb7mqd2gpuv2rh2rcgskp50v81.us. 86400 IN RRSIG NSEC3 8 2 86400 20190704175455 20190604174722 8985 us. E7eMcfq+gUl+bOi007F/m6VbMYAoQTRQjM1IuOJjkoMnuu+7gia/rMcr lmytr/h4WQvoYAFvixsO7M6SI+b5d2n5EFm52btGDb4fiVN6fkCRdPCL orkcjAHBOhejYScf93ZriRA9y7LCeQ1jTpFYBKXPY4a+8jVCtQbB0K1H V6jchb1zhXpBlxjnClQWFCqD5efIYlU57nK4GlX0Y0VAgQ==
un42u24n4ldtnbbanq09gk3kkq7j1jfo.us. 86400 IN NSEC3 1 1 1 5BF34C13 UN74UD4QL2KROLAMA5PO99TDJV7C9B3V NS DS RRSIG
un42u24n4ldtnbbanq09gk3kkq7j1jfo.us. 86400 IN RRSIG NSEC3 8 2 86400 20190630213022 20190531203509 8985 us. e6a4ae969C/40+l3HEY/HjvZAObS389GXxOVVfvnDHGDgXAIexMHLclO pxzokhU5av6hrme92zUB+ObSgRajcRcoIn0xgC3sMAMKOzDiBrJbK98v SZolrkez9rk2aeykxjuwYa+tr88FzIu3oKiwtN5i8LnipagiSea7A9D4 pRJ0JtR4kN3NFBGNHqEFSWFjtu/P+gpyUEmuJZxP36ueIw==
;; Received 651 bytes from 209.173.58.70#53(f.cctld.us) in 98 ms

www.miluo.us. 300 IN A 149.129.83.92
;; Received 57 bytes from 173.245.58.108#53(dora.ns.cloudflare.com) in 339 ms

其中第一部分列出了根域名服务器.的13个NS记录,根据内置的根域名服务器IP地址,DNS服务器向所有这些IP地址发出查询请求,询问www.miluo.us的顶级域名服务器us.的NS记录。最先回复的根域名服务器将被缓存,以后只向这台服务器发请求。

第二部分,a.root-servers.net返回了.us域名的国家与地区顶级域权威服务器地址。

第三部分,f.cctld.us这台.us域名服务器返回了miluo.us对应的域名服务器。可以看到,由于我使用了cloudflare的DNS服务,域名服务器对应为eric.ns.cloudflare.com.dora.ns.cloudflare.com.

第四部分,由dora.ns.cloudflare.com返回了www.miluo.us对应的IP地址149.129.83.92

记录类型

上面的查询过程中,我们看到记录有ANS等类型。常用记录对应的意义为:

1
2
3
4
5
6
7
8
9
(1) A:地址记录(Address),返回域名指向的IP地址。

(2) NS:域名服务器记录(Name Server),返回保存下一级域名信息的服务器地址。该记录只能设置为域名,不能设置为IP地址。

(3)MX:邮件记录(Mail eXchange),返回接收电子邮件的服务器地址。

(4)CNAME:规范名称记录(Canonical Name),返回另一个域名,即当前查询的域名是另一个域名的跳转。由于是一个跳转,域名一旦设置CNAME记录以后,就不能再设置其他记录了。

(5)PTR:逆向查询记录(Pointer Record),只用于从IP地址查询域名,dig命令的-x参数可用于查询PTR记录。

详细记录可查询IANA - Domain Name System (DNS) Parameters,上面DS/RRSIG涉及到DNSSEC,可参见How DNSSEC Works

而记录后面的TTL表示Time to live,即域名的缓存时间。

买域名中的DNS

过程

当你通过域名代理商购买域名时,域名代理商又是如何将你购买的域名关联到你的服务器上的呢?

首先,你会需要去一个域名注册商(比如GoDaddy、NameSilo)买一个域名。这些域名注册商如同零售店,可以在不同零售店买到各种顶级域名下的域名。而他们会去和”批发商“进货。

每个TLD都有一个对应的注册局记录了特定顶级域下所有域名,而注册局运营者,也成为网络信息中心(NIC, Network Information Center)是提供注册局服务的实体。

比如.comTLD就被Verisign.管理着,而.cn的管理者是CNNIC。

而所有的域名系统则由ICANN(互联网名称与数字地址分配机构)管理。(这个机构还管理IP地址的分配)。由于它是一个非盈利机构,只会在域名注册费用中抽很少的成维持自己的运营。

买完域名之后,你需要去域名注册商那里更改你的域名对应的NS记录,让其指向一个DNS解析服务商(一般域名注册商也会默认设置一个DNS解析服务商)。比较常见的例如cloudflare、DNSPod等。

接下来由于各处都有缓存,需要等待互联网各处的域名解析服务器缓存中网站对应的NS、A记录过期,才能算作完成了最终的网站地址的改变。

中国特色的DNS问题

理想状况下,上面的整个流程都不会有什么问题。然而在实际中,经常会遇到域名劫持和域名投毒的问题。

首先说DNS劫持,简而言之就是ISP的DNS在解析你的域名过程中,给你返回了错误的IP。比如一个广告页面啊、把谷歌变成百度啊什么的。这个也比较好解决,不使用ISP给你的DNS而是把DNS设置为靠谱的DNS就好。

躲过了DNS劫持,又出现了DNS投毒的问题。所谓DNS投毒,即是在你向域名服务器发送了域名查询请求后,趁查询结果还没返回,伪造一个假的DNS查询结果返回给你的电脑。如此一来,你电脑拿到的就是伪造的查询结果。该问题可以用DNSSEC或DNS over HTTPS等基于协议层解决,运营者也可以部署多台权威DNS降低攻击成功率。