DNS 一点点的基础知识

153 阅读12分钟

参考

  • 《计算机网络自顶向下方法》
  • 《网络是怎样连接的》

本篇文章算是对学习 DNS 的一个总结,结合了这两本书的 DNS 篇章,所以会有些段落参考了这两本书的内容。这篇文章理论知识较多,看完其实还挺有兴趣的。

前言

我们经常会以很多种方式来标识,例如,在现实生活中我们经常以名字来为某个人进行标识;能够通过身份证号码来标识;甚至还可能通过外号来对某个人进行标识(哈哈哈)。但是在特定环境下,某种识别方式可能比另外一种方式更加合适。例如在购买火车票系统中,程序可能就是通过身份证号码进行作为唯一标识,而不是通过身份证上的名字标识。

DNS:互联网的目录服务

那么互联网上的主机和我们一样,也可以使用多种方式进行标识。主机的一种标识方法是用它的主机名,如 baidu.com,google.com 等,这些名字便于记忆也乐于被我们所接受。然而,主机名几乎没有提供关于主机所在互联网中位置的信息。况且,因为主机名可能由不定长的字母数字,甚至是现在的中文所组成,路由器很难处理。由于这些原因,主机也可以使用 IP 地址进行标标识。

域名和 IP 地址并用的理由

TCP/IP 是通过 IP 地址来确定通信对象,因此不知道对方的 IP 地址就无法将消息发送给对方,这和我们打电话一个道理,我们要和对方打电话时必须知道对方的电话号码。而域名你可以理解为通信录中的已保存的对方昵称。

其实,我们可以直接使用 IP 地址进行请求,这样也是可以的,但是, IP 地址由 4 字节的纯数字组成和电话码一样,我们很难记住。因此,相比 IP 地址来说,域名还是使用服务器名称比较好。

那么我们是否可以不用 IP 地址,直接域名可以吗,讲道理是可以的。那么我们如果不用 IP 地址而是改用域名会怎么样呢?IP地址的长度为 32 bit,也就是 4 字节,相对地,域名最短也要几十个字节,最长甚至可以达到 255 字节。换句话说,使用 IP 地址只需要处理 4 字节的数字,而域名则需要处理几十个到 255 个字节的字符,这增加了路由器的负担,传送数据也会花费更长的时间。所以使用域名来确定通信的对象并不是明智的选择。

所以现在的方案是让人来使用名称,让路由器来使用 IP 地址。

DNS基础服务工作

DNS 提供的服务

刚刚有介绍到识别主机有两种方式,通过主机名或者 IP 地址,我们喜欢便于记忆的主机名标识方式,而路由器则喜欢定长的、有层次结构的 IP 地址。为了折中这些不同的偏好,我们则需要一种能进行主机名到 IP 地址转换的目录服务,而这个服务既是域名系统(Domain Name System, DNS)

DNS 处理的过程

DNS 通常由其他应用层协议所使用的(所以 DNS 即处于网络七层模型中的应用层),包括 HTTP、SMTP 和 FTP,将用户提供主机名解析为 IP 地址。

举一个简单的例子,当我们在浏览器的地址栏中输入 baidu.com/index.html 后页面会发生什么呢?为了使用户的主机能够将一个 HTTP 请求报文发送到 Web 服务器 baidu.com/index.html,该主机必须获得 baidu.com/index.html 的 IP 地址,所以会经过这些过程:

  • 该用户主机运行着 DNS 的客户端
  • 浏览器从上述 URL 中抽取主机名 baidu.com,并将这台主机名传给 DNS 客户端
  • DNS 客户端向 DNS 服务器发送一个包含主机名的请求
  • DNS 客户端最终会收到一份回答报文,其中包含该主机名的 IP 地址,并告知浏览器
  • 浏览器接收到 DNS 的该 IP 地址,则立即向该 IP 地址的 80 端口的 HTTP 服务器进程发起一个 TCP 连接请求

DNS服务器的基本工作

