你应该知道的 DNS —— 计算机网络自顶向下

745 阅读19分钟

DNS(Domain Name System),提供域名到 IP 地址的转换, 就是下面的这个东西 👇

前情提要

系统地学习计算机基础知识,并用博客记录下来。我们的教材是 计算机网络(原书第7版) (豆瓣),视频讲解 中科大郑烇、杨坚全套《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》课程_哔哩哔哩_bilibili

计算机网络:Internet基本原理(上)

计算机网络:Internet基本原理(下)

计算机网络:应用层协议原理

HTTP 必知必会

这篇是第二章应用层之 DNS,我们的参考资料是网络是怎样连接的 (豆瓣)

IP

IP 地址标识了主机、路由器。

基本思路

TCP/IP 的结构如图所示,由一些小的子网,通过路由器连接起来组成一个大的网络。

这里的子网可以理解为用集线器连接起来的几台计算机,然后将子网通过路由器连接起来,就形成了一个网络。

IP 地址是一个网卡在网络世界的通讯地址,相当于现实世界的门牌号。在网络中,所有的设备都会被分配一个地址,地址就相当于现实中某条路上的“×× 号 ×× 室”。

其中“号”对应的号码是分配给整个子网的,而“室”对应的号码是分配给子网中的计算机的。“号”对应的号码称为网络号,“室”对应的号码称为主机号, 这个地址的整体称为 IP 地址。

所以,通过 IP 地址我们可以判断出访问对象服务器的位置,然后将消息发送到服务器。

实际的 IP 地址

了解了 TCP/IP 中 IP 的基本思路之后,我们来看下真实世界中的 IP 地址。

实际的 IP 地址是一串 32 比特的数字,按照 8 比特(1 字节)为一组分成 4 组,分别用十进制表示 然后再用圆点隔开。比如 10.11.12.13。如果是 IPv6 的话,它是 128 比特 16 字节的数字。

在 IP 地址的规则中,网络号和主机号连起来总共是 32 比特,但这两部分的具体结构是不固定的。在组建网络时,用户可以自行决定它们之间的分配关系。

因此,我们还需要另外的附加信息来表示 IP 地址的内部结构。这一附加信息称为子网掩码。

关于子网掩码是什么,这里不再赘述,知乎上的大神解释的非常生动详细,感兴趣的同学直接看吧~ www.zhihu.com/question/56…

DNS 的必要性

但 IP 地址不好记忆,不便人类使用,因为这一串字符没有意义。而咱们人类一般倾向于使用一些有意义的字符串来标识设备,比如用 www.baidu.com 标记的百度的 web 服务器。

那有的同学可能有疑问了,为什么不直接用名称来确定通讯对象呢,每个设备给一个不同的名称不就可以解决问题啦。这样的想法没什么毛病,但是如果计算机网络这么设计的话,寻址效率会非常低。

我们都知道 IP 的作用是寻址,通过在互联网链路中交换节点的转发,把信。IP 地址的长度为 32 比特,也就是 4 字节,IPv6 是 128 比特 16 字节,但是域名最短也要几十个字节。也就是说,直接使用域名的话需要处理的字符大大增加了,这无疑增加了交换节点路由器的负担。

所以,必须提供「有意义的字符串」到「IP地址」的转换服务,域名解析系统 DNS 就应运而生。它主要解决的问题,或者说主要提供的服务,就是把「有意义的字符串」域名转换成为二进制的网络地址 IP。

DNS 系统需要解决的问题

那么 DNS 是怎么样实现域名到 IP 地址的转换呢,它需要解决哪些问题呢?

问题1:如何命名设备

这时可能同学会说,这还不简单,给每个设备取个名字不就完事了。美国的设备叫爱丽丝、鲍勃,中国的叫张三、李四等等。其实最早的计算机网络就是这么做的,但是随着网络节点的增加,这种命名方式的弊端也凸显了出来——很容易重名。

