Mike Zhang

DNS DevOps CISSP CISA Security+ 摄影 程序员 北京

RFC2181 对于DNS规范的一些说明

15 Oct 2018 » dns, rfc

1. 概述

本篇RFC主要是对于DNS协议及其规范中存在问题的地方进行补充说明,并提出一些方法去弥补已存在的缺陷。主要针对以下8个方面:

  • 具有多个IP的服务器上,IP数据包头地址的选择使用
  • 资源记录集中对于相同名称,类别和类型记录的TTL使用
  • 区划分处理
  • 三个关于SOA记录的问题
  • TTL的精确定义
  • TC比特位
  • 权威应答及CNAME
  • 有效的DNS标签

其中前6个仅仅是说明上可能不够清楚,在此做一些补充说明,剩余的两个已经给出了详细充分的说明,然而这些说明有时候却被忽略。

2. 介绍

过去的几年间出现了一些关于RFC1034,和RFC1035规范的一些问题,这些问题都是相互独立的,比如具有多IP地址的服务器在响应DNS查询的IP数据包源地址的选择;同一个RRSets中TTL使用的问题;以及CNAME和权威应当相关的问题等等。澄清一些DNS规范来避免出现该问题,本篇RFC同时修改了RFC1034中关于TTL定义以及如何使用TC bit的模糊说明。

3. 术语

本篇文章不会使用MUST, SHOULD, MAY(必须,应当,可以)以及对应的反义词。有些地方描述的比较温和,反而让人认为是可选实施的。这是不对的,任何在本文中出现的建议执行的方式,或者必须执行以及一些行为是可被接受的等等都被认为是规范的基础部分,而不用管术语表达。如果一些行为真的是可选,文章中会说明。

4. 服务器的源地址选择

大部分的DNS客户端,都会期待响应的数据包中的源地址和发送数据包中的目的地址一致。这对于一些递归服务器查询权威也是一样的(递归服务器作为客户端)。DNS最初设计可能并没有考虑过这些问题,但是至少现在的情况是这样的。

用户发送DNS查询到服务器,但一些多宿主主机在运行DNS服务器时却使用另外的地址去响应用户的查询,这些响应信息由于地址不匹配的原因会在客户端被抛弃,这就好像是一个未经请求的响应信息。

4.1 UDP源地址选择

为了避免这样的问题,服务器响应UDP查询的时候必须设置源地址与发送数据包中的目的地址匹配一致。如果这会导致从一个IP地址发送的响应数据包不被允许,这个响应应该从服务器分配的其他合法的IP地址发送。 这个地址应该尽量保证客户端是可以进一步查询使用的,当服务器这样配置的时候(并非所有地址都对于客户端是可达的)在应对AnyCast或者组播的时候需要特殊考虑

4.2 端口号选择

发送的响应数据包选择端口号应该与查询的数据包中源端口一致,这在TCP查询中是默认的配置,但是对于UDP必须记录下源地址,并将其作为目的地址进行封包。除非特殊情况下,使用默认分配的DNS查询端口号(53)

5. 资源记录RR Sets

每一个DNS资源记录都具有一个Label,类别, 类型和对应的数据,不允许两个记录这些内容都是相同的,服务器应该去重保持数据的完整,但是允许资源记录具有相同的label, 类别和类型但是具有不同的数据,我们把这些成为资源记录集:

google.com.		345600	IN	NS	ns4.google.com.
google.com.		345600	IN	NS	ns1.google.com.
google.com.		345600	IN	NS	ns2.google.com.
google.com.		345600	IN	NS	ns3.google.com.

5.1 发送资源记录

任何查询相同域名,类别和类型的数据都应该返回整个的资源集,不管这个集合是包含一个还是多个的资源记录。如果响应超出了最大的数据内容长度,应该对于数据包标记为TC=1。

5.2 TTL设置

资源记录具有生存时间(TTL), 一个资源集中的资源可以包含不同的TTL, 但是并未发现这种用法的好处,但是却有可能导致一些问题,特别是缓存服务器缓存的数据可能不全(部分数据已过期)。因此不推荐使用不同的TTL的方法,尽量保持一个集合中的资源记录具有相同的TTL时间。

客户端接收到具有不同TTL资源记录的资源集合应当认为是一个错误的数据。特别是来自于非权威的服务器的时候,应该忽略该查询,转而向权威服务器进行查询。

如果权威服务器发送这样的数据的时候,客户端应该按照最小的TTL进行处理,但是服务器应该发送相同的TTL资源集。

5.3 DNSSEC 规范

由于已经更新,此处略过

5.4 接收RRSets

