网络协议--DNS:域名系统

14.1 引言

域名系统(DNS)是一种用于TCP/IP应用程序的分布式数据库,它提供主机名字和IP地址之间的转换及有关电子邮件的选路信息。这里提到的分布式是指在Internet上的单个站点不能拥有所有的信息。每个站点(如大学中的系、校园、公司或公司中的部门)保留它自己的信息数据库,并运行一个服务器程序供Internet上的其他系统(客户程序)查询。DNS提供了允许服务器和客户程序相互通信的协议。

从应用的角度上看,对DNS的访问是通过一个地址解析器(resolver)来完成的。在Unix主机中,该解析器主要是通过两个库函数gethostbyname(3)和gethostbyaddr(3)来访问的,它们在编译应用程序时与应用程序连接在一起。前者接收主机名字返回IP地址,而后者接收IP地址来寻找主机名字。解析器通过一个或多个名字服务器来完成这种相互转换。

图4-2中指出了解析器通常是应用程序的一部分。解析器并不像TCP/IP协议那样是操作系统的内核。该图指出的另一个基本概念就是:在一个应用程序请求TCP打开一个连接或使用UDP发送一个数据报之前。心须将一个主机名转换为一个IP地址。操作系统内核中的TCP/IP协议族对于DNS一点都不知道。

本章我们将了解地址解析器如何使用TCP/IP协议(主要是UDP)与名字服务器通信。我们不介绍运行名字服务器或有关可选参数的细节,这些技术细节的内容可以覆盖整整一本书。(见[Albitz and Liu 1992]标准Unix解析器和名字服务器介绍)。

RFC 1034 [Mockapetris 1987a] 说明了DNS的概念和功能,RFC 1035 [Mockapetris 1987b] 详细说明了DNS的规范和实现。DNS最常用的版本(包括解析器和名字服务器)是BIND---伯克利Internet域名服务器。该服务器称作named。[Danzig、Obraczka和Kumar 1992]分析了DNS在广域网中产生的通信量。

14.2 DNS基础

DNS的名字空间和Unix的文件系统相似,也具有层次结构。图14-1显示了这种层次的组织形式。

每个结点(图14-1中的圆圈)有一个至多63个字符长的标识。这颗树的树根是没有任何标识的特殊结点。命名标识中一律不区分大写和小写。命名树上任何一个结点的域名就是将从该结点到最高层的域名串连起来,中间使用一个点"."分隔这些域名(注意这和Unix文件系统路径的形成不同,文件路径是由树根依次向下的形成的)。域名树中的每个结点必须有一个唯一的域名,但域名树中的不同结点可使用相同的标识。

以点"."结尾的域名称为绝对域名或完全合格的域名FQDN(Full Qualified DomainName),例如sun.tuc.noao.edu.。如果一个域名不以点结尾,则认为该域名是不完全的。如何使域名完整依赖于使用的DNS软件。如果不完整的域名由两个或两个以上的标号组成,则认为它是完整的;或者在该域名的右边加入一个局部后缀。例如域名sun通过加上局部后缀.tuc.noao.edu.成为完整的。

顶级域名被分为三个部分:

  1. arpa是一个用作地址到名字转换的特殊域(我们将在14.5节介绍)。
  2. 7个3字符长的普通域。有些书也将这些域称为组织域。
  3. 所有2字符长的域均是基于ISO3166中定义的国家代码,这些域被称为国家域,或地理域。

图14-2列出了7个普通域的正式划分。

在DNS中,通常认为3字符长的普通域仅用于美国的组织机构,2字符长的国家域则用国际组织美国军事网点于每个国家,但情况并不总是这样。许多非美国的组织机构仍然使用普通域,而一些美国的其他组织组织机构也使用.us的国家域(RFC 1480 [Cooper and Postel 1993] 详细描述了.us域)。普通域中只有.gov和.mil域局限于美国。

许多国家将它们的二级域组织成类似于普通域的结构:例如,.ac.uk是英国研究机构的二级域名,.co.uk则是英国商业机构的二级域名。

DNS的一个没在如图14-1中表示出来的重要特征是DNS中域名的授权。没有哪个机构来管理域名树中的每个标识,相反,只有一个机构,即网络信息中心NIC负责分配顶级域和委派其他指定地区域的授权机构。

一个独立管理的DNS子树称为一个区域(zone)。一个常见的区域是一个二级域,如noao.edu。许多二级域将它们的区域划分成更小的区域。例如,大学可能根据不同的系来划分区域,公司可能根据不同的部门来划分区域。

