DNS协议以及报文格式总结

主要参考内容为RFC 1034、1035(简略参考,需要时再去阅读)还有以下博客参考

本文只是简略总结学习DNS协议的要点。

DNS协议思想


总结下来就是核心是分层式的思想。有以下几个点:

  • 分层式结构自然引出树结构,树的每一个父节点只负责管理子节点的信息。

  • 节点的表示引出域名概念,按照RFC文档的规定,域名是0-63个字节的在指定字符范围内的标签,其中最特殊的0个字节缺省为根节点专属的域名。

  • 最终的主机名,是一个从根节点到达叶节点的自顶向下路径,并且路径上相邻父子节点之间通过.分隔,形成对人类友好的字符串形式。

  • 在DNS报文中,主机名将其中的点号分割替换为,通过表明域名长度的数字分割。显然结尾是0,以表示到达根节点,在此也可以看出,利用NULL作为根节点表示,是为了方便DNS报文中表示主机名结尾。

  • 域名服务器,是域名父节点管理其子节点信息的实际执行者。一般分为根服务器,顶级域名服务器,权威服务器

而DNS协议解析,根据RFC 1034的说法,是通过resolver完成的,实际上过程是这样的。

  • 对于迭代查询:
    • 客户端选择代理服务器,让他完成所有查询任务。
    • DNS代理服务器完成如下操作,以下为比喻。
    • DNS代理服务器中预先有根服务器主机名以及其IP地址,因此去到根节点上,在已知需要解析的主机名,因此,我可以推断出下一级的域名,也就是下一个要去子节点的标签,而当前根节点具有的恰好就是所有他管理的子节点信息。
    • 子节点信息主要是,子节点的主机名是什么?子节点的IP地址是什么?这解决了是谁,在哪里的问题。
    • 之后代理服务器就跑去这个查出来的子节点,这时候,根据树是递归定义出来的,当前的节点到达我想到达的最终主机之间又可以看作一棵树,那么我就还让代理服务器按照先前的方式不断地问,知道遇到了叶子节点IP地址。
    • 此时,代理服务器完成任务,就把查出来的IP地址返回给客户端。
  • 对于递归查询:
    • 客户端选择代理服务器,让他完成所有查询任务。
    • DNS代理服务器完成如下操作,以下为比喻。
    • 此时,查询就像一个甩锅的过程,先前除了代理服务器,所有服务器都是询问-回答的状态,而递归查询则是,代理服务器把查询任务丢给了根服务器,根服务器认出这是递归查询,就跑到有这个需要解析的路径分析出的子节点所在处(事实上,他只知道他的子节点,他查询时候能管的也只有他的子节点),把任务丢给子节点,然后,就静静等待子节点完成交差,等到子节点完成后,就把这个最终的结果还给代理服务器。
    • 每一级都是如此,把任务甩给下一节点,静静等待下一节点完成后,在还给之前给自己指派任务的服务器,也可以理解为,每一个下一节点的DNS服务器,都被当作了一个代理服务器。

每次这么来一遍,效率很低,考虑到现实中一个地址可能要问好几次,比如,学生选课,期间,选课官网在一段时间内,肯定是高频访问,那么如果代理服务器有存储先前的结果,那就不必大费周章的从头推导,直接背书完了。当然了,每次都要有新知识的流入,比如过一段时间,LOL S赛直播,整个大学就开始需要直播间的地址,所以,就得忘掉旧知识,不然屯的都是旧知识,没有把新知识背住,新知识用起来就很麻烦。这就是DNS服务器缓存服务器的概念,以及TTL的由来。

DNS报文格式


因特网的协议,重要特色就是报文格式,格式化的交流方式,才可以使得因特网够高效稳定。

头部


  • 会话标识(2 bytes):请求报文与对应的应答报文整个是相同的,区分应答是针对哪一个询问。
  • 标志(2 bytes):是一个标准的bit-wise的标识方法,每一位的意义如下
    • QR (1 BIT): 查询对应0,响应为1
    • opcode(4 bits): 0-标准查询,1-反向查询,2-服务器状态请求
    • AA(1 BIT): 授权回答
    • TC(1 BIT): 可截断
    • RD(1bit):表示期望递归。
    • RA(1bit):表示可用递归。
    • Z(3 bits): 全0
    • rcode(4 bits): 应答,类似http的404,200之类的。
      • 0 没有错误。
      • 1 报文格式错误(Format error) - 服务器不能理解请求的报文。
      • 2 服务器失败(Server failure) - 因为服务器的原因导致没办法处理这个请求。
      • 3 名字错误(Name Error) - 只有对授权域名解析服务器有意义,指出解析的域名不存在。
      • 4 没有实现(Not Implemented) - 域名服务器不支持查询类型。
      • 5 拒绝(Refused) - 服务器由于设置的策略拒绝给出应答。比如,服务器不希望对某些请求者给出应答,或者服务器不希望进行某些操作(比如区域传送zone transfer)。
      • 6:本来应该没有的域名,但是有
      • 7:有一个资源记录集存在,本来不应该有
      • 8:有一个资源记录集应该有,但它没有
      • 9:查询的服务器并不权威
      • 10:相关的信息并不是当前域存在的
    • 数量字段,协议报文经常出现的部分。Questions、Answer RRs、Authority RRs、Additional RRs 各自表示后面的四个区域的数目。Questions表示查询问题区域节的数量,Answers表示回答区域的数量,Authoritative namesversers表示授权区域的数量,Additional recoreds表示附加区域的数量。

正文


分为Queries 和 RR部分

Queries


  • 查询名NAME: 长度不固定,一般是需要查询的主机名(uestc.edu.cn诸如此类),如果是反向查询,就是IP地址。格式如前所述,一个字节的数字标识域名的长度,并将整个主机名分割。

  • 查询类型,这是由RFC定义的RR 类型,起初只定义了一部分,随着IPV6等问题,在之后的RFC文档又定义了新的类型

类型 助记符 说明
1 A 由域名获得IPv4地址
2 NS 查询域名服务器
5 CNAME 查询规范名称
6 SOA 开始授权
11 WKS 熟知服务
12 PTR 把IP地址转换成域名
13 HINFO 主机信息
15 MX 邮件交换
28 AAAA 由域名获得IPv6地址
252 AXFR 传送整个区的请求
255 ANY 对所有记录的请求
  • 查询类:有chaos,internet,通常选internet,用1表示

资源记录


包含回答,授权,附加三个区域,格式一致。其中回答是对询问的响应,授权是权威服务器端信息,附加是可能有用的信息。

格式如下

  • 既然是对于回答的应答,那也该有对应,所以按照此思路设计
  • 域名:一种方式就是同Queries所陈述的一样,但是,出现重复的情况,我们可以设置一个指针指向那个域名,节省空间。这种偏移指针的方式,长度为两字节,最高两位指定为11后,就能识别这是一个偏移指针,剩下14位就用于指出偏移地址,以DNS报文开头为0
  • 对应Queries的有查询类型,查询类
  • 生存时间(TTL):这就是之前提到的为了缓存服务器而设置的。
  • 资源数据:前面铺垫这么多,就需要干货了。如果查询要的是A型RR,那就返回IPV4地址,是一个CNAME的RR,那就返回一个规范主机名。
原文地址:https://www.cnblogs.com/Idi0t-N3/p/13050126.html