摘要:DNS(Domain Name System)是域名系统的英文缩写,是一种组织成域层次结构的计算机和网络服务命名系统,用于 TCP/IP 网络。
本文分享自华为云社区《DNS 那些事 —— 从浏览器输入域名开始分析 DNS 解析过程》,作者: 砖业洋__ 。
我们就从在浏览器输入域名开始分析。
1. 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 包括 .com (商业企业) .org .net .edu .gov (美国政府实体),IANA 过去曾严格限制新通用顶级域 (gTLD) 的创建,但在 2010 年这些限制有所放松。现在有数百个不太知名的 gTLD,例如 “.top”、“.xyz” 和 “.loan”。
- 国家 / 地区代码顶级域:这些包括特定于某个国家 / 地区或州的任何域。例如,.cn、.uk、.us、.ru 和 .jp 等。
- 赞助的顶级域:这些 TLD 通常代表专业、种族或地理社区。每个赞助 TLD 都有一个代表该社区的授权赞助商。例如,“.app” 是针对开发者社区的 TLD,由 Google 赞助。同样,“.gov” 旨在供美国政府使用,由总务管理局赞助。
- 基础设施性顶级域:此类别仅包含一个 TLD:“.arpa”。“.arpa” 以帮助开创现代互联网的美国军事研究组织 DARPA 命名,是有史以来创建的第一个 TLD,现在保留用于基础设施职责,例如促进反向 DNS 查找。
- 保留的顶级域:一些 TLD 位于保留列表中,这意味着它们永远无法使用。例如,“.localhost” 保留用于本地计算机环境,“.example” 保留用于示例演示。
- 权威性域名服务器:
当递归解析器收到来自 TLD 域名服务器的响应时,该响应会将解析器定向到权威性域名服务器。权威性域名服务器通常是解析器查找 IP 地址过程中的最后一步。
2. 从浏览器输入 https://abc13.ban2.lcy0000.top/,DNS 如何解析?
放一张 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)。
3. hosts 文件是什么?为什么访问网站会先查找 hosts 文件?
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/ 目录下。
4. 如何查看本地 DNS 服务器缓存的域名对应的 IP?
windows 可以用下面命令
ipconfig /displaydns
mac 可以用下面命令
// 这个是刷新本地 DNS 缓存,并清除所有缓存记录
sudo killall -HUP mDNSResponder
// 这个是显示本地 DNS 服务器缓存的所有域名和对应的 IP 地址
dscacheutil -cachedump -entries Host
执行了这个命令却没看到我刚访问的域名对应的 ip,这是没缓存吗?
如果执行了 ipconfig /displaydns 或者 dscacheutil -cachedump -entries Host 命令,但是没有看到刚访问的域名对应的 IP 地址,可能有以下几种情况:
- 本地 DNS 服务器没有缓存该域名的 IP 地址。如果你第一次访问一个域名,本地 DNS 服务器很可能没有缓存该域名的 IP 地址。在这种情况下,执行 ipconfig /displaydns 或者 dscacheutil -cachedump -entries Host 命令时,看不到该域名的缓存记录。
- 本地 DNS 服务器缓存的 TTL 时间已经过期。当你访问一个域名时,本地 DNS 服务器会将该域名的 IP 地址缓存一段时间,这个时间就是 TTL(Time To Live)时间。如果 TTL 时间已经过期,本地 DNS 服务器就会从权威 DNS 服务器重新获取该域名的 IP 地址。在这种情况下,执行 ipconfig /displaydns 或者 dscacheutil -cachedump -entries Host 命令时,可能看不到该域名的缓存记录。
- 你的电脑可能使用了其他 DNS 服务器或者代理服务器。如果你的电脑使用了其他 DNS 服务器或者代理服务器,那么执行 ipconfig /displaydns 或者 dscacheutil -cachedump -entries Host 命令时,缓存记录可能来自其他 DNS 服务器或者代理服务器,而不是本地 DNS 服务器。
5. DNS A 记录 / AAAA 记录 / CNAME 记录
- A 记录
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 记录
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 记录
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 前缀来访问网站了。
6. 为什么输入 baijiahao.baidu.com 可以访问,加上 www. 之后变成 www.baijiahao.baidu.com 就无法访问?
一般来说,两个域名的 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
记录。
7. 在浏览器输入 abc.coc 这种不符合规范的域名后,执行过程是怎样的?
假设输入的域名是 abc.coc,这个域名显然不符合域名规范,应该是 http://abc.com 或 http://abc.cn 等等。
首先,本地和递归 DNS 服务器会检查 DNS 缓存是否存在该域名的解析记录,由于这是一个不存在的域名,本地和递归 DNS 服务器缓存中肯定没有相关记录,因此会向根域名服务器发送查询请求。
根域名服务器无法解析该域名,因为 .coc 不是一个合法的顶级域名,因此根域名服务器会返回一个 “域名不存在” 的错误信息给递归 DNS 服务器。
递归 DNS 服务器收到根域名服务器的响应后,会将 “域名不存在” 的错误信息返回给客户端,客户端显示无法解析该域名。
需要注意的是,由于 abc.coc 不符合域名规范,大部分浏览器或操作系统会在输入时就进行格式校验,当输入的字符串无法被识别为域名,就会变成搜索操作。
8. DNS 解析是 TCP 还是 UDP?
DNS 解析使用的是 UDP 协议,因为 DNS 查询通常只需要发送小量的数据,而 UDP 协议是无连接、不可靠的,但是比 TCP 更快速和轻量级。当然,对于一些特殊情况下的 DNS 解析,也可能使用 TCP 协议,比如 DNS 数据包超过了 UDP 报文最大长度时,会使用 TCP 进行分片传输。如果 DNS 查询包的大小超过 512 字节,或者查询返回的响应包的大小超过 512 字节,则必须使用 TCP 协议。
9. 权威域名服务器中的循环 DNS
为了提高服务的可靠性和可用性,通常会部署多台相同配置的 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 解析请求。
10. 解决循环 DNS 的缺点 ——DNS 负载均衡技术
- DNS 负载均衡技术
可以用负载均衡来分配 DNS 查询请求到不同的 DNS 服务器上,以实现负载均衡。这些 DNS 服务器可以根据请求的源 IP 地址、地理位置或者其他特定条件来分配权重,进行筛选最优的服务器,从而避免单个权威 DNS 服务器承受过多的请求压力。如果其中一台 DNS 服务器出现问题,系统会自动将它从轮询列表中删除,从而确保之后客户端的请求不会被发送到不可用的 DNS 服务器上。
- Anycast 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 地址的性能、可用性、距离等因素来进行选择。以下是一些常见的负载均衡算法:
- 轮询算法:递归服务器按照固定的顺序依次轮询选择 IP 地址返回给客户端,确保每个 IP 地址都能够得到平均的请求量。比如:第一次返回 IP1,第二次返回 IP2,第三次返回 IP3,第四次返回 IP1,以此类推。
- 随机算法:递归服务器随机选择一个 IP 地址返回给客户端,确保每个 IP 地址都有一定的机会被选择到。
- 带权重的轮询算法:为了解决某些 IP 地址性能更高或者负载更轻的问题,递归服务器会给每个 IP 地址分配一个权重,轮询时会优先选择权重高的 IP 地址。比如:IP1 的权重为 3,IP2 的权重为 2,IP3 的权重为 1,则轮询顺序为 IP1、IP1、IP1、IP2、IP2、IP3。
- 最少连接数算法:递归服务器会记录每个 IP 地址当前的连接数,优先选择连接数最少的 IP 地址返回给客户端。这种算法适用于负载均衡服务器的场景。
- IP 地址哈希算法:递归服务器会根据客户端 IP 地址的哈希值选择一个 IP 地址返回给客户端。这种算法适用于需要固定客户端访问同一个服务器的场景。
以上是一些常见的递归服务器的负载均衡算法,实际应用中可以根据具体的情况选择不同的算法。
11. DNS 预解析(DNS prefetching)技术
现代浏览器还引入了 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 预解析,也不会出现很多需要预解析多个域名的情况。