基于 apache 和 firewall 的恶意 IP 访问封禁

发布于 2019-05-08  254 次阅读


在使用 shell 前需要安装以下软件:firewall,crontab,netstat

命令如下

firewall
        yum install firewalld
crontab
        yum install vixiecron
        yum install crontabs
netstat
        yum install net-tools

创建 ipset

创建永久封禁的 ipset
firewall-cmd --permanent --new-ipset=blacklist --type=hash:ip

创建临时封禁的 ipset, 封禁时间为 3600 秒
firewall-cmd --permanent --new-ipset=list --type=hash:ip --option=timeout=3600

封禁 ipset

firewall-cmd --permanent --zone=public --add-rich-rule='rule source ipset=blacklist drop'
firewall-cmd --permanent --zone=public --add-rich-rule='rule source ipset=list drop'

以下是 shell

#!/bin/bash
##############################设置 ###########################
num=50  #访问阈值
ipnum=10 #日志阈值
logfile=/var/log/httpd/access_log #apache 日志位置
whitelist=`cat <<eof
#############################白名单 ###########################
200
Baidu
baidu
360
google
bing
sougou
########################networkos.club########################
eof`
function check () {
    iplist=`netstat -an |grep -w ^tcp.*:"80\|443"|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}}' `
    loglist=`cat $logfile|grep -i -v "$whitelist" |grep 404|awk -F ' ' '{print $1}' |sort|uniq -c|sort -nr |awk -v str=$ipnum '{if ($1>str){print $2}}' `   #这里的"grep 404" 的 404 是 web 状态码,可以根据需求更改
    for ip in $iplist
        do
            ipset add list $ip timeout 3600
        done

    for log in $loglist
        do
            ipset add blacklist $log
        done
        sleep 5
}

for ((i=0;i<10;i++));
    do
        check >/dev/null
    done

用 crontab 定时启动 shell

路径根据自己的更改, 要用绝对路径
/1 * bash /path/IP.sh

一些注意事项

理想是美好的,然而现实往往是残酷的。如果真的按照我上面的设置,你有很大概率卡在最后一步,因为一些未知的原因(有可能是 crontab 的权限又或者 bash 的路径问题)而出现 root:Command not found 。所以可以用 nohup 来运行,命令是 nohup ./IP.sh &(注意要把 shell 中的 for 循坏改为 while true;),这样可以将 shell 调入后台运行。需要注意的是,退出 ssh 的时候要用 exit 而不能直接退出。因为在 nohup 执行成功后直接点关闭程序按钮关闭终端,所以这时候会断掉该命令所对应的 session,导致 nohup 对应的进程被通知需要一起 shutdown 。