tommwq的博客

DNS服务器是如何工作的

· [tommwq@126.com]

DNS服务器历史简介

大家好!在这篇文章中,我们将讨论互联网世界中最重要、最不可或缺的资源。这个资源我们每个人都会用到,无论我们是否了解它。

网络中的每台机器都被一个数字地址所标识。网络中的机器使用这个地址相互通信。如果没有将数字地址和一个名字相关联,要记住网络中所有的数字地址是非常困难的。即使对于本地网络中的少数主机,记住全部地址也是很难的。更不要说记住互联网上4亿多台主机的地址了。

最初了解决这个问题,产生了hosts文件的概念。网络中的每台机器都有一个hosts文件(/etc/hosts),其中包含了名字到数字地址的映射。但随着时间的推移,问题来了:

  1. 每台机器都需要自己更新地址映射条目。
  2. 没有通知机制,让客户端知道添加了新的地址映射条目。
  3. 随着时间的推移,hosts文件不断膨胀,变得难以处理。

在20世纪70年代中期,名字服务器(name servers)的概念出现了。名字服务器背后的思想是:人们更容易记住名字而非数字,尤其是名字描述了资源的某些特点时。

在网络中把名字转换成数字地址的问题,几乎和计算机网络本身一样古老。

如果网络中存在名字服务器,机器只需知道名字服务器的数字地址,以及目标机器或网站的名字。有了这些信息,机器可以向名字服务器查询目标机器的数字地址(IP地址)。

集中式名字服务器比/etc/hosts文件的解决方案更好。现在有了一个专门用于解析名字的中央服务器,机器只需要知道名字服务器的数字地址。无论何时发出请求,名字服务器都会返回目标机器名字对应的数字地址。

拥有中心名字服务器的主要优点在于,服务器的IP地址可以在其他机器无感知的情况下发生变更。此时名字服务器只需要更新IP地址条目。

但是中心名字服务器也有一些缺点,要是中心服务器不可用了怎么办?因此产生了多个名字服务器的想法,在网络中,一台作为主服务器,其他作为辅助服务器。如果主服务器不可用,则向辅助服务器查询答案。

即使是这种方案(主服务器和辅助服务器)也存在一些缺点。具体如下:

  1. 随着网络中名字数量的不断增加,名字服务器很难从数百万个条目中检索信息。我们需要一种方法来管理这些名字。
  2. 假设一个名字服务器每秒收到大量查询请求,在这种情况下,名字服务器的负载会增加。我们需要找到一种方法来分散负载。
  3. 我们需要一种机制来隔离名字服务器中条目的维护工作,因为许多不同的管理员都会添加条目。

互联网域名系统

完整的DNS功能在下面的RFC中解释:

  • RFC 1034
  • RFC 1035

互联网的域名系统是一个倒立的树状结构。树的顶部是根域名服务器(不用担心,我会解释什么是根服务器),根服务器后面是顶级域名(Top Level Domain,TLD)服务器,之后是二级域名(Second Level Domain,SLD)服务器。各级域名用点(.)分隔。

理解上面加下划线的文字对于理解DNS的概念非常重要。

根服务器由一个点表示。

顶级域名分为两种类型,通用顶级域名(Generic Top Level Domain,gTLD)是诸如.com、.net、.org、.edu的域名。国家顶级域名(Country Code Top Level Domain,ccTLD)是类似.in、.us、.uk的域名。

我们称www.slashroot.in是一个域名,这个域名是通用顶级域名、二级域名和主机名的组合。我们过段时间再讨论这个问题。

我们通常提到的域名,比如google.com,是顶级域名和二级域名的组合。

这个域名系统(树)中的每个节点(node)都被分配给一个机构或组织来管理。对特定节点负责的组织被称为是是权威的(authoritative)。在DNS系统中,权威这个词会被多次用到。

位于系统层级顶点的根名字服务器,其权威机构是一个名为ICANN(互联网名称与数字地址分配机构)的组织。

通用顶级域名也由ICANN管理,并委托给ICANN认证机构。国家顶级域名由ICANN认证给不同国家管理。

在DNS系统中,委托是一个重要的概念。我会在另外一篇文章中介绍委托。

理解下面这个事实是非常重要的:在类似www.slashroot.in的地址中,最左边的部分(www)是主机名。网站使用www主机名只是出于惯例。没有规则要求网站必须使用什么主机名。网站也可以命名为xyz.example.com。

当我在浏览器地址栏中输入www.example.com时发生了什么?

