DNS 解析流程
互联网使用 IP
地址来唯一标识一个主机,但对于人来说 IP
地址不易记忆,人们善于记忆有具体含义的事物。举个不太恰当的例子,我们记住一个人的名字远比记住一个人的身份证号要容易的多。基于这样的一种想法,人们把 IP
替换成了一个易于理解和识别的名字,这个名字叫做域名。
域名和 IP
地址相对应,既然存在这种对应关系,就需要有地方管理和维护这种对应关系,那谁来负责存储和管理这种映射关系呢?在现实生活中,人和证件号码的映射关系由国家某单位管理,网络世界存在这样的机构吗?答案是肯定的,这就是 DNS 域名系统。
DNS
除提供域名到 IP
地址的转换服务,还提供主机别名、反向域名解析、负载均衡等功能。其中主机名到 IP
地址转换服务是最为重要的一个服务。负载均衡在日常的工作中也经常出现,例如 jd.com
背后的服务器少则几台,多则上百台。这样就出现了 一个 IP
地址集合与同一个域名相联系。DNS
会将 IP
集合存储在数据库中。
在日常的开发时,访问测试环境经常需要修改电脑中的 hosts
文件。例如在 mac OS
上执行 cat /etc/hosts
查看 hosts
文件中的内容,或者向 hosts
文件添加内容: 11.20.8.1 misc.360buyimg.com
。
为什么将 11.20.8.1 misc.360buyimg.com
添加到 hosts
文件,我们就可以访问到 11.20.8.1
这台机器呢?最开始网络上主机台数很少,网络管理员可以在操作系统中一个名为 hosts
的文件中管理主机名和 IP
地址,每当将新主机添加到网络时,每个网络管理员都会手动更新他的 hosts
文件,添加新的主机名和 IP
地址。伴随着网络规模的扩大,hosts
文件文件越来越大而且增删频繁,不利于网管的维护。DNS
的出现可以规避 hosts
文件的限制。
如果没有向 hosts
文件添加 11.20.8.1 misc.360buyimg.com
,将会由谁来解析 misc.360buyimg.com
域名呢?可以尝试在 mac OS
上可以执行 cat /etc/resolv.conf
。
resolv.conf
是操作系统域名系统解析器(DNS Resolver
)的配置文件,当一个程序需要通过域名访问 Internet
上的其他主机时,需要利用 Resolver
库函数进行域名到 IP
地址的转换。Resolver
库函数会访问 resolv.conf
种定义的 DNS
服务器的 IP
地址,换取待解析域名的 IP
地址。
resolv.conf
种两个比较重要的参数:
nameserver
定义DNS
服务器的IP
地址search
定义域名的搜索列表。
nameserver
是最主要的配置项,而其他配置项是可选的。search
配置项主要是用来拼装域名,例如: search
设置为 jd.com
,host -a my
则会尝试解析 my.jd.com
。
从 DNS Resolver 这步我们接触到了 DNS 服务器,DNS 服务器的主要功能是根据输入的域名返回 对应的 IP 地址。域名的规则和 DNS 的架构设计紧密相关,两者相互影响。
早期的因特网采用的是非层级命名方式,这样域名就可以很简短。但随着网络规模的扩大,非层级命名方式很难管理一个庞大且经常变化的域名集合。比如人的姓名就可以算是非层级命名方式,根据日常经验我们可以发现人的姓名重复几率非常大。假如将人的姓名格式改一下,按照省市县乡街道姓名的格式起名字,这样名字的重复几率就会大大降低。
现在的域名规则是一种层次树状结构。通过层次树状结构,任何一个连接在因特网上的主机或路由器,都可以有一个唯一的层次结构的名字,也就是域名。域名中的域是一个可被管理的划分。例如域名可以有一级域名、二级域名等等。DNS 按照域名这种层次树状结构将整个域名空间划分成了许多不相交的区(zone),每个区的域名信息由权威域名服务器负责管理。除权威域名服务器之外还有两种主要类型的服务器:根 DNS 服务器,顶级域名 DNS 服务器。
DNS
的解析过程分为两种:迭代方式和递归方式。通常从请求主机到本地域名服务器的查询是递归查询,其余查询是迭代查询。
在开始动手解析域名之前,我们最好先观察下域名解析的表现,第一种方法可以通过 chrome network
面板查看查看,其中有一项 DNS lookup
,可以直观感受到 DNS
的耗时情况。第二种方式可以在 mac OS
上通过 host
命令查看解析的过程,例如 host www.jd.com
。除上述两个方式外也可通过 nslookup
或 dig
命令来观察。之后我们会通过 dig
命令来动手验证 DNS
的解析过程。
动手验证 DNS
的话,我们要先找到根服务器的地址,目前一共有 13
组根服务器。我们通过 dig
命令尝试用根域名服务器解析 www.jd.com
。在终端执行 dig @m.root-servers.net. www.jd.com
,这里采用 m 根域名服务器,当然也可以选用其他根域名服务器。 dig
命令执行的结果和 DNS
的 UDP 报文格式基本一致。
dig 命令默认的输出信息可以分为 5 个部分。
1. 第一部分显示 dig
命令的版本和输入的参数。
2. 第二部分显示服务返回的一些技术详情,比较重要的是 status
。如果 status
的值为 NOERROR
则说明本次查询成功结束。
3. 第三部分中的 QUESTION SECTION
显示我们要查询的域名以及查询的类型,这里我们默认查询 A 记录。
4. 第四部分的 ANSWER SECTION
是查询到的结果。
5. 第五部分则是本次查询的一些统计信息,比如用了多长时间,查询了哪个 DNS 服务器,在什么时间进行的查询等等。
通过 ANSWER SECTION
我们发现有一些关键字例如 NS
、CNAME
,这些表示什么呢?它们表示 DNS 记录的类型,DNS 记录的类型主要有以下几种:
1. A 记录,表示 IP 地址,A 记录就是把一个域名解析到一个IP地址。
2. AAAA 记录,表示 IP v6 地址。
3. CNAME 别名记录,CNAME 记录就是把域名解析到另外一个域名。使用 CNAME 记录可以很方便地变更 IP 地址。
4. NS 域名解析服务器。
在我们解析 www.jd.com 的时候可以看到 CNAME 记录,通过这条 CNAME 记录可以看出 www.jd.com 采用了 cdn 服务。
这样我们就成功解析出了 www.jd.com 对应的 IP 地址。