第14章 DNS:域名系统
14.5 指针查询
D N S中一直难于理解的部分就是指针查询方式,即给定一个 I P地址,返回与该地址对应的域名。
首先回到图1 4 - 1,查看一下顶级域a r p a,及它下面的i n - a d d r域。当一个组织加入I n t e r n e t,并获得D N S域名空间的授权,如n o a o . e d u,则它们也获得了对应I P地址的i n - a d d r . a r p a域名空间的授权。在n o a o . e d u这个例子中,它是网络号为1 4 0 . 2 5 2的B类网络。在D N S树中结点i n -a d d r . a r p a的下一级必须是该I P地址的第一字节(例中为1 4 0),再下一级为该I P地址的下一个字节(2 5 2),依此类推。但应牢记的是D N S名字是由D N S树的底部逐步向上书写的。这意味着对于I P地址为1 4 0 . 2 5 2 . 1 3 . 3 3的s u n主机,它的D N S名字为3 3 . 1 3 . 2 5 2 . 1 4 0 . i n - a d d r . a r p a。
必须写出4字节的I P地址,因为授权的代表是基于网络号: A类地址是第一字节,B类地址是第一、二字节,C类地址则是第一、二、三字节。 I P地址的第一字节一定位于i n - a d d r的下一级,但F Q D N却是自树底往上书写的。如果F Q D N由顶往下书写,则这个I P地址的D N S名字将是a r p a . i n - a d d r . 1 4 0 . 2 5 2 . 1 3 . 3 3,而它所对应的域名将是e d u . n o a o . t u c . s u n。
如果D N S树中没有独立的分支来处理这种地址—名字的转换,将无法进行这种反向转换,除非从树根开始依次尝试每个顶级域。毫不夸张地说,这将需要数天或数周的时间。虽然反写I P地址和特殊的域名会造成某些混乱,但 i n - a d d r解决方案仍是一种最有效的方式。
只有在使用h o s t程序或t c p d u m p程序直接同D N S打交道时,才会担心i n - a d d r域和反写I P地址影响我们。从应用的角度上看,正常的名字解析器函数(g e t h o s t b y a d d r)将接收一个I P地址并返回对应主机的有关信息。反转这些字节和添加i n - a d d r . a r p a域均由该函数自动完成。
14.5.1 举例
使用h o s t程序完成一个指针查询,并使用 t c p d u m p程序来观察这些分组。例子中的设置和图1 4 - 9相同,在s u n主机上运行 h o s t程序,名字服务器在主机 n o a o . e d u上。我们指明s v r 4主机的I P地址:
代码语言:javascript复制sun % host 140.252.13.34
Name: svr4.tuc.noao.edu
Address: 140.252.13.34
既然I P地址是仅有的命令行参数, h o s t程序将自动产生指针查询。图 1 4 - 1 2显示了t c p d u m p的输出。
第1行显示标识符为 1,期望递归标志设置为 1(加号“ ”),查询类型为 P T R(应注意:问号“?”表示它是一个查询而不是响应)。4 4字节的数据包括 1 2字节的D N S报文首部、2 8字节的域名标识符和4字节的查询类型和查询类。
查询结果包含一个回答 R R,且为授权回答比特置 1(带星号)。R R的类型是P T R,资源数据中包含该域名。
从名字解析器传递给名字服务器的指针查询不再是 32 bit的 I P地址,而是域名3 4 . 1 3 . 2 5 2 . 1 4 0 . i n - a d d r . a r p a。
14.5.2 主机名检查
当一个I P数据报到达一个作为服务器的主机时,无论是 U D P数据报还是T C P连接请求,服务器进程所能获得的是客户的 I P地址和端口号( U D P或T C P)。某些服务器需要客户的 I P地址来获得在D N S中的指针记录。在2 7 . 3节会看到这样的例子,从未知的 I P地址使用匿名F T P访问服务器。
其他的一些服务器如R l o g i n服务器(第2 6章)不但需要客户的I P地址来获得指针记录,还要向D N S询问该I P地址所对应的域名,并检查返回的地址中是否有地址与收到的数据报中的源I P地址匹配。该检查是因为 . r h o s t s文件(见2 6 . 2节)中的条目仅包含主机名,而没有 I P地址,因此主机需要证实该主机名是否对应源 I P地址。
某些厂商将该项检查自动并入其名字解析器的例程中,特别是函数 g e t h o s t b y a d d r。这使得任何使用名字解析器的程序均可获得这种检查,而无需在应用中人为地进行这项检查。
来看一个使用SunOS 4.13名字解析器库的例子。我们编制了一个简单的程序通过调用函数g e t h o s t b y a d d r来完成一个指针查询。我们已在文件/ e t c / r e s o l v . c o n f中将名字服务器设置为n o a o . e d u,s u n主机通过S L I P链路与它相连。图1 4 - 1 3显示了当调用函数g e t h o s t b y a d d r获取与I P地址1 4 0 . 2 5 2 . 1 . 2 9(s u n主机)对应的名字时,t c p d u m p在S L I P链路上收到的内容。
第1行是预期的指针查询,第 2行是预期的响应。但第 3行显示了该名字解析器函数自动对第2行返回的名字发出一个I P地址查询。既然s u n主机有两个I P地址,第4行的响应就包括两个回答记录。如果这两个地址中没有与 g e t h o s t b y a d d r输入参数匹配的地址,函数会向系统的日志发送一条报文,并向应用程序返回差错。