【Network】DNS原理分析

Posted by 西维蜀黍 on 2017-04-04, Last Modified on 2021-09-21

记得有一次面试,被问道:当在浏览器中输入一个URL后会发生什么。就个人而言,很喜欢这样发散性的问题,因为客观的来说,这类问题能够客观地考察其对HTTPWeb的理解,也不用担心其有意准备了面试答案,稍微深入某个细节,就可了解其掌握程度。而且,从不同的角度看完全可以得出不同的分析过程。

在这其中一个重要的过程就是DNS解析DNS:Domain Name System)。

一 产生背景

TCP/IP 网络中要求每一台互连的主机都需要拥有一个唯一不重复的IP地址,不同的主机通过这个唯一的IP地址进行通信。然而,直接使用这个IP非常不方便。因为,IP是一串数据序列,并不好记忆。

其实,电话号码与IP非常类似,每一台电话都拥有一个唯一的电话号码(每一台主机都有一个唯一不重复的IP地址)。电话号码由数字组成比较难记(当然IP也是),而且在某个人搬家后,他的电话号码就不得不变化(IP自然也存在需要变化的情况),非常难管理。

因此,在TCP/IP世界诞生之初,就有一个叫主机识别码的东西。每一台联网的主机都赋予一个主机识别码,以标识这台主机,并替代直接使用一大串非常难记的IP地址。为此,系统必须能够自动地将输入的主机标识码转换为对应的IP地址

为了实现这个功能,每台主机都将这个主机标识符到IP地址的转换表存储在一个叫hosts的数据库文件中。几乎所有的现代操作系统中,还仍然存在这个hosts文件,只是其中的内容变少了(因为其大部分职能都被DNS服务器替代了)。

我的hosts文件的一个例子:

hosts文件路径:

  • Windows:C:\Windows\System32\drivers\etc\hosts
  • Linux:/etc/hosts

在互联网的起源ARPANET中,起初由互联网信息中心(SRI-NIC)整体管理一份hosts文件。如果新增一台主机接人到ARPANET网 或者 已有的某台主机要进行IP地址变更,中心的这个hosts文件就得更新,而且,其他主机则不得不定期下载最新的hosts文件以正常使用网络。

然而,随着网络规模的不断扩大、接人主机的个数不断增加,使得这种集中式管理主机名和IP地址映射关系的方案可行性逐渐降低。

其实这种从集中式管理到分布式管理方式的转变需求,和当今架构演变需求不是非常类似吗?分布式处理、主从分离、负载均衡……

在上述背景之下,产生了一个可以有效管理主机名和IP地址之间对应关系的系统,那就是DNS系统。在这个系统中,主机的管理机构可以对该对应关系进行变更和设定。

二 域名和域名服务器

1 域名

在介绍DNS系统的工作原理之前,我们先要了解什么是域名。

域名是一个为了识别主机名称和组织机构的一种具有分层结构的名称。

域名由英文字母、数字和某些允许的英文字符用点号(“.”)连接组成,形成层次结构,这样一个主域名分配给一个组织,这个组织可以拥有多个不同名的主机,并自由地为这些主机分配主域名下的不同子域名。

域名的分层结构

域名的分层结构如一棵树,顶点是树的根(root),顶点的下一层称为顶级域名(TLD: Top Level Domain),顶级域名可分为**国别顶级域名(ccTLD: country code Top Level Domain)通用顶级域名(gTLD: generic Top Level Doamin)**两种类型。

  • 国别顶级域名:包括“cn(中国)”、“jp(日本)”、“uk(英国)”等表示国家的域名
  • 通用顶级域名:包括“edu(教育机构)”、“com(商业组织)”、“org(管理组织)”等特定领域的域名

事实上,在实际的使用中,这里的“特定领域”已经不再那么严格了,比如个人网站也能使用“.com”或“.org”结尾的特定领域顶级域名

2 域名服务器

如上面的分层结构中描述,每一个层级中的每一个节点都有一个域名服务器来管理与其相关的下一层的所有子域名,而且这些域名服务器都称为权威服务器

(1)各层中的节点都有各自的域名服务器

比如,.cn拥有自己域名服务器,.uk拥有自己的域名服务器.,people.cn拥有自己的域名服务器,.baidu.com拥有自己的域名服务器….

(2)各层域名服务器都了解自己所在节点的下一连接分层所有节点的域名服务器的IP地址

比如,.cn了解.people.cn域名服务器的IP 和 .china.cn域名服务器的IP……

(3)顺着根节点可访问到世界上所有域名服务器的地址

