写在前面
最近有个同学后台私信让我出一个DNS的工作原理,面试的时候居然问到了,所以就简单聊聊DNS的工作原理吧!
1. DNS 的核心作用
DNS(域名系统,Domain Name System)是互联网中用于将人类可读的域名转换为机器可识别的 IP 地址的核心服务。
域名与 IP 的映射:DNS 本质上是一个分布式数据库,存储了域名与对应 IP 地址的映射关系。
2. DNS 的组成部分
- 域名空间(Domain Name Space):
以树状结构组织域名,例如:根域(.) → 顶级域(.com) → 二级域(sbnvidia.com) → 子域(www.sbnvidia.com)
- DNS 服务器:
- 递归解析器(Recursive Resolver):用户直接访问的服务器(如 ISP 提供的 DNS 或公共 DNS 如
8.8.8.8
),负责代替用户完成查询。 - 根域名服务器(Root Server):全球共 13 组,存储顶级域(如
.com
、.org
)的地址信息。 - 顶级域服务器(TLD Server):管理特定顶级域(如
.com
服务器存储所有以.com
结尾的域名信息)。 - 权威域名服务器(Authoritative Server):存储具体域名的 IP 地址(如
example.com
的权威服务器由域名所有者管理)。
- 递归解析器(Recursive Resolver):用户直接访问的服务器(如 ISP 提供的 DNS 或公共 DNS 如
- DNS 记录:存储域名相关信息的条目,常见类型包括:
- A 记录:域名到 IPv4 地址的映射。
- AAAA 记录:域名到 IPv6 地址的映射。
- CNAME 记录:域名别名(如将
www.example.com
指向example.com
)。 - MX 记录:邮件服务器地址。
- NS 记录:指定管理域名的权威服务器。
这也是在我们域名解析的时候所需要了解的
3. DNS 解析流程
当用户在浏览器输入 www.sbnvidia.com
时,解析过程如下:
- 本地缓存查询:
- 浏览器检查自身缓存 → 若无,检查操作系统缓存(如
hosts
文件)。 - 若仍无结果,向递归解析器(如本地 DNS 服务器)发起请求。
- 浏览器检查自身缓存 → 若无,检查操作系统缓存(如
- 递归解析器处理:
- 递归解析器先检查自身缓存,若未命中,则从根域名服务器开始逐级查询:
a. 根域名服务器:返回.com
顶级域服务器的地址。
b. 顶级域服务器(.com):返回sbnvidia.com
的权威服务器地址。
c. 权威域名服务器:返回www.sbnvidia.com
的 IP 地址。
- 递归解析器先检查自身缓存,若未命中,则从根域名服务器开始逐级查询:
- 返回结果:
- 递归解析器将最终 IP 返回给用户设备,并缓存结果(根据记录的 TTL 时间)。
- 缓存层级:浏览器 → 操作系统 → 递归解析器均会缓存结果,减少重复查询。
- TTL(Time to Live):每条 DNS 记录设有时效性,超时后缓存失效,需重新查询。
4. 基于UDP 还是TCP?
UDP 在过去的几十年中其实都是 DNS 主要使用的协议,作为互联网的标准,目前的绝大多数 DNS 请求和响应都会使用 UDP 协议进行数据的传输,我们通过抓包工具就能轻松获得以 UDP 协议为载体的 DNS 请求和响应。
抓去 baidu.com 的DNS解析发现协议是UDP
但其实 DNS 使用了 UDP 来获取域名对应的 IP 地址,这个观点虽然没错,抓包抓出来也确实是这样,但是还是有一些片面,这仅仅只是验证了这种case是UDP,更加准确的说法其实是 DNS 查询在刚设计时主要使用 UDP 协议进行通信
,但 TCP 也是在 DNS 的演进和发展中被加入到规范的
那我们就要讲讲DNS的发展历史了:
- 1987 年的 RFC1034 和 RFC1035 定义了最初版本的 DNS 协议,刚被设计出来的 DNS 就会同时使用 UDP 和 TCP 协议,
对于绝大多数的 DNS 查询来说都会使用 UDP 数据报进行传输
,TCP 协议只会在区域传输
的场景中使用,其中 UDP 数据包只会传输最大 512 字节的数据,多余的会被截断; - 两年后发布的 RFC1123 预测了 DNS 记录中存储的数据会越来越多,同时也第一次显式的指出了发现 UDP 包被截断时应该通过 TCP 协议重试。
- 过了将近 20 年的时间,由于互联网的发展,人们发现 IPv4 已经不够分配了,所以引入了更长的 IPv6,DNS 也在 2003 年发布的 RFC3596 中进行了协议上的支持;
- 随后发布的 RFC5011 和 RFC6376 增加了在
鉴权和安全
方面的支持,但是也带来了巨大的 DNS 记录,UDP 数据包被截断变得非常常见。 - RFC6891 提供的 DNS 扩展机制能够帮助我们在一定程度上解决大数据包被截断的问题,减少了使用 TCP 协议进行重试的需要,但是由于
最大传输单元的限制
,这并不能解决所有问题。 - 在DNS出现的 30 多年后,RFC7766 才终于提出了
使用 TCP 协议作为主要协议来解决 UDP 无法解决的问题,TCP 协议也不再只是一种重试时使用的机制
。
参考
[1] https://draveness.me/whys-the-design-dns-udp-tcp/
[2] https://chat.deepseek.com/
[3] https://datatracker.ietf.org/doc/html/rfc7766