DNS 的工作原理

因为主机的 IP 地址不便于记忆,所以人们常用主机名来标识主机。而对于路由,则是使用定长的、有层次结构的 IP 地址。

因为需求之间的矛盾,这就需要一种目录服务,能够提供主机名到 IP 地址映射的查询服务。这就是 域名系统 (Domain Name System, DNS) 所提供的服务。

(Q1)DNS 是什么呢?

一般我们提到 DNS 的时候,指的是 DNS 服务器;有时候指的是 DNS 协议。DNS 服务器能够处理 DNS 报文,进而提供查询服务。

下面详细介绍一下

  • DNS 记录
  • DNS 服务器的体系结构
  • DNS 协议的原理
  • DNS 服务器提供查询服务的工作流程
  • DNS 缓存

DNS 记录

(Q2)host 和 IP 的关系在 DNS 服务器中是以怎样的形式被记录的?

DNS 服务器存储了资源记录(RR),提供了主机名到 IP 地址的映射。每个 DNS 回答报文包含了一条或多条资源记录。

资源记录是一个 4 元组: (Name, Value, Type, TTL)

  • Name 和 Value 的值取决于 Type

  • Type 有多种:(各个类型的详细介绍参考 DNS Resource Records )

    • A记录: 将 host 解析到指定的 IPv4 地址

    • AAAA记录:将 host 解析到指定的 IPv6 地址

    • CNAME记录:别名记录,将域名解析到另外一个域名。可以用于将不同域名都转到一个域名记录上,由这个域名记录统一解析管理

    • NS记录:域名服务器记录,用来指定该 host 由哪个 DNS 服务器来进行解析

    • MX记录:邮件服务器地址,它指向一个邮件服务器,用于电子邮件系统发邮件时根据收信人的地址后缀来定位邮件服务器

    • PTR记录:反向解析记录,是一个指针记录,用于将一个IP地址映射到对应的主机名,也可以看成是A记录的反向

  • TTL 是该记录的生存时间,它决定了资源记录应该从缓存中删除的时间

DNS 服务器的体系结构

在说 DNS 的体系结构之前,先想想(Q3)为什么 DNS 服务器是一个分层的分布式结构,全球只使用一个 DNS 服务器会有什么问题?

如果因特网上只是用一个 DNS 服务器,该服务器包含所有的映射。客户端直接往这个 DNS 服务器上查询,同时该 DNS 服务器直接对所有的查询客户做出响应。这样中集中式设计会出现下面几种问题:

  • 单点故障: 如果该 DNS 服务器崩溃,整个因特网将崩溃
  • 通信容量太大: 单个 DNS 服务器没法为上亿台主机提供查询服务
  • 远距离带来的延时: 全球的主机都将与这个 DNS 服务器进行通信,有些地方距离这个服务器很远,中间也许还要经过低俗和拥塞的链路,这将导致严重延时
  • 维护成本过高: 这个服务器记录的数据非常庞大,而且更新频繁,难以维护

从实际角度出发,单个的 DNS 服务器设计是不合理的。
为了满足需求,DNS 服务器应该是分布式的体系结构,分布在各个地区;且根据域名,它是一个分层的结构

DNS 体系结构

用一个图来解释 DNS 的体系结构

原图

在 DNS 的层次结构中,根据域名结构分为三类的 DNS 服务器,它们分布在全球各个地方,由各个组织进行管理:

  • 根 DNS 服务器
    • 提供顶级域(TLD) 服务器的 IP 地址
    • 有 400 多个根名字服务器,由 13 个不同的组织管理
  • 顶级域(TLD) 服务器
    • 提供了权威 DNS 服务器的 IP 地址
    • 对于每个顶级域和所有国家顶级域,都由一个专门的组织进行管理该顶级域名服务器下注册的二级域名
  • 权威 DNS 服务器
    • 在因特网上具有公共可访问主机的每个组织机构必须提供公共可访问的 DNS 记录
    • 这些记录保存在组织自己的权威 DNS 服务器上

还有一种 DNS 服务器不在层次结构中————本地 DNS 服务器:对于每一个局域网,都有一台本地 DNS 服务器,当客户发出 DNS 查询请求的时候,先会发给本地 DNS 服务器,再由它将该请求转发到 DNS 服务器各个层次结构中