一旦一个区域的授权机构被委派后,由它负责向该区域提供多个名字服务器。当一个新系统加入到一个区域中时,该区域的DNS管理者为该新系统申请一个域名和一个IP地址,并将它们加到名字服务器的数据库中。这就是授权机构存在的必要性。例如,在一个小规模的大学,一个人就能完成每次新系统的加入。但对一个规模较大的大学来说,这一工作必须被专门委派的机构(可能是系)来完成,因为一个人已无法维持这一工作。

一个名字服务器负责一个或多个区域。一个区域的管理者必须为该区域提供一个主名字服务器和至少一个辅助名字服务器。主、辅名字服务器必须是独立和冗余的,以便当某个名字服务器发生故障时不会影响该区域的名字服务。

主、辅名字服务器的主要区别在于主名字服务器从磁盘文件中调入该区域的所有信息,而辅名字服务器则从主服务器调入所有信息。我们将辅名字服务器从主服务器调入信息称为区域传送。

当一个新主机加入一个区域时,区域管理者将适当的信息(最少包括名字和IP地址)加入到运行在主名字服务器上的一个磁盘文件中,然后通知主名字服务器重新调入它的配置文件。辅名字服务器定时(通常是每隔3小时)向主名字服务器询问是否有新数据。如果有新数据,则通过区域传送方式获得新数据。

当一个名字服务器没有请求的信息时,它将如何处理?它必须与其他的名字服务器联系。(这正是DNS的分布特性)。然而,并不是每个名字服务器都知道如何同其他名字服务器联系。相反,每个名字服务器必须知道如何同根的名字服务器联系。1993年4月时有8个根名字服务器,所有的主名字服务器都必须知道根服务器的IP地址(这些IP地址在主名字服务器的配置文件中,主服务器必须知道根服务器的IP地址,而不是它们的域名)。根服务器则知道所有二级域中的每个授权名字服务器的名字和位置(即IP地址)。这意味着这样一个反复的过程:正在处理请求的名字服务器与根服务器联系,根服务器告诉它与另一个名字服务器联系。在本章的后面我们将通过一些例子来详细了解这一过程。

DNS的一个基本特性是使用高速缓存。即当一个名字服务器收到有关映射的信息(主机名字到IP地址)时,它会将该信息存放在高速缓存中。这样若以后遇到相同的映射请求,就能直接使用缓存中的结果而无需通过其他服务器查询。14.7节显示了一个使用高速缓存的例子。

14.3 DNS的报文格式

DNS定义了一个用于查询和响应的报文格式。图14-3显示这个报文的总体格式。

这个报文由12字节长的首部和4个长度可变的字段组成。

标识字段由客户程序设置并由服务器返回结果。客户程序通过它来确定响应与查询是否匹配。

16 bit的标志字段被划分为若干子字段,如图14-4所示。

我们从最左位开始依次介绍各子字段:

  1. QR是1bit字段:0表示查询报文,1表示响应报文。
  2. opcode是一个4bit字段:通常值为0(标准查询),其他值为1(反向查询)和2(服务器状态请求)。
  3. AA是1bit标志,表示"授权回答(authoritative answer)"。该名字服务器是授权于该域的。
  4. TC是1bit字段,表示"可截断的(truncated)"。使用UDP时,它表示当应答的总长度超过512字节时,只返回前512个字节。
  5. RD是1bit字段表示"期望递归(recursion desired)"。该比特能在一个查询中设置,并在响应中返回。这个标志告诉名字服务器必须处理这个查询,也称为一个递归查询。如果该位为0,且被请求的名字服务器没有一个授权回答,它就返回一个能解答该查询的其他名字服务器列表,这称为迭代查询。在后面的例子中,我们将看到这两种类型查询的例子。
  6. RA是1bit字段,表示"可用递归"。如果名字服务器支持递归查询,则在响应中将该比特设置为1。在后面的例子中可看到大多数名字服务器都提供递归查询,除了某些根服务器。
  7. 随后的3bit字段必须为0。
  8. rcode是一个4bit的返回码字段。通常的值为0(没有差错)和3(名字差错)。名字差错只有从一个授权名字服务器上返回,它表示在查询中指定的域名不存在。

随后的4个16 bit字段说明最后4个变长字段中包含的条目数。对于查询报文,问题(question)数通常是1,而其他3项则均为0。类似地,对于应答报文,回答数至少是1,剩下的两项可以是0或非0。

