DNS: internet的目录服务

Posted by Joel on February 10,2018

一道经典的面试题

从你在浏览器输入URL并按下回车到页面完整呈现都发生了什么?

这个问题可以回答的很复杂,gayhub上甚至有一个专门的仓库用来回答这个问题,从按下键盘的系统中断响应一直分析到浏览器如何解析渲染HTML文档。

我也准备在不断的学习过程中一步步地回答这个问题,当然我们不用从系统中断开始分析(笑

这篇文章将分析:DNS服务是如何将URL转换为IP地址的

什么是DNS

Domain Name System,简称DNS,译名:域名系统。

DNS有两重含义:

  1. 一个由分层的DNS服务器形成的分布式数据库
  2. 一个使得主机能够查询分布式数据库的应用层协议

关键词:分布式数据库,分层,应用层协议。

为什么要有DNS

回到开头提到的问题,我们输入了URL,那么URL是什么?

答:统一资源定位符,标记了internet中一个对象。一个对象只是一个文件,对应一个资源,如一份HTML文件,一张png图片,一段视频等。

举一个栗子🌰:
http://www.somesite.com/somepath/somepic.png

这是一个URL,由两部分组成:

  1. 主机名 www.somesite.com
  2. 路径 /somepath/somepic.png

这个URL标记了一张存储于www.somesite.com上、路径为/somepath/somepic.png的图片。

我们想要请求这个URL以下载这张图片,那么问题来了。

对于我们人类来说这样的标记很好记,然而对于计算机来说,主机名几乎没有提供关于该主机在intenet中位置的信息。

并且因为主机名由不定长的字母和数字组成,路由器很难处理。

因此,主机可以使用IP地址进行标识。

IP地址(v4)由四个字节组成,并且有着严格的层次结构,当我们从左往右扫描IP地址,我们能得到越来越具体的该主机在internet中位置的信息。

对人类来说这个四字节的地址是很难记忆的。

而DNS提供了将主机名转换为其背后的IP地址的服务。

DNS提供的服务

当我们在浏览器的地址栏输入http://www.somesite.com/somepath/somepic.png并按下回车,我们想要将一个HTTP请求报文发送到Web服务器www.somesite.com,那么我们必须提供该服务器的IP地址,这时:

  • 同一台主机上运行着DNS应用的客户端
  • 浏览器从URL中取出主机名,传递给DNS应用的客户端
  • DNS客户向DNS服务器发送一个包含主机名的请求
  • DNS客户最终收到一份回答报文,其中包含目的主机的IP地址,并将该IP地址传给浏览器
  • 浏览器向位于该IP地址80端口的HTTP服务器进程发起一个TCP连接

这就是DNS提供的主机名到IP地址转换的功能

除此以外DNS还提供以下服务:

  • 主机别名。例如一台主机的主机名很难记,例如oh-my-holy-shit.somename.com,但它可能有一个或多个好记的别名(holyshit.com),这种情况下oh-my-holy-shit.somename.com称为规范主机名,DNS提供从别名获取规范主机名和IP地址的服务。
  • 邮件服务器别名。当我们日常使用邮箱时,例如`123456@qq.com,真实的邮箱服务器主机名可能比qq.com复杂到不知道哪里去了👓,此时的qq.com`就是一个邮箱服务器的别名。DNS为电子邮件程序提供从别名到规范主机名的服务。
  • 负载分配。一个IP地址的集合可能与一个规范主机名对应,DNS数据库中存储着这些IP地址,当查询该主机名的IP地址时DNS选择一个IP返回,这样就在这些服务器间分配了负载。

你可能意识到了,访问qq.com得到的并不是一个邮件服务器,那么是DNS对邮件服务和Web服务做了区分吗?后文将回答这个问题。

DNS工作机理概述

我们主要考虑从主机名获取IP地址的服务

从上文浏览器请求图片的例子可以看出,站在浏览器的角度,DNS是一个提供简单的转换服务的黑盒,然而这个黑盒内部非常复杂。

分布式、层次数据库

在我们对DNS的定义中提到:DNS是一个由分层的DNS服务器形成的分布式数据库。

为什么分布式

如今internet上有不计其数的主机,将它们的主机名与IP地址的映射统一管理,显然是不现实的,在维护、性能、硬件上有巨大的挑战,而且一旦出现故障整个internet都会崩溃。

何为层次式

上图中自顶向下三层,分别是:

  1. 根DNS服务器。级别最高的DNS服务器,返回顶级域(如com)的TLD服务器地址。根域名服务器地址的数量被限制为13个(标号为A到M),但实际上每个根域名服务器都是一个冗余服务器的网络。截至2017年11月,全球共有800台根域名服务器在运行。
  2. 顶级域DNS服务器。(Top-Level Domain,TLD)。负责顶级域名如com、org、net、edu、gov以及所有的国家顶级域名如cn、jp、uk。
  3. 权威DNS服务器。假设你成立了一家公司,公司的官网是holyshit.com。为了让人们能够用holyshit.com这一域名访问你的网站,你可以自己架设一台DNS服务器,其中保存了holyshit.com到IP地址的映射,这台服务器就是权威DNS服务器;你也可以付钱将这一映射保存到某个服务商提供的权威DNS服务器。

DNS服务使用大量的DNS服务器,它们以分层的方式组织,分布在世界各地。

全世界的主机名与IP地址的映射分布在这些DNS服务器上,并不存在一台保存了所有映射的服务器。

本地DNS服务器

这里的本地是指离你的主机足够近(通常几台路由器的距离),而不是运行在你的端系统。

每个ISP(大学,公司,居民区)都有一台本地DNS服务器,当某台主机发起DNS请求,该请求被发往本地DNS服务器,本地DNS服务器起一个代理的作用,然后本地DNS服务器将请求转发到上文所说的DNS服务器层次结构中。

一个具体的栗子🌰


假设我们要访问holyshit.com,负责该主机名的权威DNS服务器为dns.holyshit.com

DNS查询的步骤分解如下:

  1. 请求主机向本地DNS服务器发送一个DNS查询报文,报文中包含要转换的主机名holyshit.com
  2. 本地DNS服务器将该报文转发到根DNS服务器
  3. 根DNS服务器注意到com前缀,向本地DNS服务器返回负责com前缀的TLD的IP地址列表
  4. 本地DNS服务器从返回的IP列表中选择一个,向该TLD服务器发送查询报文
  5. 该TLD服务器查询它的映射表,返回holyshit.com对应的权威DNS服务器IP地址,这个权威DNS服务器就是dns.holyshit.com
  6. 最后本地DNS服务器向dns.holyshit.com发送重发查询报文
  7. dns.holyshit.comholyshit.com的IP地址作为响应。
  8. 本地DNS服务器向请求主机返回目标主机的IP地址

迭代查询与递归查询

上节的例子中,我们发现步骤二到步骤七,查询均由本地DNS服务器发出,共执行三次查询(实践中可能更多),每查询一次得到的结果都更加接近目标的IP地址。

每一次执行查询的主体都是本地DNS服务器,这种查询是迭代查询

至于递归查询,看一张图就一目了然了。

查询由主机发出,层层深入,在得到结果后层层返回,与递归的行为非常类似,因而称为递归查询。

上节的例子中从请求主机发往本地DNS服务器的查询就是一次递归查询。

DNS缓存

DNS广泛使用了缓存技术,在一个请求链中,当某DNS服务器收到了一个DNS应答(例如,主机名到地址的映射),它能将该应答存储在本地存储器中,这样当下一个请求该主机名的请求到来时它就能提供正确的IP地址,即使它并不是该主机名的权威服务器。

缓存保存的时间一般为两天。

本地DNS也可以保存TLD服务器的地址从而绕过根DNS服务器。

DNS记录和报文

存储在DNS这个分布式数据库中的内容称为资源记录(Resource Record,RR)

资源记录是一个包含了以下四个字段的四元组:

(Name, Value, Type, TTL)

TTL决定了记录被保存的时间,而Name和Value的值取决于Type:

Type Name Value
A 主机名 IP地址
NS 域(foo.com) 权威DNS服务器主机名
CNAME 主机名 规范主机名
MX 主机名 邮件服务器的规范主机名

DNS报文分为请求报文和回答报文。我们这里并不具体研究这两种报文的格式和字段。

在请求报文中会带上请求的主机名和请求的类型(对应RR的Type字段)

在回答报文中可以携带多个RR,因此一个主机名可以有多个IP地址(冗余服务器)。

至此可以回答上文中对于qq.com并不是一个邮件服务器的疑惑:

在邮件服务中,DNS查询报文的类型字段为MX,因此查询到的RR与访问qq.com时查询的RR并不相同。


EOF


>