DDoS防护的TCP协议防护和防御原理是怎样的呢?

      TCP协议,我相信每个开发工程师都不陌生的。由于协议具有面向连接、可靠的特点,因此在Internet上得到了广泛的应用。常见的Web、SSH、FTP等都是基于TCP协议的。目前,TCP协议占整个网络流量的80%,因此这已成为黑客攻击的主要类别。

       以下是使用wireshark在本地浏览器访问www.163.com时抓包的结果:

       我们将忽略中间的数据传输过程,而专注于顶部和底部的连接,它们建立了我断开的连接。TCP连接的建立:主要目的是通知对方自己的初始序列号,这个序列号是用于IP数据包在网络中按顺序到达,便于TCP对IP数据包重新排序。

客户端的第一个报文如下:

        TCP中的syn标志位置为1,序号为 612417286(记为i)。

        服务端接收到报文后,对该报文进行确认,并发送自己的sequence number给客户端,故为SYN_ACK包,在tcp中syn,ack标志位同时被置为1,服务端确认客户端的报文,Acknowledgement number(确认号)为612417287(i+1),并带上自己的sequence number 为 522111292(记为j)。

       客户端收到后会对发送确认报文,对服务端报文进行确认,如下

       TCP的ack标志位被置为1,确认号为522111293(j+1)。这样经过这3个报文,客户端和服务端都获取到了对方的初始sequence number,连接就建立了。

       TCP连接断开:TCP是一个全双工的数量传输协议,所以TCP连接的断开实际上是2个方向上的传输关闭过程。接下来看看报文的交互过程,本例为服务端发起的关闭:

       首先服务端发送一个FIN报文。通知客户端,服务端不在有数据发送给客户端。

       这里我们可以忽略ack和Acknowledgement number,这个为对前一次客户端报文的确认。我们可以看到TCP中的FIN标志位置为1,sequence number 为522230043(记为k)。客户端收到fin报文后,回复一个ack包确认。这样从服务端到客户端这个方向上的数据传输通道就被关闭,即服务端应用不可以在通过这条连接发送数据给客户端。接下来就是关闭客户端到服务端的传输通道,客户端首先发送fin包服务端收到后发送确认报文给客户端。这样一来从客户端到服务端的传输通道也关闭了,那么此时两个方向上的传输通道都关闭了,TCP的通信双方就都断开了连接。

        从上述的连接建立和断开方式我们会发现TCP连接的建立和断开涉及多个报文,多个状态之间的转换。那么从攻击者角度看上述过程,我们该怎么利用交互过程进行DDOS攻击呢?

TCP攻击可以简单的分为以下三类:

(1)FLOOD类攻击,例如发送海量的syn、syn_ack、ack、fin等报文,占用服务器资源,使之无法提供服务。

(2)连接耗尽类攻击,如与被攻击方完成三次握手后不再发送报文一直维持连接,或者立刻发送FIN或RST报文,断开连接后再次快速发起新的连接等,消耗TCP连接资源。

         还有一类则比较巧妙,是在我们上述没有做分析的数据传输过程中的利用TCP本身的流控,可靠性保证等机制来达到攻击的目的,即:

(3)利用协议特性攻击:例如攻击这建好连接之后,基于TCP的流控特性,立马就把TCP窗口值设为0,然后断开连接,则服务器就要等待Windows开放,造成资源不可用。或者发送异常报文,可能造成被攻击目标奔溃。

        那么上述三种类型的攻击具体的实时和防御原理是怎样的呢?

        FLOOD类攻击与防御。

       Flood类攻击中最常见,危害最大的是syn_flood攻击,也是历史最悠久的攻击之一。因此我们先来看看syn_flood攻击。

       syn_flood攻击:SYN-Flood攻击是当前网络上最为常见的DDoS攻击,也是最为经典的拒绝服务攻击,它利用了TCP协议实现上的一个缺陷,通过向网络服务所在端口发送大量的伪造源地址的攻击报文,就可能造成目标服务器中的半开连接队列被占满,从而阻止其他合法用户进行访问。这种攻击早在1996年就被发现,但至今仍然显示出强大的生命力。很多操作系统,甚至防火墙、路由器都无法有效地防御这种攻击,而且由于它可以方便地伪造源地址,追查起来非常困难。

       从上文我们可以知道客户端发起连接的报文即为syn报文。当攻击者发送大量的伪造IP端口的syn报文时,服务端接收到syn报文后,新建一共表项插入到半连接队列,并发送syn_ack。但由于这些syn报文都是伪造的,发出去的syn_ack报文将没有回应。TCP是可靠协议,这时就会重传报文,默认重试次数为5次,重试的间隔时间从1s开始每次都番倍,分别为1s + 2s + 4s + 8s +16s = 31s,第5次发出后还要等32s才知道第5次也超时了,所以一共是31 + 32 = 63s。

         也就是说一共假的syn报文,会占用TCP准备队列63s之久,而半连接队列默认为1024,系统默认不同,可 cat /proc/sys/net/ipv4/tcp_max_syn_backlog c 查看。也就是说在没有任何防护的情况下,每秒发送200个伪造syn包,就足够撑爆半连接队列,从而使真正的连接无法建立,无法响应正常请求。

          而一台普通的每秒就可以轻松伪造100w个syn包。因此即使把队列大小调大最大也无济于事。那么应该如何区防护呢?

         Syn_flood防御:通常针对syn_flood 有2种比较通用的防护机制

(1)cookie源认证:

       原理是syn报文首先由DDOS防护系统来响应syn_ack。带上特定的sequence number (记为cookie)。真实的客户端会返回一个ack 并且Acknowledgment number 为cookie+1。 而伪造的客户端,将不会作出响应。这样我们就可以知道那些IP对应的客户端是真实的,将真实客户端IP加入白名单。下次访问直接通过,而其他伪造的syn报文就被拦截。

(2)reset认证:

       Reset认证利用的是TCP协议的可靠性,也是首先由DDOS防护系统来响应syn。防护设备收到syn后响应syn_ack,将Acknowledgement number (确认号)设为特定值(记为cookie)。当真实客户端收到这个报文时,发现确认号不正确,将发送reset报文,并且sequence number 为cookie + 1。

       而假消息来源,则不会有任何回应。这允许我们白名单的真正的客户端IP。

       在实际应用中,它通常与丢包和源认证相结合使用。第一个丢包的原理是:DDOS保护装置接收到syn报文后,记录5个元组,然后丢弃。正常用户将重新发送syn消息,保护设备在消息到达5元组并在指定时间内转发该消息。当重新传输的syn消息达到某个阈值时,就启用了上述源身份验证。这减少了反射的syn_ack包的数量,并在不影响保护的情况下减少了网络拥塞。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容