14.3.1 DNS查询报文中的问题部分

问题部分中每个问题的格式如图14-5所示,通常只有一个问题。

查询名是要查找的名字,它是一个或多个标识符的序列。每个标识符以首字节的计数值来说明随后标识符的字节长度,每个名字以最后字节为0结束,长度为0的标识符是根标识符。计数字节的值必须是0,63的数,因为标识符的最大长度仅为63(在本节的后面我们将看到计数字节的最高两比特为1,即值192~255,将用于压缩格式)。不像我们已经看到的许多其他报文格式,该字段无需以整32 bit边界结束,即无需填充字节。

图14-6显示了如何存储域名gemini.tuc.noao.edu

每个问题有一个查询类型,而每个响应(也称一个资源记录,我们下面将谈到)也有一个类型。大约有20个不同的类型值,其中的一些目前已经过时。图14-7显示了其中的一些值。查询类型是类型的一个超集(superset):图中显示的类型值中只有两个能用于查询类型。

最常用的查询类型是A类型,表示期望获得查询名的IP地址。一个PTR查询则请求获得一个IP地址对应的域名。这是一个指针查询,我们将在14.5节介绍。其他的查询类型将在14.6节介绍。

查询类通常是1,指互联网地址(某些站点也支持其他非IP地址)。

14.3.2 DNS响应报文中的资源记录部分

DNS报文中最后的三个字段,回答字段、授权字段和附加信息字段,均采用一种称为资源记录RR(Resource Record)的相同格式。图14-8显示了资源记录的格式。

域名是记录中资源数据对应的名字。它的格式和前面介绍的查询名字段格式(图14-6)相同。

类型说明RR的类型码。它的值和前面介绍的查询类型值是一样的。类通常为1,指Internet数据。

生存时间字段是客户程序保留该资源记录的秒数。资源记录通常的生存时间值为2天。

资源数据长度说明资源数据的数量。该数据的格式依赖于类型字段的值。对于类型1(A记录)资源数据是4字节的IP地址。

现在已经介绍了DNS查询和响应的基本格式,我们将使用tcpdump程序来观察具体的交换过程。

14.4 一个简单的例子

让我们从一个简单的例子来了解一个名字解析器与一个名字服务器之间的通信过程。在sun主机上运行Telnet客户程序远程登录到gemini主机上,并连接daytime服务器:

在这个例子中,我们引导sun主机(运行Telnet客户程序)上的名字解析器来使用位于noao.edu(140.252.1.54)的名字服务器。图14-9显示了这三个系统的排列情况。

和以前提到的一样,名字解析器是客户程序的一部分,并且在Telnet客户程序与daytime服务器建立TCP连接之前,名字解析器就能通过名字服务器获取IP地址。

在这个图中,省略了sun主机与140.252.1以太网的连接实际上是一个SLIP连接的细节(参见封2的插图),因为它不影响我们的讨论。通过在SLIP链路上运行tcpdump程序来了解名字解析器与名字服务器之间的分组交换。

sun主机上的文件/etc/resolv.conf将告诉名字解析器作什么:

第1行给出名字服务器---主机noao.edu的IP地址。最多可说明3个名字服务器行来提供足够的后备以防名字服务器故障或不可达。域名行说明默认域名。如果要查找的域名不是一个完全合格的域名(没有以句点结束),那末默认的域名.tuc.noao.edu将加到待查名后。

图14-10显示了名字解析器与名字服务器之间的分组交换。

让tcpdump程序不再显示每个IP数据报的源地址和目的地址。相反,它显示客户(resolver)的IP地址140.252.1.29和名字服务器的IP地址140.252.1.54。客户的临时端口号为1447,而名字服务器则使用熟知端口53。如果让tcpdump程序显示名字而不是IP地址,它可能会和同一个名字服务器联系(作指示查询),以致产生混乱的输出结果。

第1行中冒号后的字段(1+)表示标识字段为1,加号"+"表示RD标志(期望递归)为1。默认情况下,名字解析器要求递归查询方式。

下一个字段为A?,表示查询类型为A(我们需要一个IP地址),该问号指明它是一个查询(不是一个响应)。待查名字显示在后面:gemini.tuc.noao.edu.。名字解析器在待查名字后加上句点号指明它是一个绝对字段名。

