域名解析的DNS协议

背景
-
最初一开始使用hosts文件来描述主机名和IP地址的关系,比如host-a的主机名的IP地址为172.20.2.1
-
最初是有互联网信息来管理这个hosts文件的
-
但是这就很麻烦,如果一个新的计算机要接入网络,或者某个计算机IP变更,都需要到信息中心申请变更hosts文件
-
其他计算机也需要定期下载更新新版本的hosts文件才能上网
-
这才有了现在的DNS协议
DNS系统
-
DNS系统是一个分布式的域名服务系统,维护系统内的每个主机的IP地址和主机名的对应关系,并且是动态更新的
-
如果新计算机接入网络,将这个信息注册到数据库中
-
用户输入域名的时候,会自动查询DNS服务器,由DNS服务器检索数据库,得到对应的IP地址
至今我们的计算机上仍然保留了hosts文件。在域名解析的过程中仍然会优先查找hosts文件的内容,hosts文件在/etc/hosts。
域名简介
以www.baidu.com为例
-
com:一级域名,表示这是一个企业域名。同级的还有net(网络提供商),org(非盈利组织)
-
baidu:二级域名,公司名
-
www:这只是一种习惯用法,来表示主机支持的协议
域名服务器

-
域名服务器的结构有点像树形结构,每个层的域名上都有自己的域名服务器,最顶层是根域名服务器
-
每一级域名都知道下一级域名服务器的IP地址
-
为了容灾,每一级至少设置两个或以上的域名服务器
域名解析过程
-
输入域名后,先查询自己主机对应的域名服务器
-
域名服务器先查找自己的数据库中的数据,如果没有,就向上级域名服务器进行查找,依次类推
-
最大回溯到根域名服务器,肯定能找到这个域名的IP地址
-
域名服务器本身也会进行一些缓存,把曾经访问过的域名和对应的IP地址缓存起来,可以加速查找过程
DNS查询和应答报文格式如下图

-
16位标识:用于标记一对DNS查询和应答,以此区分一个DNS应答是哪个DNS查询的回应
-
16位标志:用于协商具体的通信方式和反馈通信状态
-
接下来的4个字段分别指出最后4个字段的资源记录数目(分别对应的),对查询报文而言,它一般包含一个查询问题,而应答资源记录数、授权资源记录数和额外资源记录数都为0。应答报文的应答资源记录数则至少为1,而授权资源记录数和额外信息记录数可为0或非0。
关于16位标志的具体细节如下

-
QR:查询/应答标志。0表示这是一个查询报文,1表示这是一个应答报文
-
opcode:定义查询和应答的类型。0表示标准查询,1表示反向查询(有IP地址获得主机域名),2表示请求服务器状态
-
AA:授权应答标志,仅由应答报文使用。1表示域名服务器是授权服务器
-
TC:截断标志,仅当DNS报文使用UDP服务时使用。因为UDP报文长度有限制,所以过长的DNS报文将被截断。1表示DNS报文超过512字节,并被截断
-
RD:递归查询标志。1表示执行递归查询,即如果目标DNS服务器无法解析某个主机名,则它将向其他DNS服务器继续查询,如此递归,直到获得结果并把结果返回给客户端。0表示执行迭代查询,即如果DNS服务器无法解析某个主机名,则它将自己知道的其他DNS服务器的IP地址返回给客户端,以供客户端参考
-
RA:允许递归标志,仅由应答报文使用。1表示DNS服务器支持递归查询
-
zero:这三位未用,必须都置为0
-
rcode:4位返回码,表示应答的状态。常用值有0(无错误)和3(域名不存在)
查询问题的格式如下

-
查询名以一定的格式封装了要查询的主机域名
-
16位查询类型表示如何进行查询操作,常见的类型如下
-
类型A,值是1,表示获取目标主机的IP地址
-
类型CNAME,值是5,表示获得目标主机的别名
-
类型PTR,值是12,表示反向查询
-
-
16位查询类通常为1,表示获取因特网地址(IP地址)
应答字段,授权字段和额外信息字段都使用资源记录(Resource Record,RR)格式。资源记录格式如图

