写点什么

网络协议之:Domain name service DNS 详解

作者:程序那些事
  • 2022 年 4 月 13 日
  • 本文字数:4272 字

    阅读完需:约 14 分钟

网络协议之:Domain name service DNS详解

简介

现在是互联网的世界,大家从各种网站中获取各类资源和信息,通常我们只需要牢记一个网站地址即可,至于这个网站后台的服务器在什么地方,我们并不需要关心。当我们的请求指向这个网址之后,接下来就只需要等待请求被转发到该网址的后端服务器上,得到返回的处理结果即可。


这个将网站名称解析成为服务 IP 地址的服务就是 DNS 服务,它的全称是 Domain Name System,也就是域名解析服务。


那么 DNS 到底是怎么工作的呢?


有聪明的小伙伴可能会说了,那还不简单,搞一个统一的服务器,把世界上所有的域名对应的 IP 都存起来,每次需要解析的时候从这个服务去取就行了。确实,在互联网的初期就是这么干的,那时候网站还不多,域名维护的成本还不高,并且最开始还没有域名系统。


作为互联网的技术基础的 ARPANET(The Advanced Research Projects Agency Network)是第一个具有分布式控制的广域分组交换网络,也是最早应用 TCP/IP 协议的网络设施。


在 ARPANET 网络中,每个主机都有一个数字地址,但是这个数字地址明显是反人类记忆模式的,所以科学家们希望能够给这些主机起一些好记的名字,那么就需要维护这些名字和主机之间的映射关系,在这个时候斯坦福研究所(现在被称为 SRI International)接下了这个任务,他们维护了一个 HOSTS.TXT 的文本文件,在这个文件中描述了主机地址和主机名字之间的映射关系。


如果有人想要更新这个 HOST 文件,那么需要在工作时间打电话给 SRI 网络信息中心,由信息中心的工作人员将主机名和地址添加到 HOSTS.TXT 文件中。当然这样的操作对少量的数据更新来说还可以,但是如果数据量太大的情况下就有问题了。


后面一个叫做 Elizabeth Feinler 的人在 SRI 网络信息中心的基础上搭建了 WHOIS 目录,用于检索有关资源、联系人和实体的信息,并且提出了域名的概念.


最开始的维护都是在一个单一的服务器上进行集中式管理,但是这种维护方式已经不能够满足日益增长的网络需求,于是在 1983 年 Paul Mockapetris 在南加州大学创建了 DNS 系统,并在 1983 年 11 月于 RFC 882 和 RFC 883 发布了相关的原始规范。


后面 DNS 经过一系列的发展,于 1987 年 11 月,RFC 1034 和 RFC 1035 取代了 1983 年的 DNS 规范。

DNS 的功能

前面我们也提过了,DNS 最基本的作用就是将用户提供的域名转换成为服务器的地址。


比如我们现在有个域名叫做 www.flydean.com,它对应的服务器 IPv4 地址是 42.138.111.201,对应的 IPv6 地址是 fe40::1024:ff:fe10:123f,DNS 要做的工作就是将 www.flydean.com 根据需要快速的转换成为 IPv4 或者 IPv6 地址。这是 DNS 的第一个功能也是最重要的功能:提供域名的解析服务。


另外,在具体的应用场景中,域名背后对应的服务器 IP 可能是会变化的,那么就需要 DNS 有快速更新的功能,可以快速反映网络的变化情况,而不影响具体用户的访问。


这种操作对用用户来说是友好的,因为用户不需要知道底层服务器的变化,他们只需要知道要访问的域名即可。


最后,现代的网络应用一般都是分布式的,可能会有多个工作节点,不同的工作节点可能会被部署在不同的地方。用户在访问一个域名的时候,为了提升访问速度,应该优先访问离用户最近的那个节点。这时候 DNS 又承担了优化网络访问的任务,它负责向用户提供最近的服务器节点,所以在现代网络架构中,DNS 的作用越来越大。

DNS 的组成

讲解完 DNS 的功能之后,让我们来看看 DNS 的组成,作为一个域名服务,DNS 是由域名空间和 Name servers 两部分组成的。


域名空间描述的是域名的结构和命令规则,而 Name servers 则是对域名进行解析的服务。接下来我们分别进行讲解。