根名字服务器(.)是名字服务器层次结构中最重要的资源。当一个名字服务器查询不到请求的信息时,它首先会询问根名字服务器。

一共有13个根名字服务器,包括:

a.root-servers.net. b.root-servers.net. c.root-servers.net. d.root-servers.net. e.root-servers.net. f.root-servers.net. g.root-servers.net. h.root-servers.net. i.root-servers.net. j.root-servers.net. k.root-servers.net. l.root-servers.net. m.root-servers.net.

现在所有DNS软件都包含上述全部根服务器的IP地址。因此DNS服务器可以访问任意一个根服务器,无需向其他服务器查询。

步骤1:用户在浏览器中输入www.example.com。

步骤2:操作系统首先检查/etc/hosts文件,查找www.example.com的IP地址。(这一机制可以通过/etc/nsswitch调整),然后检查/etc/resolv.conf文件,查找DNS服务器的IP地址。

步骤3:DNS服务器在其数据库中查询www.example.com。如果找到记录,返回。如果没有找到,向根服务器查询。

步骤4:根服务器会返回.com顶级域名服务器的地址(顶级域名服务器知道所有二级域名服务器)。在这里例子中我们查询的是www.example.com,所以根服务器将返回.com顶级域名服务器的信息。

如果输入的是www.example.net,根服务器将返回.net顶级域名服务器的地址。

步骤5:现在.com顶级域名服务器将为我们提供example.com二级域名服务器的地址。

步骤6:example.com二级域名服务器将返回www主机(www是主机名)的IP地址。

现在让我们看看这个过程实际上是如何工作的。

[root@myvm1 ~]# dig +trace www.google.com

; <<>> DiG 9.3.4-P1 <<>> +trace www.google.com
;; global options:  printcmd
.                       5       IN      NS      a.root-servers.net.
.                       5       IN      NS      b.root-servers.net.
.                       5       IN      NS      c.root-servers.net.
.                       5       IN      NS      d.root-servers.net.
.                       5       IN      NS      e.root-servers.net.
.                       5       IN      NS      f.root-servers.net.
.                       5       IN      NS      g.root-servers.net.
.                       5       IN      NS      h.root-servers.net.
.                       5       IN      NS      i.root-servers.net.
.                       5       IN      NS      j.root-servers.net.
.                       5       IN      NS      k.root-servers.net.
.                       5       IN      NS      l.root-servers.net.
.                       5       IN      NS      m.root-servers.net.
;; Received 228 bytes from 192.168.159.2#53(192.168.159.2) in 49 ms

com.                    172800  IN      NS      a.gtld-servers.net.
com.                    172800  IN      NS      b.gtld-servers.net.
com.                    172800  IN      NS      c.gtld-servers.net.
com.                    172800  IN      NS      d.gtld-servers.net.
com.                    172800  IN      NS      e.gtld-servers.net.
com.                    172800  IN      NS      f.gtld-servers.net.
com.                    172800  IN      NS      g.gtld-servers.net.
com.                    172800  IN      NS      h.gtld-servers.net.
com.                    172800  IN      NS      i.gtld-servers.net.
com.                    172800  IN      NS      j.gtld-servers.net.
com.                    172800  IN      NS      k.gtld-servers.net.
com.                    172800  IN      NS      l.gtld-servers.net.
com.                    172800  IN      NS      m.gtld-servers.net.
;; Received 504 bytes from 198.41.0.4#53(a.root-servers.net) in 153 ms

google.com.             172800  IN      NS      ns2.google.com.
google.com.             172800  IN      NS      ns1.google.com.
google.com.             172800  IN      NS      ns3.google.com.
google.com.             172800  IN      NS      ns4.google.com.
;; Received 168 bytes from 192.33.14.30#53(b.gtld-servers.net) in 12 ms

www.google.com.         300     IN      A       74.125.236.48
www.google.com.         300     IN      A       74.125.236.50
www.google.com.         300     IN      A       74.125.236.51
www.google.com.         300     IN      A       74.125.236.49
www.google.com.         300     IN      A       74.125.236.52
;; Received 112 bytes from 216.239.34.10#53(ns2.google.com) in 108 ms

现在你可以从dig输出中清楚地看到,请求首先发送到根服务器。a.root-servers.net返回的都是.com通用顶级域名服务器。然后b.gtld-servers.net返回了google.com的二级域名服务器。最终,ns2.google.com返回了www.google.com的IP地址。

希望你们喜欢这个帖子!!