Linux Vps系统防CC攻击自动拉黑IP脚本分2个版本,普通版是加入到crontab计划任务执行的,每5分钟执行一次。增强版主要是为了弥补用crontab执行时间间隔最低只能是1分钟的不足,可以让CC防护更严密,甚至每隔1S执行一次!

普通版:脚本名称:自动拉黑CC攻击者IP的Shell脚本

功能说明:通过netstat -an命令统计出当前请求并发大于100的IP,然后将不在白名单的IP自动加入DROP规则

使用说明:

1、在Linux系统下将以下代码保存为shell脚本,比如:deny_ip.sh,并执行chmod+x deny_ip.sh加执行权限

  1. #!/bin/bash
  2. #Author:ZhangGe
  3. #Desc:Auto Deny Black_IP Script.
  4. #Date:2014-10-28
  5. #从第一个参数取得限制阈值,如果未设置最高并发,将设置为100
  6. if [[ -z $1 ]];then
  7.         num=100
  8. else
  9.         num=$1
  10. fi
  11. #进入到脚本所在目录
  12. cd $(cd $(dirname $BASH_SOURCE) && pwd)
  13. #取得当前请求大于阈值$num的IP列表
  14. iplist=`netstat -an |grep ^tcp.*:80|egrep -v 'LISTEN|127.0.0.1'|awk -F"[ ]+|[:]" '{print $6}'|sort|uniq -c|sort -rn|awk -v str=$num '{if ($1>str){print $2}}'`
  15. #循环IP列表进行筛选和处理
  16. if [[ ! -z $iplist ]];
  17. then
  18.         for black_ip in $iplist
  19.             do
  20.                 #取得IP所在段
  21.                 ip_section=`echo $black_ip | awk -F"." '{print $1"."$2"."$3}'`
  22.                 #先检查白名单中是否存在匹配的IP段(为了支持整段IP为白名单)
  23.                 grep -q $ip_section ./white_ip.txt
  24.                 if [[ $? -eq 0 ]];then
  25.                         #若发现black_ip和白名单的一个段匹配,则写入到待验证列表,并暂时放过
  26.                         echo $black_ip >>./recheck_ip.txt
  27.                 else
  28.                         #若不再白名单当中,则直接将black_ip加入到防火墙的DROP规则当中,并记录
  29.                         iptables -nL | grep $black_ip || iptables -I INPUT -s $black_ip -j DROP
  30.                         echo $black_ip >>./black_ip.txt
  31.                 fi
  32.            done
  33. fi

2、如果有要排除的白名单IP,需要将这些IP加入到脚本同目录的white_ip.txt当中,一行一个

3、最后使用crontab -e 将脚本加入到系统计划任务当中,每五分钟执行一次即可(最后的数值表示最大并发数):

  1. */5 * * * * /root/deny_ip.sh 150 >dev/null 2>&1