由于每一层都记录下一层节点的域名服务器,所以可以从根节点开始,顺着层次结构,最终访问到世界上所有的域名服务器地址。

3 根域名服务器

Root节点所对应DNS服务器叫做根域名服务器。它对整理DNS解析起着至关重要的作用。根域名服务器中记录着下一层所有域名服务器的IP地址(.cn.uk.com.org…)。如果需要增加一个类似jp或者org的域名,或者修改已有域名的名称,在需要再根域名服务器中追加或者变更。

全球13组根域名服务器以英文字母A到M依序命名,域名名称格式为“[字母].root-servers.org”。其中有11个是以**任播 **(Anycasting)技术在全球多个地点设立镜像站。

任播:在待通信网络地址和网络节点之间存在一对多的关系:每一个网络地址对应一群接收节点,但在任何给定时间,只有其中一台网络节点会响应并发回响应数据。

http://www.internic.net/zones/named.root ,你可以查询到互联网根域名服务器的信息。

4 各层级域名服务器

(1)容灾能力

类似地,在根域名服务器的下一层级的域名服务器中,记录着再一下层级的域名服务器的IP地址。

如果域名服务器无法访问,那么对应域的DNS查询也就无法正常工作了。因此,为了提高容灾能力,对于某个域名,一般会设置至少两个的域名服务器(它们都是这个域的权威服务器)。

(2)子域的划分

swsmile.info就是一个顶级域名,而www.swsmile.info却不是顶级域名,他是在swsmile.info这个域里的一叫做www的主机,因此我们当然也给我们的主站命名为aaa.swsmile.infocccsss.swsmile.info,意义上与www是完全等同的,没有任何区别,只是人们习惯上把主站命名为www罢了。

一级域之后还有二级域,三级域,只要我拥有一个顶级域,那么我可以随意在前面多加几个域(当然需要在长度限制内),比如aaa.bbb.ccc.swsmile.infoa.b.c.www.swsmile.info等等都是可以的。

三 DNS解析过程

1 本机设置的DNS

现在我有一台计算机,通过 ISPInternet Service Provider,比如中国电信) 接入了互联网,那么 ISP 就会给我提供一个可供服务的DNS服务器的IP地址。

这里需要说明一下,ISP提供的可供服务的DNS服务器IP地址,指的是我可以使用它完成DNS解析服务,但并不意味着我只能使用它,因为我还可以使用114.114.114.114(114DNS)、8.8.8.8(Google Public DNS)、208.67.220.220(OpenDNS )等公共的DNS服务器。更极端一点,我还可以自己搭一个DNS服务器

注意,这个DNS服务器不是权威服务器,而是相当于一个代理的 DNS 解析服务器。也就是说,当我向它发出一个DNS解析请求时,它会检查自己的缓冲中是否已经存在了我需要查询的host对应的IP的地址。如果不存在,它会帮我向权威服务器迭代查询,并将查询结果返回给我。至于它有没有向权威服务器迭代,对我来说是透明的(不知情的),因此称它是一个代理的 DNS 解析服务器

比如,我的DNS设置:

2 DNS解析过程

在以下的描述过程中,本机设置的DNS服务器简称为本机DNS服务器,但需要明确这台服务器并不是在本机,而且其实你可以任意指定。

以在浏览器中输入“http://en.wikipedia.org” 查询后的DNS解析过程为例:

  • 浏览器检查浏览器内部的DNS缓存中该DNS条目是否有效(存在该缓存,且未过期)。如果有效,则直接返回IP地址;
  • 如果无效,查询操作系统的DNS缓存中是否存在该DNS条目。如果存在,则直接返回IP地址;
  • 如果不存在,浏览器向本机DNS服务器发出DNS请求(询问:“你知道en.wikipedia.org的IP吗?”)。
  • 本地DNS服务器查询自己的缓冲中该查询的DNS条目是否有效(存在该条目于缓存,且未过期)?如果有效,则直接返回IP地址;
  • 如果无效,本地DNS服务器向根服务器请求“.org”域的DNS服务器IP;
  • 本地DNS服务器向**“.org”域DNS服务器**请求“wikipedia.org”域的DNS服务器IP
  • 本地DNS服务器向**“wikipedia.org”域DNS服务器**请求“en.wikipedia.org”域的DNS服务器IP
  • 最终,本地DNS服务器获取到“en.wikipedia.org”域的服务器IP,并返回给本机

当然通过dig +trace en.wikipedia.org(在下文中会介绍dig工具常用的使用),你也能清晰地看到这个完整的过程:

再次强调:向根服务器请求“.org”域的DNS服务器IP向“.org”域DNS服务器请求“wikipedia.org”域的DNS服务器IP向“wikipedia.org”域DNS服务器请求“en.wikipedia.org”域的DNS服务器IP 的这三个过程都是在本地DNS服务器上完成,对于本机来说是透明的。

3 DNS的查询类型

(1)递归查询

主机向本地DNS服务器的查询一般都是采用递归查询

所谓递归查询就是:如果主机所询问的本地DNS服务器不知道被查询的域名的IP地址,那么本地DNS服务器就从根域名服务器开始发出查询请求,直至查询到目标IP地址,或者报错(表示无法查询到所需的IP地址)

具体来说,本地DNS服务器会向根域名服务器发出查询请求报文。如果根域名服务器没有直接给出结果,而是给出下一级域名服务器的(一台权威服务器)IP,那么本地DNS服务器就会向这个下一级域名服务器发出请求……一级一级地向下查询,直到查询到目标IP地址,或者报错。但是,本地DNS服务器一级一级地向权威服务器查询的行为对于发起查询的主机来说是透明的。

(2)迭代查询

本地DNS服务器向根域名服务器的查询一般都是采用迭代查询

迭代查询的特点:当根域名服务器收到本地DNS服务器发出的查询请求报文时,要么给出所要查询的IP地址,要么告诉本地DNS服务器:“你下一步应当向哪一个域名服务器(暂且称为A权威域名服务器)进行查询,并给出该A权威域名服务器的IP”。 如果本地DNS服务器接收到的是A权威域名服务器的IP,就向它发出查询请求。类似地,A权威域名服务器在收到本地DNS服务器的查询请求后,要么给出所要查询的IP地址,要么告诉本地服务器下一步应当向哪一个下级的权限域名服务器进行查询…… 最终,本地DNS服务器要么查询到目标IP地址,要么报错。

四 域名解析设置

在一个域名的解析设置中,存在一些参数可供设置。

以下是一个域名的解析设置(仅供参考):

1 常见的域名记录类型

(1)主机记录(A记录)

用于名称解析的重要记录,它将特定的主机名映射到对应主机的IPv4地址上,是最常用的的记录类型。

比如,这里把en主机(对应en.wikipedia.org域名)映射到198.35.26.96这个IP。因此,我们输入en.wikipedia.org本质上是访问了198.35.26.96

(2)IPv6主机记录(AAAA记录)

与A记录对应,用于将特定的主机名映射到一个主机的IPv6地址

(3)域名服务器记录(NS记录)

用于指定此域名由哪个权威DNS服务器来进行解析。

一般来说,为了服务的安全可靠,至少应该有两条NS记录(指定多个DNS服务器为此域名服务),而A记录(指定多个IP为此域名服务)也可以有多条,这样就提供了服务的冗余性,防止出现单点失败。

(4)别名记录(CNAME记录)

用于将某个主机映射到某个域名上,访问这台主机与访问被指向域名的效果相同。

比如,对于顶级域名swsmile.info,一条记录的类型为CNAME记录,主机记录是mail,记录值是gmail.google.com。这意味着,当用户访问mail.swsmile.info时,实际上是访问了gmail.google.com(虽然浏览器的地址栏里仍然写着mail.swsmile.info)。


再比如CNAME记录还可以用于域名的跳转(这样的配置对用户来说,是感知不到)。还是举例来说,我为swsmile.github.io设置一条CNAME记录,值为www.swsmile.info

因为我希望,用户无论通过www.swsmile.info还是swsmile.github.io都可以访问到我的111.111.111.111主机。

>
$ dig swsmile.github.io
> swsmile.github.io 1000    IN  CNAME   www.swsmile.info
> www.swsmile.info  600     IN    A     111.111.111.111

上面结果显示,swsmile.github.io的CNAME记录指向www.swsmile.info。也就是说,用户查询swsmile.github.io的IP时,实际上返回的是www.swsmile.info的IP地址(即111.111.111.111)。

这样的好处是,当我需要变更服务器IP地址时,只要修改www.swsmile.info的A记录即可。

(5)逆向查询记录(Pointer Records,PTR记录)

用于从IP地址反查域名。dig命令的-x参数用于查询PTR记录。

(6)邮件记录(Mail eXchange,MX记录)

指定接收电子邮件的服务器地址。

2 TTL

TTL(Time-To-Live),表示一条域名解析记录在DNS服务器上的有效缓存时间

当某台的DNS服务器接收到主机发来的解析请求时,就会迭代向权威DNS服务器发出解析请求从而获得解析记录;在获得这条域名解析记录后,会在这台DNS服务器中保存一段时间。在这段时间内,如果再接收到这条域名解析记录对应查询请求,DNS服务器将不再向权威DNS服务器迭代发出请求,而是直接返回缓存中的记录。而这条域名解析记录的TTL值,指定了在这条记录在这台DNS服务器上保留的时间。

