自去年开始,DDOS 攻击已经上升到了一个新的高度,其标志性攻击是针对国际反垃圾邮件联盟和 cloudflare 的大规模 DDOS 攻击,流量一度达到120G,当然后面的 DDOS 远远超过了120G,不过这一次攻击确实是历史性的。
我们现在回过头去看这些攻击已经清楚他们的攻击来源是 DNS/NTP 等反射攻击导致的,但是为什么 DNS和NTP 等服务具有如此厉害的能力呢?攻击者是如何做到制造出如此巨大的流量的呢?DNS 这个在我们日常网络使用的时候再平常不过的服务是如何被利用来变成大规模攻击的呢?
我们现在先提前给出最终答案,然后再进行解释:
1、DNS 使用了简单的 UDP 报文进行客户端和服务端之间的通讯;
2、DNS 是纯天然的流量放大器,通过极小的请求返回很大的回应数据包;
3、互联网上充斥了大量的开放 DNS 解析器,它们可以接受任何客户端的请求而不会拒绝;
4、网络的滥用导致很多地方可以发出伪造源 IP 地址的数据包。
这四个方面的问题最终结合到了一起,形成了现在的 DNS 系统的格局,也使 DNS 系统成为了 DDOS 攻击的重要问题来源。一次正常的 DNS 请求可能发出的流量只有64bytes,但是它收到的回应可能远远超过这个数,在某些特定场合下,这个流量被放大的比率可以轻轻松松超过50倍。按照这个 比率计算,如果通过一个僵尸网络来同时发送 DNS 请求的话,那么生成G/s的流量是十分轻松的,如果是使用了 DNSSEC 的话,流量还将更大。
现在的问题在于,实质上这些流量和其他流量一样都是看似正常的流量,所以简单的过滤机制对此将不起作用,我们需要寻求更深层次的解决方案来解决这个长期困扰互联网的问题。
在这个问题的讨论上,其中一个讲到如果大家在实施网络的时候都按照 BCP38 来实施的话,可以阻止虚假 IP 地址发送 DNS 请求,从而阻止了利用 DNS 进行反射放大的攻击。当然这个话题已经久到比 BCP38 本身还要早,BCP38 作为一个文档已经存在了13年之久,但令人不爽的是这仍然未能改变在过去的13年里层出不穷的源 IP 伪造攻击,所以在未来数个月甚至若干年内我们也不要对此报太大期望。
另外一个讨论是说解析器应该实施应答频率限制(response rate limiting,RRL),默默地将超过阈值的重复请求丢弃掉,这个对于权威 DNS 来说确实相当的有效率,但是对于递归解析器群来说效果就差很多,因为攻击一旦散步到各个递归服务器,那么分摊下去之后能够检测到的频率就可能达不到检测阈 值。尽管如此,权威 DNS 服务器实施 RRL 仍然是很好的选择。
另外一个讨论是说,关闭掉这些开放递归查询服务器,open resolver project(http://openresolverproject.org)这个项目就是准备干这个事情的,让开放查询服务器的维护者自行检查配 置,把有问题的查询器关闭掉,和 BCP38 的被接收程度差不多,也不要太指望这个途径能有太大作用。部分原因是因为大量的递归服务器都疏于管理。
DNS 服务器接收小包请求产生打包回应的这一行为已经成为了 DNS 的固有属性,特别针对 DNSSEC 而言更是如此,我们既想要对 DNS 解析结果有安全保障,又想要速度快,那么必然会选择 UDP 协议,结合上无处不在的递归 DNS 查询服务器,这就导致了回应包的变大,最终导致了这一平台成为了大流量攻击的神器。
如果我们想要彻底解决掉利用 DNS 进行大规模攻击的难题,留给我们发挥的空间已经很小很小了。然而仍然还存在一个关于 DNS 是否使用 UDP 的看法在延续。
在原版 RFC1123 中允许了 UDP 和 TCP 两种方式作为 DNS 服务的协议,与此有关的一段是这么描述的:
“在不久的将来新的 DNS 记录类型会超过512bytes的限制已经非常明显,据此基于 TCP 的 DNS 是需要的,所以递归解析器和权威服务器需要支持 TCP 方式提供服务作为当下使用 UDP 方式的后备方案,今后必将用到 TCP 方式。”
(为什么是512bytes呢?这个限制是来自于ipv4 主机需求定义(RFC1122),所有支持ipv4的系统都必须能够接收至少576bytes,20bytes的IP header,8bytes的 UDP header和40bytes的ip options,这就决定的单个 UDP 包的大小最大就512bytes)
现如今 IPv4 中生成更大的包已经成为可能,理论最大可以达到65535bytes,UDP包大小可达65507bytes,但是如此大的包在传输过程中是会被分片的, 在这种情况下,典型的防火墙规则能够对其后的包进行阻断,可能导致其无法到达客户端,这是由于很多防火墙是基于 UDP 和 TCP 端口地址的。因这些被分片的包本身并不包含 UDP 或 TCP 头部,这使得防火墙陷入了窘境,到底是允许呢还是允许呢?这种情境下防火墙可能最终妥协继而使得部分攻击得逞。或者是丢弃掉所有的分片?考虑到这两方面的 因素,传统 DNS 的做法是限制 UDP 回应包大小为512bytes,且当包大小超过512bytes的时候总是启用 TCP 作为备用措施。
然而,客户端或许并不知道 DNS 回应包的大小会超过512bytes,所以为了通知客户端使用 TCP 来接收整个 DNS 响应, DNS 解析器会发送给客户一个设置了"truncated"位的回应。
我们一直在这个途径上坚持了很多年, DNS 在大多数情况下使用 UDP 进行通讯,只有在极少情况下才会启用 TCP 通信。这种做法在后来我们考虑为 DNS 解析添加安全证书机制的时候就显得不是那么爽了,随着 DNSSEC 的加入已经很少有响应包可以做到不超过512bytes了,由 UDP 转换为客户端通过 TCP 重发的机制势必会导致解析的延迟。
就像 RFC5966 中写的那样:
由于 DNS 的核心原型已定, DNS 扩展机制也被提出(EDNS0 RFC2671),这套机制可以用来表明客户端可以接收大小超过512bytes的包,一个 EDNS0 兼容的客户端向兼容服务端发送的包可以是由客户端 buffer size 大小指定的包大小而无需分片。
EDNS0 允许基于 UDP 的回应包拥有更大的大小,这时 TCP 已经被当作武功秘籍而为被广为流传了,仅仅被用来做域传送,如果不想启用域传送的话,似乎 TCP 就完全不起任何作用了。
在 RFC1123 中有关主机的必要条件是这么描述的:
DNS 解析器和第归服务器必须支持 UDP,可以支持 TCP 来发送查询请求。
但是基于 TCP 的 DNS 不光是可以支持较大的 DNS 响应,如果我们重新审视一下大规模 DNS 反射攻击的先决条件,普遍的 UDP 大包响应,以及缺乏实施的 BCP38,使得攻击者可以通过源 IP 伪造的手段对目标进行攻击。
TCP 不会出现此问题,如果攻击者通过伪造源 IP 来发起 TCP 请求的话,目标 IP 顶多只会收到一个很小的包,(40bytes),只包含了 SYN 和 ACK 标记,目标系统由于没有已经建立了状态的连接,这个包将会被丢弃掉,根据本地配置的不同,目标 IP 可能会发送一个 TCP RESET 包给另一端来表明 state 的不确立,或者仅仅是默默的丢弃掉,这样 DNS 攻击的流量放大作用就没有效的解决掉。
如果说 DNS 系统已经使得整个互联网面临了如此巨大的问题的话,那么是否我们就应该停止使用EDNS0所支持的较大的 UDP 回应包,继而使用 TCP 来传输较大的请求?
我们再来看一下 RFC5966:
多数 DNS 服务运营商已经支持 TCP 且默认的软件配置也是支持 TCP 的,此文档的主要受众是那些。。。
这个地方我们需要看到的问题是,我们如何能够量化 DNS 支持 TCP 请求和回应的覆盖度?这里只的“多数”到底是多少?
通过测验发现,大部分的 DNS 系统对 TCP 类型的报文是可以响应的,也就是说,利用 TCP 来回复大包以组织 DNS 使用 UDP 发送大包这一做法是切实可行的,不支持 TCP 的那部分 DNS 系统要么是由于主备DNS的配置导致其请求第一个服务器不通进而请求下一个服务器,要么是一些其他的问题,也就是说,在处理TCP有问题的DNS服务器里 也只是有部分是真实存在问题的。
如果你是DNS系统管理员的话,我们建议:
1、尽量不要维护一些很小的开放DNS解析服务,这些事情是网络运营商该干的;
2 、权威DNS一定要对请求频率加以限制,如果是使用 bind 的话可以利用 bind 自带的 RRL 个功能进行频率限制,如果是 PDNS 的话可以通过防火墙规则来限制;
3、对 DNS 系统进行全面的检查,对 DNS 系统进行配置检查,以防止出现一些低级错误等。只有通过多方面的努力,才能将 DDOS 攻击影响逐步小化。