域名空间 Domain name space

域名空间,也叫做 Domain name space,它是所有域名的集合。下面是维基百科上的域名空间的示意图:


<img src="https://img-blog.csdnimg.cn/a4ada5191a6d4889aa54edb5a3a2e148.png" style="zoom:67%;" />


从上图可以看出,域名空间其实是一个树形结构,每个节点或者叶子节点都有一个 label 和 RR(esource records 记载着和域名相关的有用信息),域名本身由 label 组成,右边是其父节点的名称,用点分隔。


域名空间可以被划分为多个子空间,每个子空间可以单独进行管理,这样的子空间叫做一个域(zone)。


每个 DNS 域又可以被划分为一个域,也可能包含许多域和子域,具体取决于域管理器的管理选择。


大家对域名都很熟悉了,但是大家可能不是很明白域名的构成。


事实上域名是由 label 组成的,各个 label 是以点连接起来的,比如:www.flydean.com。


每个 label 都可以看做是域的一个层级,最右边是顶级域名 com,左边的是右边域名的子域名,比如 flydean 是 com 的子域名,www 是 flydean.com 的子域名,以此类推,总共可以有 127 个层级结构。


每个 label 可以包含 0 到 63 个字符,总共的域名长度不能超过 253 个字符。为什么是 253 个字符而不是 255 个字符呢?那是因为有 2 个字符是用来存储长度值的。


一般来说域名的标签是以 ASCII 字符表示的,通常使用 a-z,A-Z,0-9 和连字符来表示,这种规则简称为 LDH(letters, digits, hyphen)规则。


在域名中,字符串是大小写不敏感的,这就意味着 www.flydean.com 和 WWW.FLYDEAN.COM 是等价的。


注意,标签不能以连字符开头或者结尾,并且顶级域名不能全为数字。


有朋友可能会问了,不对呀,为什么我听过中文域名呢?


这是因为为了解决域名只能使用 ASCII 编码的问题,ICANN 通过了一个叫做 IDNA 国际化域名的系统,通过这个系统,用户应用程序(例如 Web 浏览器)可以使用 Punycode 将 Unicode 字符串映射到有效的 DNS 字符集。


什么是 Punycode 呢?Punycode 是一种使用 ASCII 字符集来表示 Unicode 的编码方式。感兴趣的同学可以自行探索,这里就不细讲了。

Name servers

name servers 也被称为名称服务器,是用来解析域名的服务器。名称服务器是一种客户端-服务器的架构,每个名称服务器用于发布有关该域的信息以及管理从属于它的任何域的名称服务器。


这样的名称管理器就构成了层级结构。为了提升域名解析的效率,通常会需要使用缓存来存储域名和服务器地址的对应关系,但是有时候我们需要时效性更高的场景和服务,于是出现了一种特殊的名称服务器,这种服务器叫做权威名称服务器。


为什么叫权威名称服务器呢?这是因为权威名称服务器仅从由原始来源配置的数据中给出 DNS 查询的答案,而不是通过对另一个名称服务器的查询获得的结果。它是域名服务器查询中的最后一站,如果权威名称服务器中保存有请求的记录,则其会将已请求主机名的 IP 地址返回到发出初始请求的 DNS 解析器.

DNS 的工作流程

上面讲了那么多概念性的东西,大家可能会有些懵。 没关系,这里我们举一个具体的例子来观察一下 DNS 查询的整个流程。


假如用户在浏览器中输入 www.flydean.com 想访问这个网站,因为用户输入的是一个域名,所以需要将域名解析成为 IP 地址,从而发送后续的数据请求包。


因为 DNS 本身是一个名称服务,所以需要一个客户端来请求 DNS,这个客户端就叫做 DNS 解析器。


一般来说 DNS 解析器是嵌入在浏览器中的,当用户输入 URL 来访问网络资源的时候,浏览器会自动调用 DNS 解析器去对这个 URL 进行解析。


那么域名解析的第一站是哪里呢?域名解析的第一站就是根服务器,也叫 root 服务器。


域名解析的请求由 root 服务器首先响应,但是 root 服务器并不会直接返回用户要解析的域名地址,而是根据用户访问的域名中的顶级域名的不同,返回顶级域名服务器(TLD)的地址。


