如何通过iptables封禁日志中每分钟请求超N次的IP地址
分钟级IP请求统计+iptables自动封禁方案
你当前的预处理逻辑存在排序缺陷:sort -n -k 1,4 按数字排序会打散同IP不同时间的日志(比如示例中119.252.76.162的21点日志被排到22点日志之后),会导致统计不准,下面是修正后的完整实现,不需要额外安装依赖,用原生awk+shell即可完成。
核心逻辑
- 修正日志预处理排序规则,保证同IP日志按时间顺序聚合
- 将日志中的时间戳截断到分钟粒度,按「IP+分钟」维度分组计数
- 筛出任意一分钟请求量超过阈值的IP,跳过白名单、避免重复添加iptables规则
- 通过crontab定时执行,实现自动检测封禁
完整脚本
先把脚本存为 /usr/local/bin/auto_ban_overload_ip.sh,按需修改开头的配置项:
#!/bin/bash ###################### 配置项 按需修改 ###################### LOG_PATH="/var/log/nginx/access.log" # 你的访问日志路径 REQUEST_THRESHOLD=4 # 单分钟请求数阈值,超过即封禁 WHITELIST=("127.0.0.1" "10.0.0.1") # 白名单IP,永不封禁 BAN_LOG="/var/log/auto_ban_ip.log" # 封禁操作日志路径 ########################################################### # 统计所有超阈值IP BAN_IP_LIST=$(awk -v threshold="$REQUEST_THRESHOLD" ' { # 截掉时间戳末尾的秒级字段,保留到分钟粒度(格式:日/月/年:时:分) minute_tag = substr($2, 1, length($2)-3) stat_key = $1 "|" minute_tag req_count[stat_key]++ } END { for (k in req_count) { if (req_count[k] > threshold) { split(k, key_arr, "|") # 同个IP多次超限只输出一次 if (!is_banned[key_arr[1]]) { is_banned[key_arr[1]] = 1 print key_arr[1] } } } } ' <(awk '{print $1, $4}' "$LOG_PATH" | sed "s/\[//g" | sort -k1,1 -k2,2)) # 遍历IP执行封禁 for ip in $BAN_IP_LIST; do # 跳过白名单 in_white=0 for wip in "${WHITELIST[@]}"; do if [ "$ip" = "$wip" ]; then in_white=1 break fi done if [ $in_white -eq 1 ]; then continue fi # 检查是否已经存在封禁规则,避免重复添加 iptables -C INPUT -s "$ip" -j DROP 2>/dev/null if [ $? -ne 0 ]; then iptables -I INPUT -s "$ip" -j DROP echo "[$(date '+%Y-%m-%d %H:%M:%S')] 封禁IP $ip,触发条件:单分钟请求数超过$REQUEST_THRESHOLD" >> "$BAN_LOG" fi done
给脚本加执行权限:
chmod +x /usr/local/bin/auto_ban_overload_ip.sh
配置定时运行
通过crontab配置每分钟执行一次脚本,实现实时检测封禁:
# 编辑crontab crontab -e # 写入以下规则后保存退出 * * * * * /usr/local/bin/auto_ban_overload_ip.sh
效果验证
用你给出的示例日志跑统计逻辑:
10.200.3.120在20/May/2021:21:05分钟内共有5条请求,超过阈值4119.252.76.162在20/May/2021:22:05分钟内共有5条请求,超过阈值4
两个IP都会被准确识别并封禁,符合预期。
可选优化
- 如果需要自动解封,可以搭配
ipset管理封禁IP,给规则加过期时间,比直接写iptables规则性能更好 - 如果日志格式不是默认Nginx/Apache格式,只需要调整预处理阶段提取IP、时间字段的awk列号即可,核心统计逻辑不需要修改
- 阈值请根据业务正常请求量设置,避免阈值过低误封正常用户
内容的提问来源于stack exchange,提问作者Ali Abdi
相关产品推荐
相关产品推荐