在查询过程中,这几类 DNS 服务器之间的交互过程是怎么样的?对于这个问题,我们留到最后再讨论

DNS 协议的原理

DNS 报文

DNS 有两种报文: 查询报文和回答报文

它们有着相同的格式:

含义
首部区域 标识符: 用于标识该查询,这个标识符会被复制到回答报文中,以便让客户用它来匹配发送的请求和接收到的回答;

标志:有若干个标志
(1) QR: 查询/响应标志,0为查询,1为响应;
(2) opcode: 0 表示标准查询,1 表示反向查询,2 表示服务器状态请求;
(3) AA: 表示授权回答;
(4) TC: 表示可截断的;
(5) RD: 表示期望递归;
(6) RA: 表示可用递归;
(7) rcode(应答码 response code): 0 没有差错,1 报文格式错误,2 服务器错误,3 名字错误 (解析的域名不存在),4 没有实现 (域名服务器不支持查询类型),5 拒接 (服务器由于设置的策略拒接给出应答) ;

问题数

回答 RR 数

权威 RR 数

附加 RR 数
问题区域 包含正在进行的查询信息,包括:
(1) 名字字段,包含正在被查询的主机名字
(2) 类型字段,指出有关该名字的正被查询的问题类型
回答区域 包含了对请求的名字的资源记录,包括资源记录里的 Type 字段,Value 字段和 TTL 字段
在回答报文的回答区域中可以包含多条 RR,因此一个主机名能够有多个 IP 地址
权威区域 包含了其他权威服务器的记录
附加区域 包含了其他有帮助的记录

基于 UDP 的 DNS 协议

DNS 服务主要是基于 UDP 实现的,原因在 DNS 数据包一般来说是小数据,使用 UDP 不需要考虑分包,如果丢包就全丢;在不担心传输质量的情况下,使用 UDP 的传输效率明显高于 TCP

但当数据长度大于 512 字节的时候,为了保证传输质量,会使用基于 TCP 的实现方式

DNS 服务器提供查询服务的工作流程

  • 第一步:主机向本地域名服务器发出一个 DNS 请求报文,报文里携带需要查询的域名
  • 第二步:
    • 主机向本地域名服务器进行递归查询
    • 本地域名服务器采用迭代查询向一个根域名服务器进行查询
    • 根域名服务器告诉本地域名服务器,下一次应该查询的顶级域名服务器的 IP 地址
    • 本地域名服务器向顶级域名服务器进行查询
    • 顶级域名服务器告诉本地域名服务器,下一次应该查询权威服务器的 IP 地址
    • 权威域名服务器告诉本地域名服务器所查询的主机的IP地址
    • 本地域名服务器最后把查询结果告诉主机

这里有两种查询方式

  • 递归查询:
    • 主机向本地域名服务器发起一次查询请求,就静待最终的结果
    • 如果本地域名服务器无法解析,自己会以 DNS 客户机的身份向其他域名服务器进行查询,直到最终的 IP 地址告诉本机
  • 迭代查询:
    • 本机域名服务器向根域名服务器查询,根域名服务器告诉它下一步到哪里去查询,然后它再去查,每次它都是以客户机的身份去各个服务器查询

DNS 缓存

在 DNS 查询服务过程中,为了提升域名查询效率,设计了域名缓存机制:当访问过某个网站并得到其 IP 后,会将其域名和 IP 缓存下来,下一次访问的时候,就不需要再请求域名服务器获取 IP,直接使用缓存中的 IP,提高了响应的速度。

计算机中 DNS 记录在本地有两种缓存方式:浏览器缓存和操作系统缓存;在其他 DNS 服务器上也同样有缓存

用户在浏览器中访问的时候,会优先访问浏览器缓存,如果未命中则访问 OS 缓存,最后再访问递归 DNS 服务器

要注意因为浏览器不直接与 DNS 服务器通信,所以浏览器中的缓存时间与 RR 中的 TTL 没有关系

注:本节内容建立在《计算机网络:自顶向下方法》的理解之上,如果错误,欢迎指正

同时参考了以下文章:

  1. 为什么DNS适合使用UDP协议而不是TCP协议?
  2. https://bbs.huaweicloud.com/blogs/8b592f4dd64011e7b8317ca23e93a891

感谢以上书和文章的作者~