比如这里我们要访问的定义域名是.com,那么 root 服务器会返回.com 的顶级域名服务器的地址。


root 服务器有多少个呢?世界上的 root 服务器 IP 地址只有 13 个,这是由于早期技术原因的限制导致的。这 13 个 root 服务器的 IP 地址中,1 个为主 root 地址,这个地址是由 ICANN 负责管理的,其他 12 地址中 9 个在美国,2 个在欧洲,1 个在日本。


虽然 root 根服务器 IP 只有 13 个,但是基于这 13 个 IP 地址构建了一个服务器集群,可以有效的保证根服务器的运行稳定性。从而不至于出现根服务器不能访问导致的大规模网络错误。


回到我们的解析过程,root 服务器把.com 顶级域名服务器的地址返回给了 DNS 解析器,DNS 解析会再次向.com TLD 发起解析查询。


.com TLD 会再次返回 flydean.com 的域名服务器地址给 DNS 解析器。


DNS 解析器再次发送请求给 flydean.com 的域名服务器,这里的域名服务器是一个权威域名服务器,因为这里是域名解析的最后一站,存放着域名的真实 IP 地址,权威域名服务器经过查询得到 www.flydean.com 的真实 IP 地址,并返回给 DNS 解析器。


最后 DNS 解析器将这个 IP 地址返回给浏览器,供后续的浏览请求使用。


可以看到 DNS 解析是一个不断递归解析的过程,所以这样的解析器又被称为 DNS 递归解析器。


从上面的流程可以看到,每次域名的请求都需要经过 root 域名服务器,那么这样 root 域名服务器的压力会很大,为了解决这个问题,事实上我们在使用的过程中引入了 DNS 缓存。


缓存的目的就是将 DNS 数据放到离自己最近的地方,从而提示数据的处理速度和展示效率。


常见的 DNS 缓存有浏览器缓存和操作系统 DNS 缓存。


浏览器缓存就是由浏览器负责维护的 DNS 缓存,而操作系统 DNS 缓存是操作系统级的 DNS 缓存。


如果这两个缓存都不存在的话,那么本地的 DNS 客户端会将 DNS 查询发生到 ISP(Internet 服务提供商)内部的 DNS 递归解析器,对于 ISP 来说,它也会存在 DNS 缓存,所以如果新增一个域名或者更改一个 IP 地址,并不是马上生效的,而是需要等待一定的时间来让缓存失效或者缓存刷新。

DNS 资源记录

前面我们提到了 DNS 命名空间中每个节点都是有 label 和 resource records (RR)组成的,RR 存储着资源的描述信息,会在收到 DNS 查询之后返回。


DNS RR 是由一条条的 record 构成的,下面是一条 record 的结构:



其中 NAME 是树中节点的完全限定域名。


TYPE 是记录类型。它表示数据的格式和用途,比如 A 表示用于将域名转换为 IPv4 地址,NS 表示列出了哪些名称服务器可以响应 DNS 的域查找,MX 表示指定用于处理指定域的邮件的邮件服务器在电子邮件地址中。


RDATA 是特定类型相关的数据,例如地址记录的 IP 地址,或 MX 记录的优先级和主机名。

DNS 消息的结构

既然有 DNS 查询,那么就会有 DNS 查询的消息结构,DNS 消息可以分为两种,分别是查询消息和回复消息。


每一个 message 都包含了一个消息头和四个其他部分:question, answer, authority 和额外空间。


header 负责控制其他的 4 个部分,header 包含了这样几个字段: Identification, Flags, Number of questions, Number of answers, Number of authority resource records (RRs)和 Number of additional RRs, 如下表所示:



整个头的标记字段长度是 16bits,紧跟着 4 个 16bits,分别表示 4 个其他部分的长度。

总结

以上就是 DNS 的结构和 DNS 工作的基本流程。


本文已收录于 http://www.flydean.com/19-domain-name-service/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

发布于: 刚刚阅读数: 2
用户头像

关注公众号:程序那些事,更多精彩等着你! 2020.06.07 加入

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧,尽在公众号:程序那些事!

评论

发布
暂无评论
网络协议之:Domain name service DNS详解_Java_程序那些事_InfoQ写作平台