次探DNS

之前已经写过一次DNS的文章了,不过那时刚接触,文中还有很多不正确的地方。DNS分为客户端和服务器端,客户端称为resolver,但是不是一个应用程序,而是一个函数库。在Linux里,resolver实现在libc库中,这个话题以后研究到再写。今天主要想总结一下域名服务器的查询方法,以及nslookup的使用方法。

域名系统是按层次划分的,从根域“.”开始。它可以使得不同域的主机可以改一样的名字,只要保证一个域里的名字不重复就可以了,类似于C++和Java的命名空间的好处。然后还要引入一个“区域(zone)”的概念,它跟“域(domain)”不同,区域指的是域里的管理范围。举个例子,假设域“.sysu.edu.cn”由中大管理,然后中大把子域“cs.sysu.edu.cn”授权给计算机系管理,那么中大管理的区域实际上是除了计算机系外的主机。也就是说,中大负责给各个主机域名解析,除了计算机系的主机外。

Domain Name System
Domain Name System

域定义了层次结构,区域定义了管理范围。每个区域可以授权下级管理一个子域,从而把子域所在的区域划出自己的管理。因此,每个区域的域名服务器只包含自己区域的名字解析,不包含已授权出去的子域的解析,但是会包含授权的子域的域名服务器名字。IANA规定每个区域至少包含两台DNS服务器。

比如想查询cisco.sysu.edu.cn。首先得查根域的域名服务器,查询“cisco.sysu.edu.cn”,但是根域中没有这个名字的解析,它会返回“.cn”子域的域名服务器。然后再向该域名服务器作同样的查询,这次还是没有得到结果,服务器只是返回“.edu.cn”的域名服务器。一直重复下去。

顺便值得一提的是,执行查询任务的DNS服务器一般是catch-only的服务器。DNS服务器分两种,一种是保存区域信息,另一种专门执行查询任务。我们在操作系统一般配置的DNS服务器就是catch-only的,只作查询任务的服务器。

DNS详解

DNS是Domain Name System(域名系统)的简称。有人认为DNS就只是把域名转换为IP地址,其实DNS还包括对域名的管理。

DNS有两大部分,是服务端和客户端。服务端称为Name Server(名字服务器),客户端称为Resolver(解析器)。

Name Server采用树状层次结构组织。比如www.baidu.com,com是根域,baidu.com是com的子域,而且是顶极域名。同样地,www.baidu.com是baidu.com的子域。如果该域名和IP地址绑定在一起,就是一个授权的名字服务器。

客户端Resolver是把域名解析为IP地址的功能,所以其实我们的PC一般都是直接连的是Resolver,而不会是Name Server。Resolver获得Name Server上的地址分为两个步骤,首先要确定哪一台Name Server有需要的映射,其次就是请求IP地址。第二步是很简单的,但是第一步就不是很容易。如果不考虑缓存的话,有两种方法。第一种是“iterative”(迭代),需要Resolver自己一层一层去获得。第二种方法是“Recursive”(递归),就是由上游的Name Server帮忙查。通常第二种方法不会出现在根域,因为这样对服务器消耗太大了。但是很可能出现在某一级的Name Server上,也就是说两种方法是可以一起用的。

那么我们的电脑到底是怎么连的呢,我们的电脑通常要设置DNS服务器,实际上设置的是Local Name Server(通常是ISP的),实际上它既是DNS服务器,但如果它自己没有该条目,也充当Resolver,我们自己的电脑也是Resolver,所以一般就是两层Resolver的结构。ISP的Local Name Server是一个中间的角色,通常没有下一层的Resolver了。

最后看一个例子。

  1. 比如查询www.baidu.com,首先检查本机Cache。
  2. 没有的话查询设置的DNS服务器,比如电信的DNS服务器,也是检查Cache。
  3. 假设还是没有,电信的DNS服务器就要用iterative或者recursive方法查询Name Server。
  4. 获得IP地址后,先加入缓存,并且返回结果。
  5. 最后本机获得IP地址,当然也会缓存。