简单实现自动过滤WEB攻击源IP

最近VPS负载经常会比较高,刚刚仔细检查了一下,发现有一些IP在非常频繁的向Blog发请求,大多数是关于评论和后台登陆页面的。
由此造成了fastcgi的进程非常繁忙,使得VPS本身就非常弱小的CPU一直处于高利用率的状态。
于是,我编写了一个简单的脚本,每隔5分钟从服务器日志中取出这些IP并通过iptables将其直接Block掉,用起来效果很不错。

根据我目前服务器的访问日志来看,如果在10000个请求中,有1000个请求来自于同一个IP的话,那么其攻击特征就非常明显了。
另外,针对后台登陆页面,我单独制定了更加严格的规则,那就是在10000次POST请求中,如果有5次尝试,就Block掉;
而针对评论页面,在10000次POST请求中,如果有100次尝试,就Block掉;

具体的脚本内容如下:

$ vim /home/rainbow/sbin/block_attack_ips.sh
#!/bin/bash
 
logfile=/webserver/blog/logs/rainbow_access.log
whitelist="125.69.76.137"
 
function check_root(){
  if [ $EUID -ne 0 ]; then
    echo "This script must be run as root"
    exit 1
  fi
}
 
function block_ips(){
  blacklist=$@
  if [ ! -z "${blacklist}" ]; then
    for ip in ${blacklist}
    do
      if ! $(echo ${whitelist} | grep -wq ${ip}); then
        if ! $(/sbin/iptables-save | grep -wq ${ip}); then
          echo "Blocked ${ip}"
          /sbin/iptables -I INPUT -s ${ip}/32 -p tcp -m tcp --dport 80 -j DROP
        fi
      fi
    done
  fi
}
 
function check_post(){
  page=$1
  tailnum=$2
  retry=$3
 
  command="grep -w POST ${logfile} |tail -n ${tailnum} |grep -w ${page} |awk '{print \$1}' |sort |uniq -c |awk '(\$1 > ${retry}){print \$2}'"
  blacklist=$(eval ${command})
  block_ips ${blacklist}
}
 
function check_all(){
  tailnum=$1
  retry=$2
 
  command="tail -n ${tailnum} ${logfile} |awk '{print \$1}' |sort |uniq -c |awk '(\$1 > ${retry}){print \$2}'"
  blacklist=$(eval ${command})
  block_ips ${blacklist}
}
 
check_root
check_post wp-login.php 10000 5
check_post wp-comments-post.php 10000 100
check_all 10000 1000
$ chmod +x /home/rainbow/sbin/block_attack_ips.sh

配置crontab计划任务,每5分钟检查一次,并每天定时重启iptables服务清除旧的记录:

$ sudo crontab -e
*/5 * * * * /home/rainbow/sbin/block_attack_ips.sh
00 01 * * * /etc/init.d/iptables restart

还没有评论,快来抢沙发!

发表评论

  • 😉
  • 😐
  • 😡
  • 😈
  • 🙂
  • 😯
  • 🙁
  • 🙄
  • 😛
  • 😳
  • 😮
  • emoji-mrgree
  • 😆
  • 💡
  • 😀
  • 👿
  • 😥
  • 😎
  • ➡
  • 😕
  • ❓
  • ❗
  • 70 queries in 0.345 seconds