全球可能有多少人叫爱丽丝,因此我们必须解决一个重名的问题。科学家想到了分层化的命名方式,用层次化命名解决一个平面命名的重名问题。(比如 www.baidu.com,有三层。)

问题2:如何完成名字到 IP 地址的转换

现在我们搞定了命名方式,每个设备有了独一无二的名字,那么怎么完成名字到 IP 地址的转换呢?

这还不简单,用一台设备来维护所有的域名到 IP 地址的对应关系,有请求进来查找,这个设备就返回对应的 IP 地址,这不就可以解决问题啦?

这个想法很好,理论上也是可以,但在现实中没这么简单,为什么?

全球有几十亿台设备,上百亿台设备。如果我们只用一台设备来维护,不管是从用户端的访问延迟来看,还是服务器的负担、占用的带宽来看,都是不可行的。 因此,一台设备集中地解决域名到 IP 地址的这种解析是不可行。

所以在现实生活中,采用分布式地解析,分布式的数据库维护和响应名字査询。我们需要提前规划好,哪些节点维护哪些范围的域名到 IP 地址的对应关系。

问题3:如何维护?

当我们的域名系统定下来之后,他是会变化的。有时候我们要增加一些域名,增加域名当中的子域,而有时候要删除一些域名。

域名怎么来维护呢,增加或者删除一个域,需要在域名系统中做哪些工作呢?

DNS 历史

我们知道,互联网是一个分组交换的实验演化而来的。一开始的时候,它也存在着名字命名和解析的这样的翻译的问题,当时是怎么解决呢?

最早的名字解析解决方案

当时的网络节点比较少, 69 年只有 4 个节点, 72 年只有 15 个节点。

  • 主机的命名全部都是在一个平面
  • 使用一台设备来维护所有的名字 ip 地址的对应关系,存在着一个集中的维护站,维护着一张主机名-IP地址的映射文件: Hosts.txt
  • 每台主机定时从维护站取文件

问题

但是,随着节点数量越来越多,主机数量很大时,一个平面命名的漏洞就体现出来了,有很多重名的设备。

并且随着设备越来越多,负责解析的设备需要付出的代价也越来越大。而且还有一个最要命的问题,经常要增加、删除一些名字,在集中式的命名的服务器中进行操作,非常容易出错。文件的管理、发布、查找都很麻烦。

总体思路

这时候,就有人提出了域名解析系统,主要思想就是采用分层、基于域的命名机制,若干分布式的数据库完成名字到 IP 地址的转换。它是运行在 UDP 之上端口号为 53 的应用服务,不需要经过复杂的三次握手、四次挥手。

是域名解析系统,在主机系统的应用层来实现。而且互联网最核心的这些功能,很多都是在网络的边缘,通过端系统之上的应用进程来实现的。也就是说互联网它的复杂性体现在边上,而不是核心。

目标

其实 DNS 除了提供我们熟知的主机的域名到 IP 地址的转换 name/IP translate,还提供其他的服务。

主机别名 Host aliasing

主机别名到规范名字的转换。

比如书中举的例子,一台名为 relay.west-coas.enterpnse.com 的主机,可能还有两个别名 enterpise.com 和 www.enterpnse.com。relay.west-coas.enterpnse.com 是规范名字,其他两个是主机别名。

可以看出,规范名字是为了便于管理,别名是为了便于用户的访问。

因为提供 web 服务的服务器可能分布在全球各地,比如美国的东海岸、西海岸,还有亚太地区等等,所以需要一个规范名字来确定它的位置,方便管理。

所以,自然存在的一个别名转换的问题。

邮件服务器别名 Mail server aliasing

邮件服务器别名到邮件服务器的正规名字的转换。

自然,我们的电子邮箱也需要好记,比如我的邮箱是地址 chuxulu@163.com,但是实际上 163 的主机名称可能很复杂,不像咱们的邮箱地址那样简单好记。

所以,DNS 还需要提供邮件服务器的别名到邮件服务器的正规名字的转化。

