摘要:DNS(Domain Name System)是域名系统的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,用于 TCP/IP 网络。
本文分享自华为云社区《DNS那些事——从浏览器输入域名开始分析DNS解析过程》,作者: 砖业洋__ 。
我们就从在浏览器输入域名开始分析。
也称为DNS解析器。这种服务器是 DNS 查询的起点,它负责从根 DNS 服务器开始解析域名,一步步查询到目标域名所在的 DNS 服务器,并将解析结果返回给用户设备。递归 DNS 服务器通常由网络服务提供商(ISP)或公司网络管理员管理。
这些服务器负责管理域名系统的根区域,它们存储着所有顶级域名(如.com、.org、.cn等)的 DNS 记录。根 DNS 服务器分为13个,分布在全球不同地点,由不同组织管理,以保证 DNS 的高可靠性和稳定性。根域名服务器由一家名为 Internet 名称与数字地址分配机构(ICANN) 的非营利组织进行监督。
根域名服务器由13组集群服务器构成(并不是只有13台服务器),每组集群服务器中包含多台服务器,共同承担服务。这些服务器被部署在全球各地的数据中心中,以确保根域名服务器的高可用性和容错能力,每个集群中都有多台服务器进行冗余备份,它们的备份和副本分布在世界各地的不同地方。
举个例子,13个根域名服务器的IP地址可能是这样
a.root-servers.net (198.41.0.4) b.root-servers.net (199.9.14.201) c.root-servers.net (192.33.4.12) d.root-servers.net (199.7.91.13) e.root-servers.net (192.203.230.10) f.root-servers.net (192.5.5.241) g.root-servers.net (192.112.36.4) h.root-servers.net (198.97.190.53) i.root-servers.net (192.36.148.17) j.root-servers.net (192.58.128.30) k.root-servers.net (193.0.14.129) l.root-servers.net (199.7.83.42) m.root-servers.net (202.12.27.33)
TLD(Top Level Domain)服务器负责管理顶级域名(如.com、.org、.net、.cn等)的 DNS 记录。当用户访问一个域名时,递归 DNS 服务器首先会向根 DNS 服务器查询顶级域名的DNS 服务器地址,然后再向相应的 TLD 服务器查询该域名的DNS服务器地址。一旦找到权威 DNS 服务器,递归 DNS 服务器就会向其查询域名的 IP 地址,最终返回给用户设备。
TLD 域名服务器的管理由 Internet 编号分配机构(IANA) 处理,其为 ICANN 的一个分支机构,IANA 将 TLD 服务器分为几组:
当递归解析器收到来自 TLD 域名服务器的响应时,该响应会将解析器定向到权威性域名服务器。权威性域名服务器通常是解析器查找 IP 地址过程中的最后一步。
放一张cloudflare的图更方便理解输入网址后请求的过程。
假设我们要访问 abc13.ban2.lcy0000.top(假设存在该网站),当浏览器输入这个网址后,查询流程如下
1.本地 hosts 文件
本地计算机会首先检查本地 hosts 文件是否包含 abc13.ban2.lcy0000.top 的 IP 地址映射。如果存在,则直接返回该 IP 地址,否则继续进行 DNS 查询。
2.本地 DNS 缓存
本地计算机会检查本地 DNS 缓存是否包含 abc13.ban2.lcy0000.top 的 IP 地址。如果存在,则直接返回该 IP 地址,否则继续进行 DNS 查询。
3.ISP的递归 DNS 服务器(图中的DNS Resolver)
本地计算机会向 ISP 的DNS 服务器发起 DNS 查询请求,询问 abc13.ban2.lcy0000.top 的 IP 地址。(图中的连线1)
ISP是互联网服务提供商,简单理解为就是移动、联通、电信。
4.根 DNS 服务器(图中的Root Server)
ISP 的 DNS 服务器会向根 DNS 服务器查询 .top 顶级域名的 DNS 服务器的 IP 地址,根 DNS 服务器会返回 .top 顶级域名的 DNS 服务器的 IP 地址。(图中的2、3连线代表查询和返回)
5.顶级域名服务器(图中的TLD Server)
ISP的 DNS 服务器会向该 DNS 服务器查询 lcy0000.top 二级域名的 DNS 服务器的 IP 地址。(图中的4、5连线代表查询和返回)
6.权威 DNS 服务器
ISP的 DNS 服务器会向lcy0000.top 二级域名的 DNS 服务器查询 ban2.lcy0000.top的DNS服务器的 IP 地址。(图中的连线6)
7.权威 DNS 服务器
ban2.lcy0000.top 的 DNS 服务器查询 abc13.ban2.lcy0000.top 的 IP 地址,abc13.ban2.lcy0000.top 的 IP 地址被返回。权威服务器之间的查询过程不需要ISP的递归服务器参与,ISP的DNS只需要查询一次权威服务器即可(图中的连线7)
8.ISP的递归 DNS 服务器(图中的DNS Resolver)
ISP的 DNS 服务器会将查询结果返回给本地计算机。操作系统将使用该IP地址来访问对应的网站,并将该IP地址添加到本地DNS缓存中,以便下次访问同一网站时更快地获取IP地址。(图中的连线8)
9.本地计算机
本地计算机将使用该 IP 地址与 abc13.ban2.lcy0000.top 进行通信,浏览器使用该IP地址向 abc13.ban2.lcy0000.top 的服务器发起HTTP请求,获取相应的网页内容。(图中的9、10连线代表查询和返回)
从图上可以看到,从浏览器到ISP的递归DNS服务器的这个步骤是递归查询(Recursive Query),从递归DNS服务器到根、顶级、权威域名服务器这个过程是迭代查询(Iteractive Query)。
hosts文件中存放着IP地址和对域名,可以手动配置,作用是为了将特定的域名映射到特定的IP地址上,从而在访问这些域名时不需要进行DNS解析,直接使用hosts文件中的IP地址进行访问。如果访问的域名不在hosts文件中,则会查找DNS缓存或者从DNS服务器获取对应的IP地址并进行访问。如果你在hosts文件配置错了IP,那这个网站将无法访问。因为后面不会再去查找本地DNS缓存和DNS服务器解析,就根据hosts文件中的IP去访问。
相对于本地DNS缓存,hosts文件的优势在于它可以直接控制特定域名的解析结果。当你在hosts文件中手动添加了一个IP地址和域名的对应关系后,这个映射关系将会一直生效,不受DNS缓存的影响。而本地DNS缓存是由操作系统自动维护的,它会根据DNS服务器返回的TTL值来判断缓存是否过期,当缓存过期后需要重新进行DNS解析,如果DNS服务器返回了不同的IP地址,则会更新缓存中的记录。
hosts文件通常位于操作系统中的一个特定目录下,比如在Windows系统中,hosts文件通常位于C:\Windows\System32\drivers\etc目录下,它是一个以文本形式存储的文件,可以使用任何文本编辑器进行编辑。在mac中,位于/etc/目录下。
windows可以用下面命令
ipconfig /displaydns
mac可以用下面命令
// 这个是刷新本地 DNS 缓存,并清除所有缓存记录 sudo killall -HUP mDNSResponder // 这个是显示本地 DNS 服务器缓存的所有域名和对应的 IP 地址 dscacheutil -cachedump -entries Host
执行了这个命令却没看到我刚访问的域名对应的ip,这是没缓存吗?
如果执行了 ipconfig /displaydns 或者 dscacheutil -cachedump -entries Host 命令,但是没有看到刚访问的域名对应的 IP 地址,可能有以下几种情况:
A 记录是 DNS 中最基本的一种记录类型,用于将一个域名(例如 http://www.example.com)映射到一个 IPv4 地址(例如 192.168.0.1)。具体来说,A 记录将一个域名与一个 IP 地址建立映射关系。当用户输入一个域名时,DNS 服务器会返回与之对应的 IP 地址,从而使用户能够访问该域名对应的网站或服务。
举个例子,假设我们有一个网站 http://www.example.com,它的 IP 地址是 192.168.0.1。我们可以在 DNS 中添加一个 A 记录,将 http://www.example.com 指向 192.168.0.1。这样,当用户输入 http://www.example.com 时,DNS 服务器会返回 IP 地址 192.168.0.1,从而使用户能够访问我们的网站。
如下这是我买的域名配置的图:
AAAA 记录是 A 记录的扩展,用于将一个域名(例如 http://www.example.com)映射到一个 IPv6 地址。具体来说,AAAA 记录将一个域名与一个 IPv6 地址建立映射关系。当用户输入一个域名时,DNS 服务器会返回与之对应的 IPv6 地址,从而使用户能够访问该域名对应的网站或服务。
举个例子,假设我们有一个网站 http://www.example.com,它的 IPv6 地址是 2001:0db8:85a3:0000:0000:8a2e:0370,我们访问 http://www.example.com 时,DNS 解析过程中就会查询该 AAAA 记录,返回 IPv6 地址。
图就不放了,和上面类似。
CNAME 记录将一个域名(例如 http://www.example.com)指向另一个域名(例如 http://example.com)。这个过程类似于重定向,方便用户快速访问该域名。CNAME 记录通常用于将某个子域名指向其父域名,或将一个域名指向另一个域名(例如将 http://www.example.com 指向 http://example.com)。
举个例子,假设我们有一个网站 http://www.example.com,它的 IP 地址是 192.168.0.1,同时我们还希望用户能够通过 http://example.com 访问该网站。我们可以在 DNS 中添加一个 CNAME 记录,将 http://example.com 指向 http://www.example.com。这样,当用户输入 http://example.com 时,DNS 服务器会返回 http://www.example.com 的 IP 地址 192.168.0.1,从而使用户能够访问我们的网站。
在DNS解析过程中,如果输入的域名没有CNAME记录,DNS权威服务器会查找该域名对应的IP地址并返回。但是如果该域名有CNAME记录,DNS权威服务器会先将域名重定向到CNAME指向的域名,然后继续解析该域名的IP地址。这个过程也被称为“CNAME链”。
因此,添加了www的CNAME记录会将没有www前缀的域名重定向到添加了www前缀的域名,这样访问者就可以通过www前缀来访问网站了。
一般来说,两个域名的DNS
解析的结果可能不同,指向的是不同的服务器。当访问"baijiahao.baidu.com"
时,域名对应的IP
可以被解析出来。但是在URL
中加上"www."
之后,请求的域名变为"www.baijiahao.baidu.com"
,这个域名的DNS
解析结果可能不同于"baijiahao.baidu.com"
,如果该域名未被配置,则无法访问该站点。
玩过云服务器配置过域名解析的就会知道,从请求的结果来看,就是www.baijiahao.baidu.com
没配置对应IP
。
这个配置需要在域名所有权者的DNS
解析控制面板中进行。具体的配置方式可能会因不同的DNS
服务提供商而有所不同,但通常可以通过添加DNS
记录来配置子域名。
在这个例子中,百度作为域名所有者,他们可能会在他们的DNS
解析控制面板中添加一个名为"www"
的CNAME
记录,将其指向"baijiahao.baidu.com"
,类似于重定向,这样当用户在浏览器中输入"www.baijiahao.baidu.com"
时,DNS
服务器就会返回指向"baijiahao.baidu.com"
的IP
地址,从而使用户能够访问该网站。或者添加一个名为"www.baijiahao.baidu.com"
的"A"
记录,然后IP
配置的和"baijiahao.baidu.com"
的IP
地址一样,这样不管访问"www.baijiahao.baidu.com"
还是"baijiahao.baidu.com"
都解析为同一个IP
。
各位可以在命令行ping www.baidu.com
和ping baidu.com
,会发现IP
不一样,也许就是配置了两个不同的A
记录。
假设输入的域名是abc.coc,这个域名显然不符合域名规范,应该是 http://abc.com 或 http://abc.cn 等等。
首先,本地和递归DNS服务器会检查DNS缓存是否存在该域名的解析记录,由于这是一个不存在的域名,本地和递归DNS服务器缓存中肯定没有相关记录,因此会向根域名服务器发送查询请求。
根域名服务器无法解析该域名,因为 .coc 不是一个合法的顶级域名,因此根域名服务器会返回一个“域名不存在”的错误信息给递归DNS服务器。
递归DNS服务器收到根域名服务器的响应后,会将“域名不存在”的错误信息返回给客户端,客户端显示无法解析该域名。
需要注意的是,由于 abc.coc 不符合域名规范,大部分浏览器或操作系统会在输入时就进行格式校验,当输入的字符串无法被识别为域名,就会变成搜索操作。
DNS解析使用的是UDP协议,因为DNS查询通常只需要发送小量的数据,而UDP协议是无连接、不可靠的,但是比TCP更快速和轻量级。当然,对于一些特殊情况下的DNS解析,也可能使用TCP协议,比如DNS数据包超过了UDP报文最大长度时,会使用TCP进行分片传输。如果 DNS 查询包的大小超过 512 字节,或者查询返回的响应包的大小超过 512 字节,则必须使用 TCP 协议。
为了提高服务的可靠性和可用性,通常会部署多台相同配置的 DNS 服务器,提供相同的 DNS 解析服务,通过将这些服务器添加到一个逻辑组中,可以实现循环 DNS 技术,从而实现负载均衡和高可用性(所以这个负载均衡并不是靠专门的硬件,有缺点)。
通过将多个相同的 DNS 权威服务器添加到一个逻辑组中,以均衡 DNS 解析请求的负载。假设有六台服务器(A、B、C、D、E、F),它们都在循环 DNS 配置中。当客户端发起 DNS 查询请求时,循环 DNS 服务器会从该组中选择一个服务器,并将请求发送到该服务器。循环 DNS 服务器选择服务器 A 处理该请求。如果服务器 A 无法响应请求,则循环 DNS 服务器会将请求发送到 B 服务器。如果 B 服务器也无法响应请求,则循环 DNS 服务器会将请求发送到 C 服务器,以此类推。每次查询 DNS 服务器时,它都会以循环方式将最近响应的 IP 地址发送到队列后面。
但是缺点很明显,越往后因为拒绝服务导致重试的次数越多,请求变慢。
超过了设定的超时时间,客户端就会认为该DNS服务器未能响应。超时时间的长度是可以设置的,通常在几秒钟到几十秒钟之间。如果在超时时间内未能获得响应,客户端就会尝试向下一个DNS服务器发起请求。如果所有的DNS服务器都未能响应,就会返回一个错误信息给用户。
在这种情况下,如果客户端的 DNS 解析超时并向另一个 DNS 服务器发出请求,则浏览器的 network 中可能会出现两个 HTTP 请求记录。第一个记录是 DNS 解析无响应的请求,第二个记录是重试能成功的 HTTP 请求。如果 DNS 解析超时并且没有重试,则只会显示一个请求记录,即 DNS 解析请求。
可以用负载均衡来分配 DNS 查询请求到不同的 DNS 服务器上,以实现负载均衡。这些 DNS 服务器可以根据请求的源 IP 地址、地理位置或者其他特定条件来分配权重,进行筛选最优的服务器,从而避免单个权威 DNS 服务器承受过多的请求压力。如果其中一台DNS服务器出现问题,系统会自动将它从轮询列表中删除,从而确保之后客户端的请求不会被发送到不可用的DNS服务器上。
可以根据地理位置将 DNS 查询发送到最近的 DNS 服务器,是因为它利用了网络路由中的机制。在互联网中,路由器将数据包转发到下一跳时,通常会选择距离最短的路径。这个距离可以通过测量网络的物理距离、延迟等指标来计算。Anycast DNS 利用了这个机制,在不同的地理位置部署多个 DNS 权威服务器,从而实现了就近访问。
假设有一个名为 http://www.example.com 的域名,该域名有三个 DNS 权威服务器,分别位于深圳、上海和北京。这三个 DNS 服务器根据域名能解析出同一个 IP 地址。现在,一个位于深圳的客户端发起 DNS 查询请求。路由器会将该请求发送到距离最近的 DNS 服务器,也就是深圳的那个 DNS 服务器。如果这个 DNS 服务器无法响应,那么路由器会将请求发送到次近的 DNS 服务器,也就是上海的那个 DNS 服务器。以此类推,直到找到可响应请求的 DNS 服务器为止。
上面说的是DNS权威服务器之间的的负载均衡,应用基于DNS的负载均衡又是怎样的呢?
假设有一个域名 http://example.com,它对应着多个应用服务器的 IP地址,为了实现负载均衡,可以在同一个权威域名服务器的 DNS 记录中配置多个 A 记录,每个 A记录对应一个应用服务器的 IP地址,权威域名服务器会将A记录中的多个IP地址返回给DNS递归服务器,由递归服务器根据一定的负载均衡策略选择其中一个IP地址返回给客户端。这样就实现了应用基于DNS的负载均衡。
递归服务器的负载均衡策略通常会根据一定的算法从多个IP地址中选择一个来返回给客户端,这个算法通常是根据IP地址的性能、可用性、距离等因素来进行选择。以下是一些常见的负载均衡算法:
以上是一些常见的递归服务器的负载均衡算法,实际应用中可以根据具体的情况选择不同的算法。
现代浏览器还引入了 DNS 预解析(DNS prefetching)技术,可以在页面加载时自动解析该页面中可能需要的 DNS 记录,以便在用户点击链接时可以更快地打开页面。这种技术可以有效地减少 DNS 查询时间。
具体来说,当浏览器遇到页面中的链接或资源(如图片、样式表、脚本等)时,会自动进行DNS预解析。这样,在用户点击链接或浏览到相关资源时,域名已经被解析,可以更快地获取到数据,提升用户体验。
DNS预解析的原理是通过浏览器的解析器在后台进行DNS查询并缓存结果,以减少DNS查询的延迟。当浏览器发现一个可能需要进行DNS查询的链接或资源时,它会自动在后台发起DNS查询并缓存结果。如果用户后续访问同一域名下的其他资源,浏览器就可以直接使用缓存的DNS结果,而无需再次进行DNS查询。
例如,当浏览器遇到以下HTML代码时(<a>标签默认开启DNS预解析):
<a href="https://www.example.com">Example</a>
浏览器就会自动进行DNS预解析,向DNS服务器查询http://www.example.com的IP地址,并将结果缓存下来。当用户点击链接后,浏览器就可以直接使用缓存的DNS结果,而无需再次进行DNS查询。
需要注意的是,DNS预解析虽然可以提高页面加载速度和性能,但也会增加网络负载和DNS服务器的负担。考虑到实际需求,一般都不会去禁止DNS预解析,也不会出现很多需要预解析多个域名的情况。