前面介绍了客户端与 DNS 服务器之间的交互过程,那 DNS 服务器呢,DNS 服务器的基本工作就是接收来自客户端的查询消息,然后根据消息的内容返回响应。

其中,来自客户端的查询消息包含以下 3 种信息:

  • 域名:服务器、邮件服务器的名称
  • Class:在最早设计 DNS 方案时,DNS 在互联网以外的其他网络中的应用也被考虑到了,用于识别网络的信息,如今除了互联网并没有其他网络了,因此 Class 的值永远是代表互联网的 IN
  • 记录类型:标识域名对应何种类型的记录。例如:当类型为 A(Address) 时,表示域名对应 IP 地址;当类型为 MX (Mail eXchange)时,表示域名对应的是邮件服务器,对于不同的记录类型,服务器向客户端返回的信息也会不同。

DNS 服务器上事先保存有前面 3 种信息对应的记录数据,DNS 服务器就是根据这些记录查找符合查询请求的内容并对客户端进行响应的。

例如,如果要查询 baidu.com 这个域名对应的 IP 地址,客户端会向 DNS 服务器发送包含以下信息的查询消息

  • 域名=baidu.com
  • Class=IN
  • 记录类型=A

然后,DNS 服务器会从已有的记录中查询域名、Class 和记录类型全部匹配的记录。

DNS 提供其他重要的服务

除了进行主机名到 IP 地址的转换外,DNS还提供了一些重要的服务

  • 主机别名:程序可以调用 DNS 来获得主机别名对应的规范主机名以及主机的IP地址
  • 邮件服务器别名:邮件程序可以调用 DNS,对提供的邮件服务器别名进行解析,以获得该主机的规范主机名及其 IP 地址
  • 负载分配:DNS 也用于在冗余的服务器之间进行负载分配

域名的层次结构

在前面的介绍中,我们都是假设要查询的信息已经保存在DNS服务器记录中了,如果是向学校的内部网络这样 Web 和邮件服务器数量有限的环境中,所有的信息都可以保存在一台 DNS 服务器中,那么查询方式就很简单了,查询,返回就可以了。然而,互联网中存在着不计其数的服务器,将这些服务器的信息全部保存在一台 DNS 服务器中是不可能的,因此一定会出现在 DNS 服务器中找不到要查询的信息情况。

其实就是讲信息分布式保存在多台 DNS 服务器中,这些 DNS 服务器相互接力配合,从而找出要查询的信息,不过这个机制就很复杂,所以要需要介绍一下信息是如果在 DNS 服务器上注册并保存的。

DNS 服务器中的所有信息都是按照域名以分层次结构来保存的,层次结构就类似于学校的结构,如:某学校下的某年级下的某班级下的某个人。DNS 中的域名都是以句点来分割的,例如 www.baidu.com 这里的句点就代表了不同层次之间的界限,就相当于学校的结构不同划分。

这种层次结构的域名信息会注册到 DNS 服务器中,每个域都是作为一个整体来处理的,也就是一个域的信息是作为一个整体存放在 DNS 服务器中的,不能将一个域拆开来存放在多台 DNS 服务器中。不过,DNS服务器和域之间的关系也并不是一对一的,一台 DNS 服务器中也可以存放多个域的信息。

寻找相应的DNS服务器并获取IP地址

客户端其实就想直接请求 DNS 服务器,然后它告诉我 IP 地址即可,但是互联网中有数万太 DNS 服务器,肯定不能一台一台的去找,所以采用下面的方法进行快速查找。首先,将负责管理下级域的 DNS 服务器的 IP 地址注册到他们的上级 DNS 服务器中,然后上级 DNS 服务器的 IP 地址再注册到更上级的 DNS 服务器中,以此类推,这样我们就可以通过上级 DNS 服务器查询出下级 DNS 服务器的 IP 地址,也就可以向下级 DNS 服务器发送查询请求了。

