欧阳简之 > CentOS Nginx环境下解决CC攻击问题

热爱代码,对每一行代码保持一颗敬畏之心。

CC攻击是一种常见的网站攻击方式,如果程序未合理利用缓存,当然即使有缓存,如果攻击量较大,一般服务器也无法承受,导致网站无法访问,在这里分享个简单粗暴的方式,直接根据访问日志,对于异常访问的IP防火墙屏蔽,对于大多数情况,是能够解决问题的,脚本如下:

#!/bin/bash

access="/data/app/nginx/logs/access.log"

drop () {
    # 先取出所有IP,过滤掉正常IP(假如是123.123.123.123),再排序,最后只取前20个
    awk '{S[$1]++}END{for(k in S) print S[k],k}' ${access} | grep -v "123.123.123.123" | sort -rn | head -n 20 > /tmp/top20_access.log
    while read line1
    do
        limit="5000"
        ip=$(echo $line1 | awk '{print $2}')
        count1=$(echo $line1 | awk '{print $1}')
        count2=$(iptables -nL | grep -c $ip)

        # 判断访问次数已达到limit限制数,且未被封的IP,满足条件则进行封禁
        if [ $count1 -ge $limit -a $count2 -lt 1 ];then
            /usr/sbin/iptables -I INPUT -s $ip -j DROP
            # 记录被DROP掉的IP
            echo $ip >> /tmp/drop_ip_list_$(date +%F).log
        fi
    done < /tmp/top20_access.log
}

# 将前一天被封的IP解封
del () {
    list="/tmp/drop_ip_list_$(date +%F -d '-1day').log"
    if [ -f $list ];then
        while read line2
        do
            if [ $(iptables -nL | grep -c "$line2") -ge 1 ];then
                /usr/sbin/iptables -D INPUT -s $line2 -j DROP
            fi
        done < $list
    fi
}

main () {
  drop
  sleep 1
  del
}
main $*
tagged by none