(1)设置较大的TTL值,加速域名解析

对于很少变化域名记录的网站,可以增大域名记录的TTL值,以增加这条域名记录在各个DNS服务器中的缓存时间。这样当主机访问这个网站时,请求的DNS服务器就不必再去请求权威服务器,而是直接将缓存中这条域名记录直接返回给主机。

(2)设置较小的TTL值,加速变化后的域名解析

相反,如果设置了较小的TTL值,当域名解析记录变化时,就可以在更短的时间生效。当然,这也意味着,会增加DNS服务器向权威服务器查询这条解析记录的次数,因而会增加主机平均查询这条域名解析记录的时间,影响用户的访问体验。

总的来说,TTL大了,修改解析记录后等待生效的时间就会变长。TTL小了,域名的解析速度就会受到影响。因此,TTL设置多少合适,没有一个绝对的答案,而需要根据网站的具体情况决定。

五 dig工具

(1)+trace -> 显示在DNS服务器迭代向权威服务器查询的过程

> $ dig +trace en.wikipedia.org

; <<>> DiG 9.8.3-P1 <<>> +trace en.wikipedia.org
;; global options: +cmd
.			5	IN	NS	a.root-servers.net.
.			5	IN	NS	c.root-servers.net.
.			5	IN	NS	b.root-servers.net.
.			5	IN	NS	l.root-servers.net.
.			5	IN	NS	d.root-servers.net.
.			5	IN	NS	j.root-servers.net.
.			5	IN	NS	m.root-servers.net.
.			5	IN	NS	f.root-servers.net.
.			5	IN	NS	i.root-servers.net.
.			5	IN	NS	h.root-servers.net.
.			5	IN	NS	g.root-servers.net.
.			5	IN	NS	k.root-servers.net.
.			5	IN	NS	e.root-servers.net.
;; Received 228 bytes from 192.168.30.2#53(192.168.30.2) in 220 ms

org.			172800	IN	NS	a0.org.afilias-nst.info.
org.			172800	IN	NS	a2.org.afilias-nst.info.
org.			172800	IN	NS	b0.org.afilias-nst.org.
org.			172800	IN	NS	b2.org.afilias-nst.org.
org.			172800	IN	NS	c0.org.afilias-nst.info.
org.			172800	IN	NS	d0.org.afilias-nst.org.
;; Received 436 bytes from 198.97.190.53#53(198.97.190.53) in 327 ms

wikipedia.org.		86400	IN	NS	ns0.wikimedia.org.
wikipedia.org.		86400	IN	NS	ns2.wikimedia.org.
wikipedia.org.		86400	IN	NS	ns1.wikimedia.org.
;; Received 146 bytes from 199.19.53.1#53(199.19.53.1) in 130 ms

en.wikipedia.org.	600	IN	A	198.35.26.96
;; Received 78 bytes from 91.198.174.239#53(91.198.174.239) in 262 ms

(2)+short -> 最少内容显示

如果不想看到这么多内容,可以使用+short参数。

> $ dig +short en.wikipedia.org

198.35.26.96

(3)@ -> 指定某台DNS服务器进行解析

在未指定DNS服务器时,dig会向本级指定的默认DNS服务器查询。

> $ dig @114.114.114.114 en.wikipedia.org

; <<>> DiG 9.8.3-P1 <<>> @114.114.114.114 en.wikipedia.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24390
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;en.wikipedia.org.		IN	A

;; ANSWER SECTION:
en.wikipedia.org.	66	IN	A	198.35.26.96

;; Query time: 9 msec
;; SERVER: 114.114.114.114#53(114.114.114.114)
;; WHEN: Thu Apr  6 07:31:39 2017
;; MSG SIZE  rcvd: 50

六 WHOIS

通过WHOIS,你可以查询到这个域名的所有者信息

对于大多数根域名服务器,基本的WHOIS由ICANN维护,而WHOIS的细节则由控制那个域的域注册机构维护。

对于240多个国家代码顶级域名(ccTLDs),通常由该域名权威注册机构负责维护WHOIS。例如中国互联网络信息中心(China Internet Network Information Center)负责.CN域名的WHOIS维护,香港互联网注册管理有限公司(Hong Kong Internet Registration Corporation Limited)负责.HK域名的WHOIS维护,台湾网络信息中心(Taiwan Network Information Center)负责.TW域名的WHOIS维护。

比如,我可以查看baidu.com的所有者信息:

七 参考