负载均衡 load distribution

从图中可以看出,用户的访问不是集中在一个服务器上,而是被分流在了不同的节点上。

这样就起到了一个负载均衡的作用,当同一时间存在很多请求时,返回给用户的速度会大大增加。即使某一个节点出现了故障,也不会影响到其他节点。

问题1:DNS名字空间(The DNS Name5pace)

我们已经知道命名为了防止重名,必须要层次化的命名,来看下具体怎么命名的吧。

域名结构

在图中我们可以看出,一开始整个的名字空间缩成一个点,后来被分解成几百个顶级域。顶级域分为两类,一个是通用的,比如 .com 。一个是国家的,比如 .cn。

每个顶级域下再分为若干个二级域名,.cn 下面可以分为 com.cn、.edu.cn。一层层来分解域名,把整个的互联网的名字空间,分成一个倒着生长的一棵树,树叶是主机。命名一个设备的时候,是从树叶往树根走,每过一个层次用逗点来区分,一直到顶级域。

根名字服务器

根,就是上图中我圈出来的地方。DNS 名字空间有几个根呢,是一个吗?

当然不是,因为如果只有一个根,它宕机了,整个互联网的查询也就出现了问题。所以现存的根有 13 个,大部分运行在北美,欧洲,日本也有。查询的时候,必须要从 13 个树根当中的任何一个往下找。

那么这样安排有什么好处呢?可靠。我可以从离我最近的一个树根开始找,如果这个树根死掉了,我可以找其他的树根,再往下去查域名。

域 vs 主机

域的域名,可以用于表示一个域,比如 baidu.com。主机的域名,表示一个域上的一个主机,比如 www.baidu.com。

主机的域名是,顺着树叶往上走,一直到树根。每过一个层次,用逗点间隔;

而域的域名,是从中间的一个树枝往上走,一直走到树根。每过一级,用逗点来间隔。

采用这种层次化命名的方式,就能够大大的减少重复性命名的概率。

域名的管理

Generic 和 Countries 给每个国家分配了顶级域,然后各个国家再自行分配他们的子域。比如日本,它底下的二级域的划分跟中国是不一样的,中国的教育网是 edu,日本的教育和研究机构用 academic 来表示。

所以说每个域怎么样划分它的子域怎么样命名是由它所属域决定的,跟其他域没关系。当然,如果要创建一个新的域,必须征得它所属域的同意。

域与物理网络无关

域遵从组织界限,而不是物理网络;域的划分是逻辑的,而不是物理的。

也就是说,一个域的主机可以不在一个网络,一个网络的主机不一定在一个域。

比如处在百度子域的这些主机,可能是在百度公司内,可能在北京,可能在苏州,可能在深圳。只要服务器维护了百度的域名和 IP 地址,百度的网站就可以正常运行。

问题2:解析问题——名字服务器(Name Server)

第二个问题是完成域名到 IP 地址的转换。

只有一个名字服务器

那么我们前面有分析过了只有一个名字服务器来解决所有的解析问题和维护问题。存在以下的这些技术上的困难。

  • 可靠性问题:单点故障。只用一个机器来维护,所有的域名继续挂了,没法提供域名,所有的应用都跑不起来。
  • 扩展性问题:通信容量。所有的流量都走这台设备,那么这个服务器周边的流量会非常大。
  • 维护问题:远距离的集中式数据库。增加一个域,删除一个域,修改一个主机的域名到 ip 地址的对应关系非常麻烦。

那怎么办?我们要分布式解决。

区域(zone)

  • 区域的划分由区域管理者自己决定

  • 将 DNS 名字空间划分为互不相交的区域,每个区域都是树的一部分。

  • 名字服务器

    • 每个区域都有一个名字服务器:维护着它所管辖区域的权威信息 (authoritative record),称为权威名字服务器。

      • 是不是权威取决于,你是不是域的权威名字服务器。比如说你的领导在你们公司是权威的,但是换了个地方,他就不是权威了。
    • 名字服务器允许被放置在区域之外,以保障可靠性。

