Shell 脚本:根据访问日志自动封禁高频 IP
需求:根据 web 服务器访问日志,把请求量异常高的 IP 用 iptables 封禁;每隔半小时把不再请求或请求量很小的 IP 解封。一分钟内请求量高于 100 次的 IP 视为不正常。
#!/bin/bash
# 封 IP 函数
block_ip() {
t1=`date -d "-1 min" +%Y:%H:%M` # 上一分钟
log=/data/logs/access_log
# 截取上一分钟日志
egrep "$t1:[0-9]+" $log > /tmp/tmp_last_min.log
# 把访问超过 100 次的 IP 写入临时文件
awk '{print $1}' /tmp/tmp_last_min.log | sort -n | uniq -c | sort -n | awk '$1>100 {print $2}' > /tmp/bad_ip.list
n=`wc -l /tmp/bad_ip.list | awk '{print $1}'`
if [ $n -ne 0 ]; then
for ip in `cat /tmp/bad_ip.list`; do
iptables -I INPUT -s $ip -j REJECT
done
fi
rm -f /tmp/tmp_last_min.log /tmp/bad_ip.list
}
# 解封 IP 函数
unblock_ip() {
# 包数少于 5 个的 IP 记入白名单
iptables -nvL INPUT | sed '1d' | awk '$1<5 {print $8}' > /tmp/good_ip.list
n=`wc -l /tmp/good_ip.list | awk '{print $1}'`
if [ $n -ne 0 ]; then
for ip in `cat /tmp/good_ip.list`; do
iptables -D INPUT -s $ip -j REJECT
done
fi
iptables -Z # 清空计数器
rm -f /tmp/good_ip.list
}
# 每隔半小时(分钟为 00 或 30)先解封再封,否则只封
t=`date +%M`
if [ $t == "00" ] || [ $t == "30" ]; then
unblock_ip
block_ip
else
block_ip
fi
配合 crontab 每分钟执行一次。
原文链接:https://www.ssssmy.com/notes/shell-jiao-ben-gen-ju-fang-wen-ri-zhi-zi-dong-feng-jin-gao-pin-ip