Total Pageviews

Monday 29 October 2012

处理ddos攻击经验小结

先是前端的负载彪升,然后机房的限制下行若干M带宽被用尽,于是攻击效果几何级增长,全线瘫痪,所有服务器都连不上了。
1. 假如不是带宽耗尽,我们能负载得了么?
发现两个问题。
第一,是 ip_conntrack 的问题,net.ipv4.netfilter.ip_conntrack_max 默认 65536 ,就是说,系统只能处理65536个连接,大于这个值时,就会阻塞,收到 kernel: ip_conntrack: table full, dropping packet.这样的信息。并且,系统负载上升。这个玩意儿本来是供给NAT使用的,到现在为止,还没有找到启动iptables,但不加载 ip_conntrack模块的办法。为了增加系统处理能力,需要增加这个值,我在rc.local里增加了 sysctl -w net.ipv4.netfilter.ip_conntrack_max=655360 。但是发现无效:原因是,当iptables启动之后,该参数才有效。并且,重启iptables后,该参数会被初始化成默认值。当系统负载高的时候,就 出引发 ip_conntrack: table full, dropping packet 导致的连接阻塞问题。
但是我怀疑一件事情,一味的增大此值,是否是在解决问题的根本。六万多连接,定是因为连接处理不了,阻塞而积累起来的。一味的放宽限制,不是意味着连接阻塞问题将导致更多资源被耗尽?
猜想:前端是用了nginx的,就是说高并发,对于nginx并不能够成威胁,那么大量的连接阻塞,定然是出在了fast-cgi处理上。高并发的请求,一下子涌向fast-cgi,于是……
故且不管这些,在高负载的系统上,还是先停止iptables这样的应用吧。尽管是内核级的应用,不占用什么资源。
第二,关于打开文件数的限制。
又是经验性的致命错误。在/etc/security/limits.conf里,增加了对daemon用户打开文件数的限制。然而似乎并没有起到作用。 后来突然明白,daemon只是运行程序的用户,是root启动程序后,set的euid,应该是没有以该uid被始化环境,而是直接继承的root用户 的环境。所以,这个设置也是没有生效的!
准备采用另外的方法,将ulimit -n 10240 这样的语句写进apache和nginx的启动脚本里,这样,系统就清洁了。并且走到哪里都不会有问题。
2. 抱着主动的态度,ddos的时候,能做些什么?
确定攻击类型之后,有几件事儿可以做。
第一,换IP地址。
第二,查攻击IP,封IP。
第三,查攻击目标,处理之(似之占用负载最小)。
不同的攻击类型,有不同的处理方法。但基本上,ddos最终是要将系统资源耗尽。
第二和第三可同时进行。但是这两个,只有当是小流量的攻击的时候,才可能有机会和时间这么做。需要说明的是,在遭受攻击之情形下,使用 iptables封IP时,应使用reject,而不应该使用drop。根据实验结果,reject可以有效降低对方发包的速度,从而降低对带宽的影响。
将受攻击的目标通过DNS解析走,或者封掉,或者禁止访问,可有效降低对系统负载的消耗,但无异是一种对“网络暴力”的妥协,委屈求全。
换IP是个不错的方法,只要对方不是玩命的跟你死磕,一般都能凌效。一般的ddos攻击不会持续时间很长,一来,调动大量的肉鸡,是在消耗自己的资 源,攻击的时间越大,将损失的肉鸡就会越多,二来,自己的淫威已经得到证明,没有必要死磕下去。但是换IP地址对用户的影响比较大。从换解析到全部生效, 需要一段时间。不是万不得已,还是不用为好。
需要注意的是,原IP必须停止使用,不能配置在任何一台自己的主机上。
假如有抗DDOS攻击的设备,那就另当别论了,或者能在电信部门的配合,能在路由器上做些处理,那效果就更明显了。