分享

如何利用iRules保护你的应用

 sys 2012-06-03
 作为网络维护人员,最怕的就是系统故障、无法访问。导致这种结果的原因有很多种,但是有很大一部分原因都是由于网络攻击造成的。
网络攻击可以分为很多种:如造成网络出口堵塞的MSSQL蠕虫病毒,把服务器TCP/IP Stack耗尽的Syn Flood攻击,利用系统设计缺陷访问特定URL导致CPU资源耗尽,利用系统漏洞、后门获得系统权限等。
今天我们主要围绕DDoS攻击的防护,谈谈如何利用iRules保护系统,保护应用。
常见的DDoS攻击主要有三种:Syn Flood, Connection Flood, 访问特定URL导致CPU、内存资源耗尽。
首先我们看一下Syn Flood与Connection Flood的攻击原理。
这是TCP三次握手建立连接的过程:


这张图上一共有3次交互,如果缺少最后一次交互,那么服务端将一直挂起在Accept()调用上,那么服务器的一个线程/进程将一直挂在这里。如果所有的线程/进程都因为这个原因,挂起在Accept()调用上,那么这就构成了Syn Flood的DDoS攻击。
那么为什么会缺少最后一次交互过程呢?客户端为什么没有发送ACK到服务端呢?有几种可能:
1. 客户端没有收到服务端发送的SYN-ACK信息
2. 客户端不响应来自服务端IP的SYN包(被防火墙过滤)
服务端一收到SYN,就会回应SYN-ACK,同时一直等待客户端发送ACK。如果发送SYN的时候,我们客户端使用的不是自己的IP地址,而是一个伪 造的IP地址,那么服务端回应的SYN-ACK,自然就被发送到了这个伪造的IP地址上,利索当然就不会有第三部的ACK从客户端发往服务端。服务端只有 等待很久的时间,只好放弃这个握手过程转而处理下一个SYN包。
那么F5 iRules是如何对Syn Flood攻击进行防护的呢?让我们再来看一张图。
这是F5特有的Full Proxy架构下TCP六次握手的过程:


为什么是六次呢?因为客户端首先要跟F5 LTM建立TCP三次握手,然后F5 LTM再跟服务器建立TCP三次握手,就是六次握手了。
其实这里完全没有什么iRules,只要你用了F5 LTM,那就可以使用到这个功能。从图上我们就能清晰的看出来,对于Syn Flood攻击六次握手对服务器具有强大的保护,它将SYN攻击一个不留的挡在了F5 LTM之外。
因为客户端首先要跟F5 LTM完成握手,如果是Syn Flood攻击,这个过程自然不能够完成,那么有人要问了:这不就意味着F5 LTM要承担所有的Syn Flood攻击?对,不过F5 LTM处理会话的能力非常强,而且还可以调整TCP超时时间,快速的释放掉链接。对于LTM 8400/8800更是具有硬件的Syn Cookie功能,可以启用Syn Cookie达到0 CPU占用防护Syn Flood。
又有人要说了Syn Cookie也能防护Syn Flood啊,跟六次握手相比有什么区别吗?Syn Cookie也是需要CPU计算及比对的,而且由于我们常见的计算机系统的随机数都是伪随机数,就是说是可以猜测的,那么Syn Cookie的代码如果编写的不好同样会出现问题,这种问题已经在某些OS上出现过。正是基于这个原因,我们在LTM8400/8800的高端平台提供了 基于硬件实现的Syn Cookie功能。
那么iRules在哪里呢?别着急,主角要出场了,对于Connection Flood我们就要使用iRules来防护了。让我们先来看看Connection Flood的特点:
1. 真实的客户端IP地址
2. 能够完成TCP三次握手,正常建立连接
3. 建立连接后不会发送任何数据
4. 客户端不会主动关闭连接,只有服务端主动关闭链接
5. 每个客户端不停的与服务端建立连接
看上去很恐怖,要是有几千台肉鸡,什么网站都能给黑掉,Apache这种基于线程/进程的WebServer会死的很难看。那么F5的六次握手对它有防护作用吗?回头看看六次握手的过程,貌似没有防护作用,那么iRules有什么好办法呢?
我们看到Connection Flood的特点就是拼命建链接,就是不发请求,这样就只有等到服务端程序判断超时,主动关闭连接,释放资源,然后再处理下一个链接、请求。
那我们就写一个iRules来判断客户端是否发送请求数据,然后再与服务端建立链接:



when CLIENT_ACCEPTED {
TCP::collect
}

when CLIENT_DATA {
TCP::release
}

这个iRules看上去很简单,可是真的能做大事。
首先,在客户端与F5 LTM成功建立连接之后,TMOS会触发一个叫做CLIENT_ACCEPTED的事件。
然后,TMOS就会运行一段与这个事件相关联的iRules代码,TCP::collect这个命令是将网络流量收集到iRules缓冲区。
接下来,当有数据到达iRules缓冲区之后,TMOS又会触发一个叫做CLIENT_DATA的事件。
然后,TMOS又会运行一段与这个事件相关联的iRules代码,TCP::release这个命令是将缓冲区中的数据发回到网络层
最后,TMOS发现有网络流量要到达服务器,但是还没有一个可以跟服务器通讯的TCP链接,所以TMOS就赶紧跟服务器进行TCP三次握手,然后把来自客户端的网络数据发送到服务器。

这个过程我们可以叫做“数据驱动的六次握手”,因为在两个TCP三次握手中间,有一个检查是否有网络数据的步骤,以此作为是否进行第二个TCP三次握手的条件。

这样我们再一次把Connection Flood的攻击压力压在了F5 LTM的身上,这回可是真实的连接,每一个链接都可能会有数据进出,那么F5 LTM如何区分哪些是攻击无用链接,哪些是正常的用户连接呢?F5 LTM有一个参数叫做idle connection timeout,对于长时间,没有数据进出的链接我们叫做idle connection(闲置链接),如果这个链接闲置的时间很久,久到一定的时间,F5 LTM就发送RST,关闭这个链接了,这样我们就可以快速的回收TCP连接资源,同时又不会错误的把正常用户的连接给关闭。

如果 我建立连接之后发送一串非法的请求呢?例如说,我们本来是提供HTTP服务的,结果黑客的攻击程序在建立连接之后,发送了一大串的乱码过来,我们可怜的 Apache好不容易接受下来一个请求,发现不是HTTP的请求,并且在AccessLog日志里记录了一堆错误信息,扰乱了我们正常的业务,这个时候又 该怎么解决呢?
这个时候我们可以采取简单校验请求合法性的方法,拒绝非法的请求,有点像防火墙,不过这可是七层的防护功能。
我们只要把前面的iRules稍微改进一下就可以了,[TCP::payload]就代表了缓冲区内的内容。
when CLIENT_ACCEPTED {
TCP::collect
}

when CLIENT_DATA {
if { [TCP::payload] starts_with “GET ” } {
TCP::release
} else if { [TCP::payload] starts_with “POST ” } {
TCP::release
} else {
reject
}
}

凡是请求不以GET,POST开头的统统拒绝,注意在GET,POST后面我都多加了一个空格,这样校验起来更严格

下一次我再为大家介绍如何利用iRules保护特定的URL资源,防止被频繁请求导致后端数据库的压力升高,以及如何实现防盗链等。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    来自: sys > 《F5》

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多