RFC 7873 – Domain Name System (DNS) Cookies

DNS Cookie作为一个轻量级的DNS安全扩展功能,可以对于DNS服务器和客户端之间通信中存在的DOS攻击,放大和伪造攻击以及缓存中毒提供一定的保护。同时DNS Cookie的实施对于NAT和NAT-PT 和AnyCast广播不会产生任何的影响。

1 介绍

DNS早期开发阶段,主要面向的是一些可信环境和用户,因此设计协议的时候并未考虑太多的安全问题。但是现在DNS服务于全球互联网用户,可以看到不断出现的一些针对或者利用DNS协议实施的滥用行为的出现。

DNS Cookie作为一个轻量级的DNS安全扩展功能, 主要利用RFC6891(EDNS)定义的OPT扩展来实现。提供服务器和客户端之间有限的滥用防护。同时兼容其他的比如RFC5452定义的一些其他的DNS防护措施。

DNS Cookie主要是提供类似于TCP传输DNS消息的保护机制,TCP传输中攻击者需要猜测一个32bit的序列号,而DNS Cookie提供的则需要攻击者猜测64bit的伪随机Cookie值。但是前提是双方都必须支持DNS-Cookie才可以。

2. 安全威胁

2.1 DOS拒绝服务攻击

一种是伪造原地址发送DNS消息给服务器端,伪造的地址一般是被攻击的地址,这样服务器将所有DNS响应流量转到被攻击方。另外一种是直接性的DNS流量攻击,使得服务器由于无法处理而拒绝服务。对于第二种攻击,Cookie无法处理,但是这也提供了一种可以确定攻击来源的方式,使得可以采取进一步的措施去防护。

  • DNS放大攻击:攻击者伪造源地址,生成放大流量,转向被攻击服务器。对于实施强制DNS Cookie的这种情况下,可以验证双方,对于无效的客户端,返回错误消息,从而可以有效的减少甚至缩减攻击流量,使得放大无法实现,同时对于DNS Cookie还可以结合RRL实现有效的针对此类错误进行限速。
  • DNS服务器拒绝服务攻击: 攻击者通过大量服务器生成正常的流量,在此情况下,网络带宽被阻塞,或者如果需要做DNSSEC验证的话,服务器计算资源可能被占满。导致服务器无法继续提供服务。这种情况下,无法直接的进行基于IP地址的封锁或者限制。
2.2 缓存中毒以及响应伪造

缓存中毒主要是通过伪造的响应信息,在正确的查询返回之前,使得服务器提前接受,从而注入到递归服务器的缓存中,使其生效。一般较短的TTL记录资源更容易被实施这种攻击,通过实施Cookie可以直接拒绝伪造的DNS响应消息,使其失效。

3. 已有DNS安全措施

针对DNS的两种主要的安全方面是: 数据安全和消息传输安全。

数据安全:主要依赖于现有的DNSSEC实现,防止数据的篡改, 不仅保护已存在的数据,还对于不存在的数据提供认证确认(NSEC), 尽管可以有效的防止伪造数据和缓存中毒,但这项技术也带来了响应数据包的大幅度增加以及计算资源(加解密)的使用。

消息传输安全: 主要依赖于TSIG或者SIG等方式实现消息传递的安全,但是TSIG由于部署上的负担较大,并没有有效的得到部署。同时TSIG还要求较繁琐的秘钥分发管理措施,时间同步等前提条件,因此实际使用上较少。SIG(0)以及TKEY等方面尽管也可以提供一些安全传输方面的功能,但是都或多或少存在部署或者实施的问题。

因此对于已经存在的安全措施,并没有任何协议可以提供类似于DNS Cookie这样的轻量级,部署更加容易的方式的实现。

4. DNS Cookie实现

DNS Cookie的实现同样是作为EDNS扩展实现的一部分,作为一个Opt类型数据,存储在RDATA中,但是有两类的实现,这两种实现使用相同的OptionCode,主要区别在长度字段上。