-
32位域名是该记录中与资源对应的名字,其格式和查询问题中的查询名相同
-
16位类型和16位类字段的意思也和查询问题中的对应字段相同
-
32位生存时间表示该查询记录结果可被本地客户端程序缓存多少时间,单位是秒
-
16位资源数据长度和资源数据字段的内容取决于资源类型。对类型A而言,资源数据是32位的IPv4地址,而资源数据长度是4(以字节为单位)
Linux使用/etc/resolv.conf文件来存放DNS服务器的IP地址,可以在这个文件自己添加一些公网的DNS服务器作为首选的IP地址,此处我们得到的自动分配的局域网的DNS服务器地址,我们可以在下面的抓包过程中看到我们的DNS服务器的IP地址(192.168.224.2)

Linux中常用的访问DNS服务器的客户端程序是host,如下我们就是用首选DNS服务器查询www.baidu.com的IP地址

上面的查询结果告诉我们,www.baidu.com是www.a.shifen.com的别名,www.a.shifen.com有两个IP地址。host命令使用DNS协议与DNS服务器通信,-t选项告诉DNS协议使用哪种查询类型,这里使用的A类型,表示获取目标主机的IP地址(但实际上返回的资源记录中还包含机器的别名)。
host命令的使用方法如下
host +(选项) + 参数
-a
|
显示详细的DNS信息
|
-c<类型>
|
指定查询类型,默认值为“IN”
|
-C
|
查询指定主机的完整的SOA记录
|
-r
|
在查询域名时,不使用递归的查询方式
|
-t<类型>
|
指定查询的域名信息类型
|
-v
|
显示指令执行的详细信息
|
-w
|
如果域名服务器没有给出应答信息,则总是等待,直到域名服务器给出应答
|
-W<时间>
|
指定域名查询的最长时间,如果在指定时间内域名服务器没有给出应答信息,则退出指令
|
-4
|
使用IPv4
|
-6
|
使用IPv6
|
参数:指定要查询的主机的信息
使用tcpdump观察DNS通信的过程
我们使用tcpdump抓包工具来看一看DNS到底是怎么通信的。我们在本机上运行host命令以查询主机www.baidu.com的IP地址,并使用tcpdump抓取之一过程中局域网上传输的以太网帧。先执行以下命令
sudo tcpdump -i ens33 -nt -s 500 port domain
host -t A www.baidu.com //另开一个终端执行这个命令
-
-s 500 表示设置抓包的长度为500
-
port domain用来过滤数据包,表示只抓取domain(域名)服务的数据包
抓包得到的内容如下

-
两个数据包的IP指出,后续的内容是一个IP数据报
-
在第一个数据包中,192.168.224.2就是我们的首选DNS服务器的IP地址,53端口号表示DNS服务的端口号,62478是查询报文的标识值,因此该值也在DNS应答中,“+”表示启用递归查询标志。“A?”表示使用A类型的查询方式,“www.baidu.com”则是DNS查询问题中的查询名,括号中的31是DNS查询报文的长度(字节)
-
在第二个数据包中,DNS服务器返回给了本机一个应答,“3/0/0”表示该报文中包含3个应答资源记录,没有授权资源记录和额外信息记录。“CNAME www.a.shifen.com.,A 183.232.231.172,183.232.231.173”则表示3个应答资源的内容。其中CNAME表示紧随其后的记录是机器的别名,A表示紧随其后的记录是IP地址,该应答报文长度为90个字节。
面试题:在浏览器中输入一个url之后发生的事(没有标准答案,讲的越仔细越好)

-
查询hosts文件
-
查询DNS服务器(拿到IP地址)
-
通过运营商的路由器进行路由,找到通往百度路由器的路径
-
很有可能会命中运营商的CDN服务器,直接把一个资源返回给浏览器
-
如果没命中CDN,请求会走到命百度机房的入口服务器中,这个服务器很可能是一个反向代理服务器,也缓冲了一定的资源,如果命中了反向代理服务器上的缓存,也就将数据直接返回。
-
如果没有命中反向代理服务器上的缓存,就会去找到百度应用服务器集群上
-
进入百度应用服务器后,会先请求一个前端应用服务器。
-
前端应用服务器-->进入到分词服务器-->返回给前端应用服务器
-
前端应用服务器拿到分词结果,请求检索服务器,获得到检索结果对应的文档id
-
拿到文档id后,请求物料服务器得到完整的页面结果