注意事项:

  1. 该脚本对于使用了百度云加速或360网站卫士的网站无效,因为IP都已经变成了CDN节点了,请勿使用此脚本
  2. 若不需要支持一个段为白名单,可自行修改24~27行的代码,更加准确的对应到每个IP
  3. 若发现和白名单同一个段IP出现在高并发列表,将不会直接拉黑,而是写入到recheck_ip.txt,如果有监控信息机制,可以在这个地方加入监控报警,告知管理员这个可疑的IP
  4. 增强版:上面的Shell脚本是加入到crontab计划任务执行的,每5分钟执行一次,如果觉得时间间隔太长,那么可以考虑下么的增强版。
  1. #!/bin/bash
  2. #Author:ZhangGe
  3. #Desc:Auto Deny Black_IP Script.
  4. #Date:2014-11-05
  5. #取得参数$1为并发阈值,若留空则默认允许单IP最大100并发(实际测试发现,2M带宽,十来个并发服务器就已经无法访问了!)
  6. if [[ -z $1 ]];then
  7.         num=50
  8. else
  9.         num=$1
  10. fi
  11. #巧妙的进入到脚本工作目录
  12. cd $(cd $(dirname $BASH_SOURCE) && pwd)
  13. #请求检查、判断及拉黑主功能函数
  14. function check(){
  15.         iplist=`netstat -an |grep ^tcp.*:80|egrep -v 'LISTEN|127.0.0.1'|awk -F"[ ]+|[:]" '{print $6}'|sort|uniq -c|sort -rn|awk -v str=$num '{if ($1>str){print $2}}'`
  16.         if [[ ! -z $iplist ]];
  17.                 then
  18.                 >./iplist/black_ip.txt
  19.                 for black_ip in $iplist
  20.                 do
  21.                         #白名单过滤中已取消IP段的判断功能,可根据需要自行修改以下代码(请参考前天写的脚本)
  22.                         #exclude_ip=`echo $black_ip | awk -F"." '{print $1"."$2"."$3}'`
  23.                         #grep -q $exclude_ip ./white_ip.txt
  24.                         grep -q $black_ip ./white_ip.txt
  25.                         if [[ $? -eq 0 ]];then
  26.                                 echo "$black_ip (white_ip)" >>./black_ip.txt
  27.                         else
  28.                                 echo $black_ip >>./black_ip.txt
  29.                                 iptables -nL | grep $black_ip ||(iptables -I INPUT -s $black_ip -j DROP && echo "$black_ip  `date +%Y-%m-%H:%M:%S`">>./iplist/denylog.txt)
  30.                         fi
  31.                 done
  32.                 #存在并发超过阈值的单IP就发送邮件
  33.                 sendmsg
  34.         fi
  35. }
  36. #发邮件函数
  37. function sendmsg(){
  38.         netstat -nutlp | grep "sendmail" >/dev/null 2>&1 || /etc/init.d/sendmail start >/dev/null 2>&1
  39.         echo -e "From: ge@zhangge.netnTo:gobi918@vip.qq.comnSubject:Someone Attacking your system!!nIts Ip is" >./message
  40.         cat ./black_ip.txt >>./message
  41.         /usr/sbin/sendmail -f ge@zhangge.net -t gobi918@vip.qq.com -i <./message
  42. }
  43. #间隔10s无限循环检查函数
  44. while true
  45. do
  46.         check
  47.         #每隔10s检查一次,时间可根据需要自定义
  48.         sleep 10
  49. done

二、执行脚本
将以上代码保存为deny_blackip.sh之后,使用如下命令后台执行脚本(后面的50表示并发数,可自行调整):

  1. nohup ./deny_blackip.sh 50 &

执行后会出现如下信息:

  1. [root@Mars_Server iptables]# nohup ./deny_blackip.sh 50 & 
  2. [1] 23630
  3. [root@Mars_Server iptables]# nohup: ignoring input and appending output to `nohup.out'

表示如果脚本产生输出信息,将会写入到nohup.out文件,可以看到当前目录已经生成了一个空的nohup.out:

  1. [root@Mars_Server iptables]# ll nohup.out
  2. -rw------- 1 root root 0 Nov  5 21:15 nohup.out

好了,现在你执行执行ps aux 应该可以找到如下进程:

  1. root     23630  0.0  0.2   5060  1224 pts/0    S    21:15   0:00 /bin/bash ./deny_blackip.sh
  2. root     23964  0.0  0.0   4064   508 pts/0    S    21:19   0:00 sleep 10

一切顺利!每10s将检查一次服务器请求,如果某个IP超过50个并发,立即拉黑,并发一封邮件给你!

附加说明
①、脚本发邮件需要安装sendmail,若未安装请执行yum -y install sendmail安装并启动即可;

②、若要停止后台运行的脚本,只要使用ps aux命令找到该脚本的pid线程号,然后执行kill -9 pid号即可结束;

③、关于脚本的单IP并发限制,实际测试同时打开博客多个页面并持续刷新,顶多也就产生十来个并发,所以单IP超过50个并发就已经有很大的问题了!当然,文章的阈值设为50也只是建议值,你可以根据需求自行调整;

④、写这个脚本,主要是为了弥补用crontab执行时间间隔最低只能是1分钟的不足,可以让CC防护更严密,甚至每隔1S执行一次!虽说脚本不怎么占用资源,不过还是建议10s执行一次为佳,不用太过极端是吧?

⑤、对于白名单过滤,只要将白名单IP保存到脚本同一目录下的white_ip.txt文件中即可,若发现攻击IP在白名单中,脚本不会直接拉黑,而是发一封邮件给你,让你自己判断这个白名单攻击你是为毛?如果白名单需要支持IP段,请参考我普通版的脚本即可。
资料来源:http://zhangge.net/4649.html

发表回复

后才能评论