xiaoemo0 2020-02-20
这一篇文章描述DDoS流量清洗实现的一些思路。
假设有这样一种场景:一个武林高手和一个基本没有功底的人切磋武艺,胜负如何是无需多言;换另一种场景,如果是十个普通人和武功高手对招,虽然可能费点力气,但是武功高手还是可以再拿下一城;更进一步假设,一百个毫无底子的成年人一拥而上,和这名高手对打,如果高手的武艺有如当年镇守襄阳城的郭靖,还是有胜算的;最后,如果是一千名、一万名普通人对武林高手群殴的话,我猜就算是达摩祖师,估计也难以抵挡得住。
DDoS攻击,就像上面扫描的场景:一个恶意IP的请求到达服务器,应该掀不起什么波浪;但如果是成千上万台恶意肉鸡对同一个域名发起DDoS攻击,威力是绝对不容小觑的。更何况,现在几十万恶意肉鸡发起的攻击,都已经司空见惯,以后随着入网的物联网设备增多,参与攻击的肉鸡数量相比如今,可能数量级还会再往上升一级。
再回到刚才假想的最后一种场景,如果武林高手想要夺回主动权,他应该怎么办?可能会有几个办法:第一,请帮手,拉更多的人加入对抗;第二,找一个狭长的地方,一夫当关,万夫莫开,纵然对方人再多,也只能一个一个过来挨揍;第三,找一个很高或者说普通人很难上去的地方,一般人爬不上去,提升这一批人和高手过招的门槛。
对应到DDoS的攻击防护中,处理的思路颇有相似之处:第一,对服务器做横向扩容。如果后端源站数量足够多,处理性能足够强劲,再加上如果能够弹性扩容,这样对方想把应用搞瘫,也绝非易事。当然这种方法成本太高,对于传统未上云的企业来说,会造成资源的浪费。第二,对访问流量做限流。按平时的业务访问情况进行评估,针对单个访问用户实施限流,避免出现一些异常访问源的请求量过大,影响业务。同时如果到达目标服务器的流量太高,可能会超出服务的处理性能,通过对目标进行限速,可以保证服务器不挂,至少业务是不会完全中断的;第三,对于不合法的流量实施过滤。事实上,互联网上的很多攻击流量,特别是SYN Flood攻击,都会携带比较大的payload,这样一方面可以消耗服务器的连接性能,同时也可以堵塞带宽,造成网络拥塞;对于这种畸形报文的攻击,清洗设备是可以直接将其过滤掉的。第四,对访问源做认证,提高对服务器的访问门槛。只有经过认证的请求,才可以被送到后端的服务器。按照理想的情况,所有的肉鸡均是异常IP,理论上都不应该通过清洗设备的认证。
第一种思路是对不合法的流量实施过滤。具体的过滤手段比较多,在以太网中正常传输的数据报文,会有以太帧头、IP头部、TCP头部、应用层payload信息。对于不同层次的协议字段,都可能作为流量过滤的依据。首先,针对IP协议、TCP/UDP协议、或者一些常见的应用层协议如HTTP,都会有RFC文档说明,进行通信协议标准的定义,描述各个协议字段的具体含义以及合理的取值范围。如果报文内容不符合RFC协议规范,或者报文中的不同字段,出现了本不应该出现的组合方式,我们就认为这些报文是畸形报文,可以将其过滤掉。最常见的是SYN畸形包,正常的TCP三次握手的第一个SYN报文,是不应该携带payload内容的。(当然如果在协议中开启了了TCP fast open,可能也会携带有payload信息。不过在现网流量中,目前还没有遇到这种类型的访问流量,应该来说,应用还是极少数)而现有的很多压测工具,例如hping,发出来的SYN压测流量,就是典型的畸形报文,是可以做为不合法报文进行过滤的:
其次,客户端发送到服务器的请求报文符合RFC描述的协议规范,但是在实际的应用场景中是不应该出现的。举个例子,从IP协议层来说,运营商网络中应用的uRPF配置,可以阻断掉虚假源ip发起的攻击;在很多场景下,一个应用可能只允许某些IP,或者某些区域的IP地址访问,那我们可以根据源IP地址及其来源地区实施过滤,这就是很多网络设备或者安全设备都具备的ACL功能。从应用层的识别来说,如果一个WEB类型的应用,只接受GET、POST请求,那就可以把HEAD、PUT等请求过滤掉。诸如此类的阻断思路,我都把它们归于不合法流量的精准匹配过滤这种场景当中。
身份认证在信息安全领域,应用范围相当广泛,认证技术也多种多样:口令认证、密钥认证、手机短信认证、生物特征认证等等。而在DDoS防护领域,认证也是很重要的一种识别攻击者的手段。但是DDoS的认证又相对特殊:正常的认证是服务器和客户端之间的互动行为,服务器询问客户端知道什么,或者拥有什么;客户端提供相对应的内容,就能通过服务器的认证。DDoS防护设备的特殊之处在于它处理的是网络层的攻击,它所处的位置决定了它不能像服务器一样,和客户端进行互动。现在很多认证手段是在客户端植入SDK,用于和服务器进行认证。但是一些使用标准客户端的程序,是没办法集成SDK的,比如使用浏览器访问服务器网页,或者使用微信H5页面访问服务器。这些场景下,客户端都是没办法植入SDK的,但是服务器照样可能遭受ddos攻击。DDoS防护设备,当然还需要对这种场景下的服务器进行防护。
从上面的描述来看,DDoS场景下的认证大致可以分为两种:如果没办法集成SDK的,可以使用基于网络协议的反向探测认证;如果用户有自己的客户端,可以可以接受嵌入SDK的,则可以使用基于加解密算法的认证方式。基于网络协议的反向探测,粒度会相对比较粗,思路是对客户端的网络层行为进行认证。清洗设备截获客户端发往服务器的请求报文,并构造特定的响应报文回给客户端,以观察客户端的这些报文做出的响应动作。如果响应行为符合预期,则将客户端地址加白,放行该IP地址的后续报文;如果不能通过认证,则直接把请求报文丢弃或者直接把源IP拉黑。
举两个实际使用场景中的例子:在SYN Flood防护中对源ip地址的探测、首包丢弃等,就是利用了TCP协议的可靠传输及超时重传特性。
对第一个包丢弃处理,等待TCP握手的重传。
对于应用层来说,也有着类似的检测机制。例如截获客户的GET请求,对客户端回送302跳转报文,或者通过setcookie要求客户端携带随机的cookie值,亦或是给客户端回应一段JS代码,需要客户端能够返回对应的验证结果,这些手段,都是利用网络层或者应用层协议的特性,对客户端进行粗粒度的认证。
利用网络层协议特性进行认证,它的好处在于适用性比较强,只要是采用了TCP通信协议,就可以使用SYNCookie的验证手段;只要是HTTP客户端,就应该能够响应302跳转。另外一个好处就是这种验证手法对于客户端是无侵入的,不需要对服务器和客户端做任何改造,只要服务器、客户端遵循对应的网络协议,就能够使用这种认证方法。不好的地方是对网络通信是有损的,增大了网络报文的交互。因此在对时延要求比较敏感的情况下,这种认证方式使用面不广。而且正是因为这种手法的适用面太广,如果肉鸡也具备对应网络协议栈的行为,就能够突破清洗设备的认证。
使用SDK是另外一种认证手法,在客户端接入我们提供的SDK,和清洗设备进行认证。通过鉴权的客户端能够正常和服务器建立连接,没有通过认证的客户端则被阻断掉。这种方式是比较安全可靠的手段,但是缺点是需要被防护的用户对自己的客户端做改造,接入SDK,提高了成本。目前在大流量防护领域,这种方式的使用不是很广,可能在更精细化的攻防对抗领域,会有更多的应用场景。
还有一种防护思路,就是实施限流。限流的对象可以是请求源,也可以是被访问目标。限流的维度也比较多,比如可以是源/目的ip地址、源/目标新建频率、源/目标会话数、URI的访问次数、cookie出现频率等等。无攻击时,可以基于单个源ip,或者单个源用户做基线统计,评估正常的业务水位。在被攻击时, 设置限流的门限值,超过门限值时即采取指定的动作。这种方式可以认为是一种兜底的方式,特别是基于目标的限流,可以保障服务器不挂,但是难免会出现对正常的访问请求产生误杀,这种方式对正常业务是会有一定影响的,在实际使用过程当中需要根据具体情况进行取舍。
随着攻防对抗技术的不断演进,防护也在慢慢朝着自动化、智能化的趋势发展。智能化防护依托于底层设备丰富的数据支撑,自动识别攻击用户的恶意行为,实施自动化防护。目前智能防护在阿里云高防产品的攻击防护中,已经普遍使用,并且也取得了不错的效果。