而且呢,隐含了一个条件,上层的区域可以知道下层区域该怎么走。因为是倒生长的一棵树,被分成一个个的区域,如果上面不知道下面在哪,解析是无法完成的。

那么有了权威名字服务器的概念之后,我们来看怎么解析。

TLD 服务器(top-level domain)

顶级域(TLD)服务器,负责顶级域名(如com、org、net、edu 和 gov)和所有国家级的顶级域名(如cn、uk、fr、ca、jp)。

  • Network solutions 公司维护 com TLD 服务器
  • Educause 公司维护 edu TLD 服务器

资源记录

每个区域的权威名字服务器都要维护一个数据库,存储区域的内部的子域,还有区域内部的一些域名到 IP 地址的对应关系,所有的这些信息都是以数据库资源记录的形式来维护的。

  • 资源记录(resource records)

    • 作用:维护域名——IP地址(其它)的映射关系
    • 位置:Name Server 的分布式数据库中

他的格式包括这几个字段。

  • RR格式:(domain name,TTL,type,class,Value)

    • Domain name:域名

    • TTL:time to live:生存时间(权威,缓冲记录)

      • TTL Time to Leave 生存时间,决定了资源记录应当从缓存中删除的时间。就是说资源记录插到表单中,它的生存时间到底是多少。
      • 如果是很长的无限大,这就是一个权威记录;如果是一个有限值,指的是一个缓存。
      • 缓冲是为了性能, 删除是为了一致性。
    • Class 类别:对于 Internet,值为 IN。(可以看出,一开始 DNS 并不是为互联网设计的)

    • Value 值:可以是数字,域名或 ASCII串

    • Type 类别:资源记录的类型

Type

保存资源记录(RR)的分布式数据库。

RR 格式:(nane,value,type,ttl)

还有一个 type 字段,表示提供服务的类型。

我们知道运行系统除了域名、ip 一致的对应关系的转换之外,还提供别名到正规名字的转换、邮件服务器别名到正规地址的转换、 还包括上层域下的子域是怎么样划分的。

所以说,这些资源记录起到不同的作用,用 Type 字段的不同的值来标识。

Type=A:域名、ip 一致的对应关系的转换

  • Name 为主机
  • Value 为 IP 地址

Type=NS:上层域下的子域

  • Name 域名,如 foo.com
  • Value 为该域名的权威服务器的域名

Type=CNAME:别名到正规名字的转换

  • Name 为规范名字的别名

    • www.ibm.com 的规范名字为 servereast. backup. ibm. com
  • Value为规范名字

Type=MX:邮件服务器别名到正规地址的转换

  • Value 为 Name 对应的邮件服务器的名字

大致工作过程

名字服务器的解析过程是这样:

1:应用 web 浏览器调用本地的应用调用解析器(resolver)

2:解析器作为客户向 Name Server 发出查询报文(封装在 UDP 段中)

3:Name Server 返回响应报文(name/ip)

4:IP 地址返回给应用

那你说我本地的调解析器是怎么知道 Local Name Server 的 IP 地址是什么呢?要么手工配,要么是通过协议自动配。

一个机器上线之后,你必须要具备这几个信息。IP 地址、子网掩码、Local Name Server 的 IP 地址。如果遇到名字的问题,该问哪个 IP 名字服务器,都是配好的。

(还有一个信息是默认网关 default gateway。如果机器发送的分组跟它不在一个子网范围之内,它会把分组发给默认网关,由默认网关来转发)

整个的域名解析系统当中,有很多的名字服务器,我们可以指定任何一个为 Local Name Server。一般,我们会设置离我们比较近的服务器为 Local Name Server,因为在一个局域网中,返回的速度会更快。

