DNS
一、认识
DNS
(Domain Name System
,域名系统) 是互联网的基础服务之一,主要负责将人类易于记忆的域名转换为计算机网络中实际使用的 IP
地址。通过域名获取对应IP
地址的过程称为 域名解析, 也叫 DNS
解析。
二、DNS 解析
当用户在浏览器中输入一个域名时,系统需要知道对应的服务器 IP
地址, DNS
采用了分布式、分层的架构,通过多个服务器协同工作来完成解析。每个域名记录都有一个 TTL
(Time To Live
)值,表示该记录在缓存中可保存的时间,以减少重复查询的负担。解析过程如下:
本地缓存查询: 首先检查浏览器缓存中是否有该域名对应的 IP
缓存记录。如果浏览器没有命中,会查询操作系统的 DNS
缓存。在某些场景下, 操作系统还会首先查找本地的 hosts
文件,该文件可以将特定域名映射到预定义 IP
。如果缓存中存在且未过期,则直接返回结果,无需向外部 DNS
服务器发起查询。如果本地缓存没有命中, DNS
会通过递归查询或者迭代查询来获取最终的 IP
地址或错误信息。递归查询或者迭代查询各有优势。
2.1 递归查询
递归解析器 Resolver
递归查询: 如果本地缓存中未命中,客户端会将解析请求发送给配置好的递归 DNS
服务器(通常由 ISP
提供或用户手动配置,例如 Google 的 8.8.8.8
)。递归解析器代表客户端发起后续的查询过程,负责与其他 DNS
服务器通信,直到找到权威答案为止。解析器会将查询结果缓存,以便下次快速响应同样的请求。客户端与解析器的关系: 客户端(比如操作系统或浏览器) 将整个 查询 请求交给 递归解析器,后者负责代表客户端完成整个解析过程,直至返回最终结果。查询流程 递归解析器接到请求后,会依次向根服务器、顶级域服务器和权威服务器发起查询。对于每一级 DNS
服务器的响应,解析器会自动发起下一步查询,直到获取最终的 IP
地址或错误信息。递归查询 中,解析器承担所有查询工作,客户端只发起一次请求, 递归查询更适用于大部分实际应用,因为它利用缓存和集中处理提高效率。
-
查询根域名服务器, 递归解析器首先向根域名服务器发起查询。根服务器不保存具体的
IP
地址,而是返回负责管理该顶级域(如.com
、.or
g、.cn
等)的顶级域(TLD
)服务器的地址。全球目前有13
组逻辑上的根服务器(通过多个实例分布在世界各地),确保了整个DNS
系统的冗余与高可用性。 -
查询顶级域服务器, 解析器根据根服务器返回的信息,向相应的顶级域服务器查询。顶级域服务器会返回负责管理该域名的权威
DNS
服务器地址。这一步骤将查询范围缩小到具体域名管理者控制的服务器上。 -
查询权威
DNS
服务器, 递归解析器最终向权威DNS
服务器发起查询。权威服务器保存了域名的最终记录(如A
、AAAA
、CNAME
等),并将对应的IP
地址返回给解析器。如果查询成功,权威服务器返回具体的IP
地址; 如果不存在,则返回相应的错误(如NXDOMAIN
,表示该域名不存在)。 -
结果缓存与返回, 解析器会将查询到的结果在
TTL
指定的时间内缓存起来,降低后续相同请求的查询延时。最终,递归解析器将解析结果返回给用户的浏览器,浏览器再使用这个IP
地址与目标服务器建立连接,进行后续的HTTP
或HTTPS
通信。
2.2 迭代查询
迭代解析器查询: 客户端与服务器的关系, 在迭代查询中, 客户端(通常用于调试或部分特定应用场景)直接与各级 DNS
服务器进行交互。查询流程, 客户端首先向根服务器发起请求,根服务器返回一个指向顶级域服务器的引用(地址)。客户端根据返回的信息,接着向顶级域服务器查询,再由顶级域服务器返回权威服务器地址,最后客户端向权威服务器查询获取最终的 IP
地址。每一步都是客户端主动发起查询,并根据服务器的 推荐 信息自行决定下一步。迭代查询中, 客户端需要逐级进行查询,完全控制查询过程。迭代查询则在调试和教学中更常见,能直观展示 DNS
系统的分层架构。
三、DNS 负载均衡
首先我们得知道DNS是可以用于在冗余的服务器上实现负载平衡。
原因: 这是因为一般的大型网站使用多台服务器提供服务,因此一个域名可能会对应 多个服务器地址。
- 当用户发起网站域名的 DNS 请求的时候,DNS 服务器返回这个域名所对应的服务器 IP 地址的集合
- 在每个回答中,会循环这些 IP 地址的顺序,用户一般会选择排在前面的地址发送请求。
- 以此将用户的请求均衡的分配到各个不同的服务器上,这样来实现负载均衡。
四、DNS 存在的问题
4.1 DNS 查询时延
一次完整的 DNS 查询过程需要访问多台 DNS 服务器才能得到最终的结果,这肯定会带来一定的时延。从实践来看,这个时间还不容小觑。
4.2 缓存一致性
DNS 缓存的存在虽然减少了时延,却是以牺牲一致性(consistency)为代价的。具体来说:Local DNS 是分地区、分运营商的,在域名解析缓存的处理上,实现策略就不统一了。有时候 Local DNS 的解析结果 可能不是最近、最优的节点,有的时候并不会遵从 TTL 的限制,而是设置一个固定时间。这就会导致域名指向新的 IP 地址后,一些客户端依然访问了缓存中 旧的 IP 地址。 除了运营商的缓存策略外,缓存投毒也是降低 DNS 可用性的原因。攻击者可以通过 DNS 劫持,利用 DNS 的缓存机制不对应答数据做检查的漏洞,诱骗 DNS 服务器缓存较大 TTL 的虚假 DNS 记录,从而长期欺骗客户端。
4.3 DNS 劫持(中间人攻击)
由于 DNS 缺乏 加密、认证、完整性保护的安全机制,容易引发网络完全问题。最常见的域名劫持攻击是针对 DNS 报文首部的 事务 ID 进行欺骗,由于事务 ID 在查询报文和应答报文中是匹配的,因此伪装 DNS 服务器可以提前将事务 ID 相同的伪造报文发送到客户端,以实现域名劫持(前提是合法的报文还未到达),把目标网站域名解析到错误的 IP 地址。
由于DNS劫持或故障造成的服务不可用,进而影响用户体验
4.4 调度不精准问题
由于存在缓存、转发、NAT 等问题,权威的 DNS 服务器可能会误判客户端所在的位置和运营商,从而导致解析出跨运营商访问的 IP 地址,用户的访问速度降低。
由于DNS调度不准确导致的性能退化,进而影响用户体验
五、问题
5.1 什么是 DNS?
5.2 DNS 解析过程?
5.3 如何加快 DNS 的解析?
加快 DNS
解析主要是通过减少查询延迟和提高命中率来实现。以下是几种常见方法:
一、本地缓存: 1. 浏览器与操作系统缓存, 利用浏览器和操作系统自身的 DNS
缓存,可以避免重复查询。确保操作系统配置合理,增加缓存存储时间(TTL
)有助于命中率提升; 2. Hosts
文件, 对常用域名预先在 hosts
文件中配置映射,直接绕过外部查询。
二、使用快速稳定的递归 DNS
服务器: 1. 使用性能更好、响应更快的公共 DNS
服务(如 Google
的 8.8.8.8
、Cloudflare
的 1.1.1.1
),这能显著缩短首次查询的时间; 2. 部署本地递归解析器,尤其是在企业或大规模网络环境中,能够减少外部网络延迟。
三、DNS
预解析(DNS Prefetching
): 浏览器可以通过 <link rel="dns-prefetch" href="//example.com">
标签提前解析页面中可能用到的域名,从而在用户点击链接前就获得解析结果,减少后续延迟。
四、使用 CDN
与 Anycast
技术: 内容分发网络(CDN
)通常会在全球各地部署 DNS
服务器,通过 Anycast
路由技术将用户请求导向最近的服务器,这能大幅降低 DNS
查询时间。
五、优化 TTL
策略: 合理设置 TTL
值可以让缓存数据保持足够长的时间,但又不至于在资源更新时造成问题。较长的 TTL
值可以减少频繁查询,但更新时需要注意同步问题。
六、减少 DNS
重定向: 尽量避免使用过多 CNAME
记录,因为每次重定向都需要一次额外的 DNS
查询,增加整体延迟。