DNS Cookie数据的长度是八个字节,也就是64bit的数据。以下是客户端发送的Cookie数据,客户端当前不知道服务器的Cookie数据,因此只包含自己的Cookie数据。

                         1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |       OPTION-CODE = 10     |       OPTION-LENGTH = 8       |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  +-+-   Client Cookie (fixed size, 8 bytes)             -+-+-+-+
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

如果客户端已知服务器的Cookie数据,因此传递的数据中需要带上服务器的Cookie信息, 此时的OPTION-LENGTH长度不是上面固定的8, 而是可变的16-40个字节长度。 服务器的Cookie的长度最小为8字节,最大32字节。

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |       OPTION-CODE = 10     |   OPTION-LENGTH >= 16, <= 40   |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  +-+-   Client Cookie (fixed size, 8 bytes)             -+-+-+-+
  |                                                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                                                               |
  /       Server Cookie (variable size, 8 to 32 bytes)           /
  /                                                               /
  +-+-+-+-...

Client端的Cookie应该由一个函数生成,函数参数包含客户端IP, 服务器端IP以及一个客户端自己的密钥共同生成,并且该密钥应该至少64字节长度,以及定期的修改。客户端通过逆向处理Cookie可以验证是否是自己生成的。

服务器端的Cookie 应当包含至少64位,且生成过程中的函数应该由客户端IP地址,客户端发送的Cookie以及服务器端的密钥共同生成, 同时服务器发送不同的Server Cookie到不同的客户端地址(具有不同的Client Cookie)

5. DNS Cookie 协议规范

DNS客户端发送每一个DNS请求的时候,都应当携带Client Cookie, 除非本身的Cookie机制被关闭。如果客户端具有一个缓存的服务器Cookie对应它自己的地址。应当同时将该Cookie附在RDATA中,否则仅仅发送Client Cookie即可。

服务器响应的时候,如果本身没有实施Cookie机制,简单的忽略DNS消息中的任何包含Cookie字段的信息, 并且响应中不会有Cookie信息的存在

  • 当Cookie启用的时候,存在五种情况:
    • 客户端发送的DNS查询不存在OPT RR,或者OPT RR不包含Cookie
    • Cookie数据存在问题,长度不合规范,无法正常解析
    • Cookie数据长度有效,但是没有ServerCookie
    • Cookie数据长度有效,存在ServerCookie,但是ServerCookie无效
    • Cookie数据存在ServerCookie也有效。

针对上面的五种情况:

第一种: 不存在OPT或者不存在Cookie信息, 服务器响应数据,就像本身没有开启Cookie机制一样处理。

第二种: 长度不合规, 比如长度太短,不足以存储任何Cookie信息,服务器响应FORMERR, 或者超出最大的Cookie长度也同样返回FORMERR

第三种: 对于仅仅包含Client Cookie, 针对服务器策略不同可以选择:

  • 简单的丢弃请求
  • 发送一个BADCOOKIE错误
  • 处理请求,并提供有效的响应,如果不存在其他的错误,应该返回RCODE=NOERROR

对于服务器选择2,3的时候,应该同时发送自己的SeverCookie给客户端,这样客户端可以在后续的请求中携带有效的ServerCookie查询,同时,服务器也无需保存状态。

第四种:有效的Client Cookie以及一个无效的ServerCookie: 服务器通过计算IP和客户端Cookie来获取服务器Cookie,确定是否有效,如果无效的话,则应该按照步骤三处理

第五种: 有效的Client Cookie以及有效的服务器端Cookie: 服务器端处理请求,并在相应的响应数据中要么复制原来的Cookie信息,或者生成一个新的ServerCookie+原来的客户端Cookie

DNS客户端在启用Cookie机制后,当接受到Cookie数据的响应信息,可以一定程度上假设数据为最初的查询所产生的,因为包含相同的Client Cookie. 同时应该检查DNS响应数据是否是包含合法的Cookie数据,防止数据伪造。客户端需要缓存服务器端的Cookie值,留作后用。

当客户端开启查询后,接收到任何BADCOOKIE,代表服务器端需要一个合法的cookie信息,因此客户端需要重试查询并携带正确的ServerCookie信息。如果仍旧获得该信息,则应该尝试使用TCP来完成传输。