本地名字服务器(Local Name Server)

  • 并不严格属于层次结构

  • 每个 ISP (居民区的 ISP、公司、大学)都有一个本地 DNS 服务器,也称为“默认名字服务器”。

  • 当一个主机发起一个 DNS 查询时,査询被送到其本地 DNS 服务器。

    • 起着代理的作用,将查询转发到层次结构中

名字解析过程

目标名字在 Local Name Server 中时,有两种情况,一种是査询的名字在该区域内部,一种是缓存(cashing)。

这时候,直接返回查询结果即可。

当与本地名字服务器不能解析名字的时候,联系根名字服务器,顺着根到 TLD 往上走,一直找到权威名字服务器。

递归查询

从图上我们可以看出,名字解析负担都放在当前联络的名字服务器上。本地不知道问根,根不知道问上层,查询到之后再依次返回。

在这个过程当中,需要维护整个查询的过程。而且根服务器,需要做很多工作,负担太重。

所以就有了第二种查询方法——迭代查询。

迭代查询

什么是迭代查询呢?我们来看看图中的例子。

主机 cis.poly.edu 想知道主机 gaia.cs.umass.edu 的 IP 地址,它向本地 DNS 服务器发出询问。

  • 根(及各级域名)服务器 返回的不是查询结果,而是下一个 DNS 的地址。
  • 最后由权威名字服务器给出解析结果。
  • 当前联络的服务器给出可以联系的服务器的名字,相当于每个服务器会告诉你“我不知道这个名字,但你可以向这个服务器请求“

缓存

  • 一旦名字服务器学到了一个映射,就将该映射缓存起来
  • 根服务器通常都在本地服务器中缓存着,使得根服务器不用经常被访问,这样可以提高效率。
  • 但也可能存在问题,如果情况变化,缓存结果和权威资源记录不一致。所以采用上面介绍的 TTL 解决,默认设置过期时间是2天。

问题3:维护问题

我们来看看,怎么新增一个域。

  • 在上级域的名字服务器中增加两条记录,指向这个新增的子域的域名和域名服务器的地址
  • 在新增子域的名字服务器上运行名字服务器,负责本域的名字到 IP 地址的解析

🌰 例子:在 com 域中建立一个“ Network Utopia”

  • 到注册登记机构注册域名 networkutopia.com

    • 需要向该机构提供权威 DNS 服务器(基本的、和辅助的)的名字和 IP 地址
    • 登记机构在 com TLD服务器中插入两条 RR 记录

(networkutopia.com, dns1.networkutopia.com, NS)

(dns1.networkutopia.com, 212.212.212.1, A)

  • 在 networutopia.com 的权威服务器中确保有

    • 用于 Web 服务器的 wwww.networkuptopia.com 的类型为 A 的记录,名字服务器对应的 IP 地址。
    • 用于邮件服务器 mail.networkutopia.com 的类型为 MX 的记录,邮件服务器别名到正规地址的转换。

攻击DNS

那么域名解析系统,它的健壮性、安全性怎么样?现在有各种各样的攻击手段来攻击域名解析系统,相应的防护措施都是什么?

先看结论——总的说来,DNS 比较健壮。

DDoS攻击

  • 对根服务器进行流量轰炸攻击:发送大量 ping

    • 没有成功
    • 原因1:根目录服务器配置了流量过滤器、防火墙
    • 原因2: Local DNS 服务器缓存了 TLD 服务器的 IP 地址,因此无需查询根服务器
  • 向 TLD 服务器流量轰炸攻击:发送大量查询

    • 可能比上面的攻击更危险
    • 但是效果一般,因为大部分 DNS 缓存了 TLD

重定向攻击

  • 中间人攻击

    • 截获查询,伪造回答,从而攻击某个(DNS 回答指定的 IP)站点
  • DNS中毒

    • 发送伪造的应答给DNS服务器,希望它能够缓存虚假的结果
  • 技术上较困难:分布式截获和伪造

利用DNS基础设施进行DDoS

  • 伪造某个IP进行查询,攻击这个目标IP
  • 査询放大,响应报文比査询报文大
  • 效果有限