服务器不能合并缓存的资源记录去形成一个新的资源记录集,如果一个查询响应包含将于服务器缓存数据形成资源记录集的数据,服务器应该忽略响应中的资源记录或者丢弃整个的资源记录集。因此也就不会产生关于TTL在缓存和响应数据中不一致的问题,如果来自于响应的数据和缓存中的数据不一致,其中必有一个是不正确的。

对于服务器所面临的问题则是需要区别到底哪些数据是正确的,哪些不是。如果接收到的数据和缓存中的数据仅仅只是TTL不同,可以选择性的更新TTL。如果接收到的响应数据更加权威,则应该执行更新操作

5.4.1 数据排名算法

基于上面的问题,一个服务器应该考虑数据的相对可信性来决定选择哪个数据。一个权威的应答应该替换缓存的数据(缓存来自于之前应大众的additional字段。在缓存中已经存在的来自于权威区的应答的时候,额外的字段信息中包含相同的记录应当被忽略。

数据的选择应该基于它的来源,可信度从高到低的排序如下:

  • 数据来自于一个权威区内容,而不是glue记录
  • 数据来自于区传输,而不是glue记录
  • 权威应答数据包含在权威响应的应答字段
  • 存储在权威应答中的权威字段
  • glue记录来自于主区,或者来自于区传送
  • 数据来自于非权威响应的应答字段,非权威数据来自于权威应答的的响应字段
  • 权威应答的Additional信息,数据来自于非权威应答的权威字段 ,非权威应答的Additional字段

一般来自于权威应答的响应字段仅仅包含权威的数据,但是当考虑到是一个CNAME记录的时候,仅仅别名是必要的权威数据。 客户端应当假定其他的记录来自于服务器的缓存。当需要权威应答的时候,客户端需要使用CNAME的记录重新查询

对于上面的信任度较低的来源,数据来自于Additional字段和数据来自于非权威应答的权威字段不应当被缓存作为对于记录查询的响应。这些数据可能会被返回作为适当的Additional信息。忽略这一点的话也将导致相对不信任的数据的可信度没有任何原因的被提升。

请注意的是,glue记录在两个正确配置的主区域文件,或者两个正确配置的辅助区域(来自区域传输的数据)或来自正确配置的主区域和辅助区域的数据的数据是不可能发生冲突。如果同样的Glue记录存在于不同的区的时候,当他们的值不同的时候,名称服务器应该选择来自于主区的数据而不是二级区数据,或者选择任何一个数据集。选择那些靠近权威数据源的数据可能更加合适,当存在这种问题的数据时,选择主数据而不是二级区的数据可以更容易的发现不正确的配置。当一个服务器可以检查两个区文件配置不一致的时候,应该拒绝加载区文件并进行适当的诊断。

上面提到的Glue记录包含任何不确切属于该区域的记录,以及委托的子区域的NS服务器记录和对应的地址记录,和可能出现的任何其他的杂散数据。

5.5 发送资源记录

任何资源记录集应当仅仅在响应中出现一次,可以是在响应中,权威记录中或者是Additianal字段。但是有一个例外是SOA记录,在查询AXFR的时候,要求头部和尾部同时传输SOA记录。重复发送的情况下,每一个的TTL传输必须一致。

6. Zone划分

DNS树形结构被划分到多个区中,这些属于同一个区的域名作为一个管理单元。 划分区将从父区里面分离出新的子区。出现在区顶部的域名称之为区的Origin, 区的名字和Origin域名一致。每一个区包含DNS树形结构中的子树(区的Origin以及以下的部分), 父区里面包含子区的NS记录,但子区里面不包含父区的任何引用

6.1 区权威

区权威域名服务器存储在区文件中的NS记录中,与SOA一样都是必须存在的。用于划分区的NS记录和其他的子区的域名记录都是子区的属性, 同时一个域名服务器不应该返回其他区的域名的权威响应,除非这个服务器也同时作为其他区的权威。

6.2 DNSSEC问题

关于DNSSEC请参考具体DNSSEC相关的RFC,已做更新

7. SOA资源记录

SOA资源记录中有三个主要问题需要重新澄清一下。

7.1 权威应答中的SOA

如果响应中加入SOA记录,应当放置在权威应答中,比如下面的查询域名不存在的时候,响应的消息中包含SOA记录:

               +---------------------------------------------------+
    Header     | OPCODE=SQUERY, RESPONSE, AA, RCODE=NE             |
               +---------------------------------------------------+
    Question   | QNAME=SIR-NIC.ARPA., QCLASS=IN, QTYPE=A           |
               +---------------------------------------------------+
    Answer     | <empty>                                           |
               +---------------------------------------------------+
    Authority  | . SOA SRI-NIC.ARPA. HOSTMASTER.SRI-NIC.ARPA.      |
               |       870611 1800 300 604800 86400                |
               +---------------------------------------------------+
    Additional | <empty>                                           |
               +---------------------------------------------------+

7.2 SOA资源记录中的TTL

所有的RR记录都设置有TTL字段,用来设置缓存时间,RFC1035最初的描述中记录SOA记录应该设置其TTL为0防止缓存被设置,但是后来从内容中删除了该描述。

这种要求没有在任何其他地方出现过,因此软件实施不应该认为SOA记录的TTL为0,也没有被要求设置SOA记录的TTL为0

7.3 SOA中MNAME信息

规范中声明了MNAME域的信息应该包含SOA所在区的主服务器的域名信息,不应该包含区本身名字。设置成区名字是没有用的,因为为了查询这个信息你需要找到域名的SOA记录,而这就是区的名称。

8. TTL生存时间

TTL生存时间设置应该以32位无符号整数标示,也就是范围为[0, 2147483647], 该值应编码在32位TTL字段的较低有效31位中,最高有效位或符号位设置为零。

如果接收到的TTL的最高比特位被设置为1,则忽略该数值,设置TTL为0

实施的时候可以自由的设置TTL上限,并将任何大于该边界的TTL的值为边界值,TTL定义的是最大生存时间,而不是强制的生存时间

9. TC标志位

TC标志仅仅在作为响应的资源记录没有充分的空间来存储的情况下设置,接收到这样的请求后,应该忽略响应的数据包。TC标志位不应在额外信息的存储空间不足的情况下被设置,这种情况下应该取消发送这部分信息,设置TC为0并发送数据,如果接受者确实需要这部分信息,则应该重新发送新的查询请求。

TC被设置为1的时候,部分RRSet无法放入响应数据包,当一个DNS客户端接收到一个设置了TC的响应, 应该忽略数据包,重新发送查询,比如使用TCP连接,这种方式可以允许发送更大的数据包了

10. 命名问题

DNS规范中并没有要求一个主机或者主机的一个接口只能有一个权威或者官方域名或者CNAME名称。

10.1 CNAME资源记录

CNAME记录用来提供域名的别名功能,CNAME记录指向的域名应该在其他地方被定义解析,但是有一些情况下,对应的域名是未定义的(并非强制存在),一般将CNAME记录的标签称之为“a CNAME” . 但是不幸的是,CNAME是规范名称的缩写,而一个CNAME记录的标签可能是最不像是规范名称的, 这时一种根深蒂固的用法,本文中CNAME资源记录的标签将一直指向一个别名记录。

10.2 PTR记录

一个域名的PTR记录不一定只有一个。PTR资源记录的值,也就是返回的域名必须不能是别名。尽管PTR记录的值不能是别名,但并没有要求处理过程中不会遇到别名。查询PTR记录的域名可能有一个CNAME记录,也就是他可能是一个别名,CNAME资源记录的值将给出查找PTR资源记录的位置。

10.3 MX和NS记录

NS记录和MX记录的值不能是一个别名。不仅仅规定定义,而且如此配置也会导致不能正常工作。这两个记录的值可以是一个或者多个地址记录,当前必须是A记录,但是或许将来接受其他的类型记录,但是不能是CNAME记录。

NS记录或者MX记录的实际地址查询将导致额外的一些查询,使得真正的地址记录追加到响应的Additional数据中。如果一个别名记录作为NS或者MX的值,additional字段将不会返回任何的数据内容,这也就会导致查询的失败,因为这种配置会导致在每次域名查询的时候都导致更多的额外查询。为了解决这个问题,只需要将正确的NS地址或者MX地址放在区数据中,而不是使用别名记录。

11. 域名语法

有时候认为DNS服务器仅仅能够映射主机域名到数据,或者映射互联网地址到主机名,这是不正确的,DNS是一个通用的分层数据库,可以存储几乎任何的数据,以及任何的目的。

DNS本身仅仅的限制是长度不能超过255字节,单个label的长度不能超过63,0长度代表了根节点,通常被写作“.” 实施DNS协议不应该增加任何其他的限制条件,同时DNS服务器也不能因为某一些DNS客户端的原因而拒绝去加载区数据。 DNS服务器可以配置去当主区的数据可能出现问题的时候提示告警或者拒绝加载,但是缺省是不应该出现的。

不同的应用在使用DNS的时候可能加入一些限制条件,比如声依永MX记录的视乎,任何二进制的Label 可以具有MX记录不代表任何人都可以使用任意的二级制名称作为邮箱名称。因此客户端的限制,应该由客户端去全权负责做数据的验证,确保符合自身的使用规范。

12. 安全问题

本篇文档不包含任何安全相关的内容,文档中内容也没有增加任何安全相关问题,或者必要的缓解安全的方式。正确的理解和澄清原来RFC的内容可能从某些方面减少DNS中错误数据包的产生,但是只有DNSSEC才能帮助处理故意伪造的DNS数据