攻击种类
大家肯定都熟悉OSI七层模型,ddos攻击最常出现在第三层(网络层)、第四层(传输层)、第六层(表示层)和第七层(应用层)。第三层和第四层的ddos攻击一般被统称为基础设施层攻击,一般通过模拟大量三四层的报文如icmp、udp、tcp来让服务器进行响应,从而达到消耗服务器资源的目的。这种攻击是最常见的,也是最简单的,甚至开源了很多工具如hping3来模拟这种ddos攻击。正因为这类攻击有一些独有的特性,也使得开发者可以比较容易的识别出这类攻击从而进行防范;第六层和第七层的ddos攻击一般可以归为应用层攻击,这类攻击通过模拟应用层的请求如http来让服务器进行响应。这类攻击没有第一类常见,因为攻击者必须了解服务端应用程序工作方式,需要构造更加复杂的请求,比如某登陆页的http请求、某dns服务器的dns请求。这一类攻击都是正常的请求,所以也更难防范。
常见ddos攻击
畸形报文
这种攻击有一点以巧取胜的意思,它并不需要很大的数量,也许只需要一个特殊的报文就可以导致服务器的崩溃。所谓畸形报文,就是指那些不符合协议规定的报文,比如tcp头的SYN、RST标志位都置1的报文;比如ip头例源地址和目的地址都是同一个的报文等等。
udp flood
攻击者利用udp无状态的特点,向服务器的不同端口发送udp报文,服务器收到之后会寻找对应端口的应用程序,如果没有找到,会返回“目标不可达”的消息。攻击者往往会通过伪造源ip来达到隐藏自己身份的目的。这种攻击方法以量取胜,一旦服务器被攻击流量淹没,那就无法响应正常用户的请求。
icmp flood
攻击者想服务器发送大量icmp报文,服务器收到之后会回复一个icmp echo给源地址。这种攻击和上面的udp flood攻击类似,可以看到攻击请求和服务器响应流量是1:1的关系,“性价比”并不高,现在已经很少看到了。
syn flood
最常见最知名的一种攻击,它的防御方法甚至被写进了linux内核。攻击者利用了三次握手的机制,发送大量第一次握手的syn包给服务器,并且无视服务器返回第二次握手的synack包,故意不发送第三次握手,导致服务器大量端口处于SYN_RECV状态。由于服务器收不到第二次握手的报文,超时重传,重传一定次数之后,才会释放连接。服务器的这个状态我们一般称为半连接,要知道服务器能每收到一个syn包时,都会将连接信息储存到一个队列中,这个队列肯定也是有长度的,当超过队列长度时,新来的syn包就无法被响应,服务器也就无法响应正常的tcp请求了。
ack flood
攻击者向服务器发送大量ack标志位置1的报文,服务器收到后,会在协议栈判断报文是否合法(是否有该四元组的连接,序列号是否正常等等),如果不合法,服务器会返回一个rst报文。跟这种攻击比较类似的还有rst flood和fin flood。
udp reflect
udp是无状态的,没有三次握手,攻击者利用udp的这个特点,向服务器发送大量业务请求,导致服务器返回远大于请求量的响应,从而达到占用大量带宽的目的。
udp reflect攻击主要针对哪些响应包远大于请求包的协议,如dns、ntp等,以达到四两拨千斤的效果。
以dns为例,由于dns大部分提供公网服务,会将53端口暴露到公网上。攻击者伪造一个源ip地址,向dns服务器的53端口发送大量的dns请求,dns服务器收到之后,会回给攻击者伪造的ip地址大量的dns响应。可以看到受攻击的对象有两个,一个是攻击者伪造的ip地址,另一个是dns服务器。
ssl flood
这是表示层的一种ddos攻击。SSL握手的过程中,在协商加密算法时服务器CPU的开销是客户端开销的15倍左右。攻击者利用这一特点,在一个TCP连接中不停地快速重新协商,从而达到耗尽服务器CPU资源的目的。
SSL客户端发送一条ClientHello消息来初始化一次新的握手,该消息大约100字节左右,不需要加密。服务器端响应ClientHello消息,需要连续发出3个消息,ServerHello、Certificate、ServerHelloDone,这3个消息一般在3000字节左右,需要用高级加密标准AES或流加密算法簇RC-4进行加密后再发送。每次ssl握手,SSL服务端发送的数据比客户端多了30倍,还要进行加密,从而导致服务端CPU计算资源大量占用。
http flood
http flood是最难模拟也是最难防范的一种攻击,攻击者模拟用户的真实操作对某些接口发送大量http请求,导致其他正常用户的请求响应速度变慢甚至被拒绝。
如何防御?
减少暴露面
尽可能少的把端口暴露在公网上,减少可能的攻击点。
配置安全组、acl访问控制或者iptables防火墙规则,这三种操作的目的其实都是一样的,都是为了限制不明客户端的访问,只是生效的地方不一样。一般来说,我们肯定希望把这些流量在离服务器更远的地方限制住。
将服务器放在cdn、负载均衡后面,目的其实是和第二点一样。cdn可以缓存服务器资源到各个边缘节点上,让用户就近访问最近的边缘节点,从而缓解服务器的压力。负载均衡可以配置调度算法,将流量按需分配给后端服务器,并且对后端进行个性化的健康监测,将不健康的服务器踢出,不继续处理请求。
服务器安全加固
及时更新安全补丁。
优化内核参数如半连接timeout时间、全连接队列长度、禁用icmp广播等等。
及时止损
如果我们没有防御成功,需要及时止损,将影响降到最低。
在部署服务的阶段,我们就应该尽可能一个集群只部署一个服务,让服务之间互不影响,即使某个服务受到了攻击,也可以把影响降到最小。
建立完善的监控告警机制。这个公司内部应该都有,监控cpu使用率、连接数之类的,如果达到阈值,就会发出告警,交由专人处理。
对系统进行压测,配置限速机制。我们需要对业务架构进行完善的压力测试,以评估现有架构的吞吐能力。并根据系统性能对业务进行限速,避免ddos攻击将服务器打挂。
集群具有可伸缩性。当集群某些指标达到阈值时,为了让业务不受损,应该及时对集群进行扩容。
识别异常流量
预防ddos攻击的关键其实就是怎么识别正常流量和异常流量。这需要我们对ddos攻击的方法非常了解,对不同的ddos攻击类型做出相应的防御动作。服务器本身几乎没有识别异常流量的能力,所以大部分企业都会购买anti-ddos服务或者waf这样的专业设备来防御ddos攻击。
anti-ddos当然也分为硬件设备和软件。硬件anti-ddos一般会旁挂到汇聚或者核心交换机上,交换机将流量镜像一份发给ddos,ddos识别出异常流量后会做一些流量清洗动作。软件antiddos可能会直接安装到四七层网关上,对经过四七层网关的流量进行过滤。显而易见,软件anti-ddos的优点就是便宜,简单;缺点是可能会拖累四七层网关的性能,可防护的ddos类型和防御能力肯定不如硬件anti-ddos。
但其实有的地方硬件和软件anti-ddos都会用,硬件antiddos主要是进行一个流量清洗的功能,软件antiddos在硬件的后面,主要做一个兜底的作用。
syn flood
syn flood是最常见的一种ddos攻击,在服务器、网关、anti-ddos每一个环节都有相应的手段可以进行防御。
syn cookie。syn cookie已集成到了linux内核,是在服务器上防御syn flood的方法。服务器每当收到一个syn,就会创建一个半连接队列,来缓存连接信息,当半连接队列满了之后,服务器就无法处理正常请求了。所以我们需要找到一种方法,不用记录全部的连接信息。我们知道,服务器发出的第二次握手的序列号是服务器自己生成的,syn cookie将连接的部分信息(mss、时间戳、四元组)通过某种算法生成一个唯一的序列号给客户端,并且这个序列号是可以解码的。服务器收到第三次握手的确认序列号后,将这个值减1,就可以还原出之前的序列号。可以看到,服务器巧妙地通过这种方式间接保存了一部分SYN报文的信息,节省了服务器的部分资源,但是同时也增加了加解密的计算。
syn proxy。syn proxy在四层网关中用的比较多,用法也比较简单。网关收到syn后,并不直接发送给后端服务器,而是代替后端,与客户端进行三次握手,当握手成功之后,再与后端服务器进行三次握手。syn proxy经常与syn cookie结合起来用,网关在于客户端三次握手的过程中可以使用syn cookie。syn proxy有一个问题就是两次握手的序列号不一样,所以网关在后续的数据传输阶段还要继续调整序列号和确认序列号。
首包丢弃。这种方法比较暴力,syn flood不会重传,所以我们只要把第一个syn包都丢弃了,正常请求后进行重传,异常请求就被丢弃了。
算法。antiddos可以通过统计syn包占到所有流量的比例,当这个比例达到某个阈值时,即判定受到了ddos攻击。然后就到了识别异常流量的时候了,如果antiddos可以查到会话信息,那就简单了,那些在几分钟内完成过三次握手的源ip地址,是ddos攻击的可能性较小,可以直接放行。剩下的ip地址是ddos攻击的可能性就比较大了。我们知道ddos攻击可以分为随机源ip和真实源ip两种。antiddos可以将syn包的个数除以源ip的数目,如果大于某个阈值,则可以判定为真实源ip攻击,直接将这几个源ip地址的syn包全部丢弃就可以了;如果小与某个阈值,则判定为随机源ip攻击,这时可以利用上面说的首包丢弃的方法,判断出正常流量,将正常的源ip地址放行。
ack/fin/rst flood
这三种ddos攻击比较类似,都依赖于会话。如果没有建立会话,那不管是在服务器还是在网关都会直接被丢弃的。判断是否收到攻击也比较简单,就比较命中会话的报文和没命中的比例就好了。
畸形报文
畸形报文往往有一些特征,antiddos可以提前识别以下畸形报文:
非法的tcp flag标志位,如SYN和FIN同时为1等。
源ip和目的ip一样的报文。
源ip为内网ip或预留ip。
length字段与实际payload不一致。
有data的syn包或者无option的syn包。
无payload的udp包
分片包。
等等
其中4、5、6并不一定是异常流量,只是比较像由发包器发出来的报文,具体问题还得具体分析。
其他
其他的一些攻击比如udp reflect、http flood、ssl flood,都是一些接近正常流量的请求,感觉识别异常流量比较复杂,应该只能通过算法来识别。也可以借鉴syn flood的防御方法,主要还是得识别出异常流量和正常流量的源ip地址。