同时实施上服务器可以通过接受查询内容为空,也就是QCOUNT=0的查询,响应信息携带必要的Cookie信息,但是如果服务器没有实施该方式,应该响应FORMERR的错误。

6. NAT及任意播问题

针对NAT的问题,对于一个NAT后面的多个客户端,如果ServerCookie仅仅依赖于客户端的IP,则可能出现无法区分每一个客户端的问题,也会存在一定的安全风险,比如这群NAT后面的客户端存在一个僵尸机器,该机器可以得到服务器的针对其他机器产生的ServerCookie并利用该cookie伪造查询。为此ServerCookie的产生一般通过混合了ClientIP以及ClientCookie的方式。Client Cookie 则一般通过服务器IP以及一两个变化不大的内容比如Client的密钥作为辅助生成。

对于AnyCast的方式,为了保证Cookie的实现, 通过1. 复制所有的服务器密钥配置。2 分发某一类请求到指定的机器处理,比如IP地址段。 但是推荐使用第一种方式,实施起来更简单一些。

7. 运维部署问题

DNS服务器和客户端实施了DNSCookie, 可兼容没有实施的客户端或服务器 并进行交互通信。部署和运维上面需要考虑的几个方面包括:

  • 客户端和服务器的密钥轮转, 缺省是一天,最大允许一个月。
  • 服务器端的ServerCookie应当在轮转后,一段时间内原来的Cookie保持有效,并返回新的cookie,默认为150秒的时间
  • 客户端推荐保持原有的Cookie直到不再有于此Cookie相关的外发请求正在处理中。避免由于修改ClientCookie导致错误的ClientCookie问题。
  • 客户端的秘钥修改应该保持一定的间隔,不要选择同一时间的修改,减少一些安全风险。

8. IANA分配资源号

分配的option类型码以及对应的错误的RCODE码, 如下面所示:

        Value       Name      Status        Reference
    --------   ------   --------   ---------------
        10       COOKIE   Standard       RFC 7873
       
      RCODE       Name       Description                 Reference
    -------- --------- -------------------------   ---------------
        23     BADCOOKIE Bad/missing Server Cookie     RFC 7873

9. 安全问题

DNS Cookie的部署可以显著的减少放大攻击以及拒绝服务攻击中的伪造问题,但是无法处理一些传输“”路径“”上的攻击的发生。

路径指的是可以直接观察明文DNS流量的传输通道,比如传输交换机,路由器等等,另外的例子比如我们使用无密码保护的WIFI也被认为可以被直接观察流量,而WPA2保护的则只有路由器本身属于路径,其他访问节点则不属于路径。

同时攻击者不知道ServerCookie的情况下, 可以发送没有Cookie Option数据或者伪造ServerCookie, 服务器需要做一定的RRL去实施必要的保护,防止滥用。

当服务器接收到突然增加的BadServerCookie的时候,基本上可以确定遭受到了攻击,从而采取必要的措施进行保护。

实施Cookie生成算法,也要实现必要的保护强度,也要保证不要给服务器带来太多计算的负担。可以通过更加频繁的更换密钥的方式补偿一些更简介高效的算法。

客户端Cookie生成实例一 :

其中|代表了追加,FNV64算法是一种处理算法。

      Client Cookie =
        FNV64( Client IP Address | Server IP Address | Client Secret )

客户端Cookie生成实例二:

该方法可能需要更多的计算资源来实现

      Client Cookie =
        HMAC-SHA256-64( Client IP Address | Server IP Address,
                        Client Secret )

服务器端Cookie生成实例一

      Server Cookie =
        FNV64( Client IP Address | Client Cookie | Server Secret )

服务器端Cookie生成实例二

如下为Bind实现找那个采用的一种方式,获得的Cookie大小为128bit, 每次发送的都是新的ServerCookie.

       hash =
          HMAC-SHA256-64( Server Secret,
              (Client Cookie | Nonce | Time | Client IP Address) )

发表评论

邮箱地址不会被公开。 必填项已用*标注