一个没用的冷知识:在域名层次结构的段落中,com、cn 这些域就是似乎最顶层的域,事实并非如此,其实它们上面还有一级域,称为根域。根域不像 com、cn 有着自己的名字,因此在一般输入域名时经常被忽略,如果要明确表示根域,应该像 www.baidu.com. 这样在域名的最后加上一个句点,而这个句点就代表根域。我尝试输入并访问,然而访问不了,有兴趣的可以了解下为什么。

获取 IP 地址的过程

  • 客户端首先会访问最近的一台 DNS 服务器
  • 如果访问最近的一台 DNS 服务器中没有所缓存的域名信息,则该服务器会将请求信息转发至根域名服务器查询
  • 如果根域服务器中还是没有保存,则会依次向下域名服务器查询,例如 www.baidu.com ,com 域名服务器中没有信息,则会向 baidu.com 域名服务器查询,还是没有,则会再向 www.baidu.com 域名服务器查询
  • 定位到最终的 DNS 管理该域名的服务器后,该域名服务器会响应客户端该域名的 IP 地址。

DNS缓存服务

有时候并不需要从最上级的根域名开始查找,因为 DNS 服务器有缓存功能,可以记住之前查询过的域名。如果要查询的域名和相关信息已经在缓存中,那么就可以直接从缓存中得到所需的信息,接下来的查询可以从缓存的位置开始向下查找。相比每次都从根域找起来比较,缓存可以减少查询的时间。

当要查询的域名不存在时,不存在这一响应结果也会被缓存。这样,当下次查询这个域名不存在的域名时,也可以做到快速响应。

缓存机制和其他服务相同都存在时效性的问题,就是信息被缓存后,原本的注册信息可能会发生改变,这时缓存中保存的信息可能是错误的。因此 DNS 服务器中保存的信息都设置有一个有效期,当缓存中的信息超过有效期后,数据就会从缓存中删除。而且,在对查询进行响应时,DNS 服务器也会告知客户端这一响应结果是来自缓存还是来自负责管理该域名的 DNS 服务器。

DNS的安全性

DNS 是网络中至关重要的一个服务,包括 Web 、邮件等需要重要的服务,如果 DNS 不能正常工作,那么依赖它的服务都无法正常工作。因此,那么 DNS 服务器会受到怎样的攻击呢?

针对 DNS 服务器进行 DDoS

首先想到的就是对 DNS 服务器进行 DDoS 攻击,例如,攻击者能够向每个 DNS 根服务器发送大量的分组,使得大多数合法 DNS 请求得不到回答。这种对 DNS 根服务器的 DDoS 大规模攻击其实在 2002 年 10 月 21 日真实发生过,在这次攻击中,该攻击者利用了一个僵尸网络向 13 个 DNS 根服务器中的每个都发送了大批的 ICMP ping 报文,这次攻击虽然成功地将大量的分组指向了根服务器,但许多 DNS 根服务器收到了分组过滤的保护,所以对用户的网上冲浪几乎没有甚至没有影响。

这得益于大多数本地 DNS 服务器缓存了顶级域名服务器的 IP 地址,使得这些请求过程通常绕过了 DNS 根服务器。

中间人攻击

在中间人攻击中,攻击者截获来自主机的请求并返回伪造的回答,攻击者向一台 DNS 服务器发送伪造的回答,诱使服务器在它的缓存中接收伪造的记录。这一攻击能够使满怀信任的客户端重定向到攻击者想要你访问的站点,然而,这些攻击难以实现,因为它们要求截获分组或者扼制住服务器。

反射攻击

还有一种重要的 DNS 攻击本质上并不是一种对 DNS 服务的攻击,而是充分利用 DNS 基础设施来对目标主机发起的 DDoS 攻击。在这种攻击中,攻击者向许多权威 DNS 服务器发送 DNS 请求,每个请求具有目标主机的假冒源地址,这些 DNS 服务器则直接向目标主机发送它们的回答。

如果这些请求的响应比请求大得多,则攻击者不必自行产生大量的流量就有可能淹没目标主机。