SYN泛洪一直是互联网上最常见也是最经典的DDoS攻击方式。这种攻击通过向服务器发送大量tcp请求连接报文(源IP一般是离散的),服务器为每一条连接分配资源最终导致内存耗尽而无法为后续的合法请求建立连接和服务。
为了更好地理解SYN Flood攻击我们从老生常谈的TCP三次握手(three way handshake)谈起。熟悉的同学可以跳过^_^,笔者以如下的一次HTTP请求和回复(共11个报文)为例为大家说明。
细心的同学可能会发现报文中的seq是0,实际上握手时的初始序号是随机的。我们在wireshark上看到其序号为零是因为wireshark为了方便我们查看分析而做了优化,大家可以在:编辑>首选项>Protocols>TCP>Relative sequence number中关闭这个选项。
1.客户端向服务器发送一个syn消息请求建立连接,初始序号seq为1675805722
2.服务器对请求做出响应,首先创建传输控制块TCB(Transmission Control Block)记录这个未完成的连接,然后启动超时定时器(负责syn-ack报文的超时重传)并向客户端发送SYN-ACK报文,如下报文seq=3078681102,ack=1675805722+1
3.客户端确认服务器的SYN的ack正确后回复ACK报文(否则回复RST),seq=1675805723,ack=307861103。此时客户端进入ESTABLISHED(已建立连接状态),当服务器收到客户端的确认后,也进入ESTABLISHED状态。
我们回过头来从安全的角度看三次握手,会发现这个流程是有缺陷的:在第二次握手中,当服务器发送了syn+ack报文后,若该连接的定时器超过超时重传时间(出现超时的原因可能是syn+ack报文丢失、客户ack报文丢失、RTT时间过长、甚至可能客户是在进行synflood攻击),服务器就会对报文进行重传,当重传次数超过阈值服务器认为TCP连接超时,而后才会销毁该请求套接口释放TCB。如果攻击者用快于服务器TCP连接超时的速度,连续对目标服务器开放的端口发送SYN报文,服务器的所有资源都将被消耗,以至于不能再接受其他客户的正常连接请求。
目前对于SYN Flood攻击一般都通过实时监测tcp的新建连接速率来判断。显然地,当恶意客户端向目标发起攻击时,对目标服务器的请求连接报文会在短时间内大量增加,安全设备发现去往服务器的请求连接速率超过指定的阈值后即可开启防御。
防御的前提当然是要区分出那些请求是合法的连接哪些是SYN泛洪,有一种机制叫SYN cookies,各大厂商的防御手段多采用该机制实现,但具体实现起来各公司还是略有区别,我们现在来看几种典型的实现方法。
方法一:①当安全设备获取到发往服务器的SYN报文后,设备模拟服务端会给此源IP回复ack=Cookie的SYN/ACK报文(Cookie是通过五元组加密计算出来的值,正常情况下的ack=seq+1)。
②正常客户端会回复RST报文,而攻击流则不会回复。
③安全设备收到RST报文并校验后便可把回复正确报文的客户端IP加入白名单(校验通过的标准是RST报文中携带的seq等于用该报文的五元组等信息算出的Cookie)。
④后续安全设备放行属于该IP的正常流量。
方法二:①当安全设备获取到发往服务器的SYN报文后,设备模拟服务器给源IP回复seq=Cookie的SYN/ACK报文。
②正常客户端会回复ACK报文,确认序列号为Cookie+1。
③安全设备收到ack报文并校验无误后将该客户端的IP加入白名单,并向客户端发送RST报文断开连接。
④后续安全设备放行属于该IP的正常流量。
方法三:①当安全设备获取到发往服务器的SYN报文后,设备模拟服务器给源IP回复seq=Cookie的SYN/ACK报文。
②正常客户端会回复ACK报文,确认序列号为Cookie+1。
③安全设备收到ack报文并校验无误后,设备与服务发送连接请求,通过三次握手后与服务器建立起连接。
④客户端与防火墙之间建立了连接,防火墙与服务器之间也建立了连接,客户端与服务器间关于此次连接的后续数据报文都将通过安全设备进行代理转发。
可见以上几种方式都是通过源认证的方式,即判断请求是否是真实源发出的方式来防御SYN Flood攻击。