在UDP数据报中的用户数据长度显示为37字节:12字节为固定长度的报文首部(图14-3);21字节为查询名字(图14-6),以及用于查询类型和查询类的4个字节。在DNS报文中无需填充数据。

tcpdump程序的第2行显示的是从名字服务器发回的响应。1*是标识字段,星号表示设置AA标志(授权回答)(该服务器是noao.edu域的主域名服务器,其回答在该域内是可相信的。)

输出结果2/0/0表示在响应报文中最后3个变长字段的资源记录数:回答RR数为2,授权RR和附加信息RR数均为0。tcpdump仅显示第一个回答,回答类型为A(IP地址),值为140.252.1.11。

为什么我们的查询会得到两个回答?这是因为gemini是多接口主机,因此得到两个IP地址。事实上,另一个有用的DNS工具是一个称为host的公开程序,它能将查询传递给名字服务器,并显示返回的结果。如果使用这个程序,就能看到这个多地址主机的两个IP地址:

图14-10中的第一个回答与host命令的第一行输出均是在同一子网(140.252.1)的IP地址。这不是偶然的。如果名字服务器和发出请求的主机位于相同的网络(或子网),那么BIND会排列显示的结果以便在相同网络的地址优先显示。

在这个例子中要说明的最后一个问题是在查询结果中的UDP数据长度:69字节。为说明这些字节需要知道以下两点:

  1. 在返回的结果中包含查询问题。
  2. 在返回的结果中会有许多重复的域名,因此使用压缩方式。在这个例子中,域名gemini.tuc.noao.edu出现了三次。

压缩方法很简单,当一个域名中的标识符是压缩的,它的单计数字节(范围由0~63)中的最高两位将被设置为11。这表示它是一个16 bit指针而不再是8bit的计数字节。指针中的剩下14 bit说明在该DNS报文中标识符所在的位置(起始位置由标识字段的第一字节起算)。我们明确说明只要一个标识符是压缩的,就可以使用这种指针,而不一定非要一个完整的域名压缩时才能使用。因为一个指针可能指向一个完整的域名,也可能只指向域名的结尾部分(这是因为给定域名的结尾标识符是相同的)。

图14-11显示了对应于图14-10的第2行的DNS应答的格式。我们也显示了IP首部和UDP首部来重申DNS报文被封装在UDP数据报中。还明确显示了在问题部分的域名中各标识符的计数字节。返回的两个回答除了返回的IP地址不同外,其余都是一样的。在这个例子中,每个回答中的指针值为12,表示从DNS首部开始的偏移量。

在这个例子中最后要注意的是使用telnet命令后输出的第2行,这里重复一下:

我们仅仅输入了主机名(gemini)而不是FQDN,但Telnet客户程序部输出了FQDN。这是由于Telnet程序通过调用名字解析器(gethostbyname)对输入的名字进行查询,返回的结果包括IP地址和FQDN。Telnet程序就输出它试图与之建立TCP连接的IP地址,当连接建立后,它就输出FQDN。

如果在输入Telnet命令后间隔很长时间才显示IP地址,这个时延是由名字解析器和名字服务器在由域名到IP地址的解析所引起的。而显示Trying到显示Connected to的时延则是由客户与服务器建立TCP连接所引起的,与DNS无关。

相关推荐
初晴~17 天前
【网络原理】数据链路层协议与DNS
网络·c++·python·网络协议·以太网·dns·数据链路层
火山引擎边缘云21 天前
亮相QCon2024,火山引擎边缘云揭秘云原生操作系统与HTTPDNS技术实践
云原生·边缘计算·dns
fareast_mzh24 天前
Difference between `systemd-resolved` and `dnsmasq`
运维·dns
CXDNW1 个月前
【网络篇】计算机网络——应用层详述(笔记)
服务器·笔记·计算机网络·http·web·cdn·dns
zhangxueyi1 个月前
详解DNS工作原理及实例分析
linux·运维·服务器·dns
威迪斯特1 个月前
linux网络服务:网络名称解析管理器,提供系统级的DNS缓存服务,并管理网络连接和DNS解析的服务systemd-resolved详解
linux·服务器·网络·缓存·dns·域名解析
中草药z1 个月前
【JavaEE】数据链路层协议和DNS
网络·学习·mac·ip·dns·mtu·数据链路
luofengmacheng1 个月前
记一次域名解析的问题定位
dns·域名解析
青衫客362 个月前
DNS解析流程
计算机网络·dns
椰椰椰耶2 个月前
【网络】DNS,域名解析系统
网络·dns