转载请注明出处:http://blog.csdn.net/luotuo44/article/details/45545059
DNS(domain name system),读者们或多或少都听过,就是可以将域名转换给IP的一个系统。使得我们只需记住域名而非IP就能访问某个网站。当我们在浏览器里面输入一个网址时,浏览器会向本地DNS服务器发出查询请求,本地DNS服务器会把网址对应的IP返回给浏览器。注意:更确切来说,不是本地DNS服务器,而是Windows网络连接里面所配置的DNS服务器。一般我们不会配置的,所以本文默认使用本地DNS服务器。 除了用浏览器,我们也可以通过命令行的方式查询某个网址的IP。比如使用nslookup命令。下图是通过nslookup命令向阿里的公共DNS服务器223.5.5.5查询www.weibo.com的IP地址。可以看到最后的查询结果是121.194.0.221
从上面的叙述和命令使用,可以得知从域名到IP参与者有:DNS客户端(浏览器或者nslookup命令);DNS服务器(本地DNS服务器或者阿里的公共服务器)。其实,这里还隐藏了另外一个参与者:名字服务器(name server)。一共有三个参与者:DNS客户端( domain name systemclient)、DNS服务器(domain name system server)、名字服务器(name server)。
名字服务器有什么用呢?它和DNS服务器又有什么区别呢?要弄懂这个,首先要解决一个问题,阿里的公共DNS是如何知道微博IP的?它记住了,确实它是记住了(上图返回的是非权威应答,这说明是记住了)。但它不可能记住全球所有网站的IP吧。当用户向它查询一个它没有记住的网址时,它是怎么办的呢?我们不知道一个网址的IP,可以求助于DNS服务器,那么DNS服务器不知道呢?嘿嘿。
或许读者听说过DNS是分层的,不知道的话,就向上层查询。DNS确实是分层的,并且全球有13个根域名服务器(root name server)。阿里的公共DNS不懂一个网址的IP就要向根域名服务器询问(也可能不是向根域名服务器询问),不懂就要问嘛。但根域名服务器也不可能把全球的所有网址的IP都记录下来吧(对于IPv4或许有点可能,但对于IPv6就不可能了)。如果根域名服务器都不知道某个网址的IP,那可怎么办?其实,虽然根域名服务器不能告诉你某个网址的IP,但它会提供非常有用的信息给查询者(也就是阿里公共DNS服务器或者本地DNS服务器)。
在继续讲解查询之前,要先介绍域(domain)这个概念,因为网址是分域而治的。域名系统就像我们平常使用的文件目录那样,是分层的。首先是根,然后是顶级域(一级域)、接着是二级域、三级域、……。我们熟知的顶级域有:com、net、org、cn。父域将某个标识符(比如cn)分配给子域,然后子域cn将全权负责cn下面的二级域的具体分配。对于cn,熟知的二级域有com.cn、edu.cn这些。当然对于edu.cn又会负责旗下的三级域名分配(比如每个大学分配一个)。这样分层的一个好处就是方便管理。下图是一个DNS层次例子。
图来自《DNS 与 BIND》 图2-5
除了域(domain),还有另外一个重要的概念区域(zone)。假如A是一个域(domain),并且A有子域a和b。如果域(domain)A的管理者把a和b授权给另外的人管理,那么a和b就各自形成一个区域(zone)。也就是说,站在A的角度来看,a和b是区域(zone),但如果只看a或者b,那么又是一个域了。这类似于树里面的,树的一个孩子节点本身也是一颗树。下面用一张图说明这点:
图来自《DNS与BIND》
每一个区域(zone)都会有名字服务器(name server)[1],用来管理这个区域。管理包括对这个域进行再划分成更小的子域以及对子域名的IP解析(也就是将域名转换成IP)。对于某个区域,该区域的名字服务器(name server)就是该区域的权威,权威可以这样认为:该名字服务器给出的本区域的域名到IP转换结果是权威的(除了域名到IP的转换外,还有其他转换的)。
可以使用nslookup 命令查询一个区域(zone)或者主机的名字服务器(name server),如下图所示。其中,-qt=ns 指明要查询的类型是名字服务器(name server);223.5.5.5则是阿里的公共DNS服务器。
从上图可以看到,区域(zone) qq.com的名字服务器是ns[1-4].qq.com,而主机www.qq.com则是ns-tell.qq.com。
需要注意的是,区域(zone)和域(domain)都是一个范围而不是一台主机。比如qq.com它不是一台主机,而qq旗下的万维网服务器的主机名为www.qq.com,还有v.qq.com则是视频服务器的主机名。
有了上面的那些介绍,明确DNS中有什么物理实体,那么讲解DNS查询过程就容易多了。
使用阿里的223.5.5.5作为DNS服务器,查询www.qq.com的IP。假设在查询过程中,阿里的DNS服务器的缓存中并没有任何有关www.qq.com的记录。
- 我的PC机向223.5.5.5提出查询请求,查询www.qq.com对应的IP地址
- 223.5.5.5向根域名服务器提出查询请求,查询www.qq.com。根域名服务器的IP地址是固定的,每一个DNS服务器都会从配置文件中读取到
- 根域名服务器告诉223.5.5.5:“x.x.x.x是.com的名字服务器的IP地址,你去.com的名字服务器查询吧。哥只能帮你到这里了。”
- 223.5.5.5拿到这个回复并不生气,而是屁颠屁颠地向.com的名字服务器发出查询请求:“请告诉我www.qq.com的IP地址?”
- .com的名字服务器回复说,“给你qq.com区域的名字服务器 ns1.qq.com的IP地址y.y.y.y,你去那里查吧。”
- 吃完闭门羹,223.5.5.5再次出发向ns1.qq.com提出查询请求,“你总能告诉我www.qq.com的IP地址吧?这是你们旗下的域名啊”
- ns1.qq.com嘿嘿一声,说:“你去ns-tel1.qq.com查吧,它的IP是z.z.z.z”
- 223.5.5.5不抱希望地问ns-tel1.qq.com:“你能告诉我www.qq.com的IP吗”
- ns-tel1.qq.com说:“可以啊,它的IP是14.17.42.40”
- 223.5.5.5拿到结果后,在自己的缓存中存了一份备份,免得待会又有人问我的时候又要这样问来问去。最后223.5.5.5把结果告诉我的PC机
由于223.5.5.5会在自己的缓存中保留一份备份,这就有权威应答和非权威应答两种。如果223.5.5.5返回的结果是直接从自己的缓存中读取的,那么就是非权威应答。如果是从域名本身的权威名字服务器得到的结果,那么就是权威应答。
下图是《DNS与BIND》书中关于DNS查询过程的流程图:
图中的解析器相当于PC里面的浏览器或者nslookup程序。左边的名字服务器就相当于本地DNS服务器或者阿里的公共DNS服务器。
有一点要注意:阿里公共DNS服务器每次发出查询时,请求查询的内容都www.qq.com,而不是其中的某一部分。上图也展示了这一点。这是因为可能途中某个名字服务器的缓存中有www.qq.com,如果仅仅查询qq.com可能会错过[2]。
需要指出的是,DNS查询有两种:递归查询和迭代查询[3]。前面展示的是递归查询,查询工作由本地DNS服务器或者本文中的阿里公共DNS服务器完成绝大部分任务,查询的最初提出者只需等待结果即可。而在迭代查询中,如果本地DNS服务器或者公共DNS服务器的缓存中有查询的域名,那么返回之。如果没有,那么就像上图右边的那些名字服务器(name server)那样,告诉查询提出者“你去那里查吧”,当然也是可以直接返回一个错误信息的。
递归查询使得我们无法观察整个流程,此时可以使用dig命令,通过+trace强制使用迭代查询观看整个流程。下图展示了整个流程(@223.5.5.5表示使用阿里公共DNS服务器):
参考:
[1] http://en.wikipedia.org/wiki/Name_server#Authoritative_name_server
[2]《DNS与BIND》第5版 32页
[3] http://en.wikipedia.org/wiki/Domain_Name_System#DNS_resolvers