Nginx可通过日志分析+脚本检测+独立conf文件实现IP段流量突刺监控与自动封禁:一、用awk精准提取192.168.100.0/24网段每分钟请求;二、脚本每分钟检查超阈值IP并写入block_segment.conf;三、主配置include该文件,reload仅刷新规则。

要让 Nginx 监控特定 IP 段的流量突刺(如 1 分钟内请求激增),并自动触发封禁,核心是“日志分析 + 条件识别 + 配置写入 + 平滑生效”。整个流程不依赖 reload 全局配置,也不需要改主 conf,而是通过模块化、可插拔的方式实现。下面分三步讲清楚关键操作。
一、在 access.log 中精准提取目标 IP 段的访问行为
默认日志格式中 $remote_addr 是真实客户端 IP(若前端有代理,需确保已用 real_ip 模块还原)。先确认你的日志格式是否包含该字段:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';
假设你要监控 192.168.100.0/24 这个网段,可用以下命令实时抓取该段每分钟的请求次数:
awk '$1 ~ /^192.168.100./ {print $1, substr($4,2,15)}' /var/log/nginx/access.log | awk '{key=$1" "$2} {c[key]++} END {for (i in c) if(c[i]>80) print c[i], i}' | sort -nr
说明:
• 第一个 awk 筛出属于该网段的行,并提取 IP + 时间戳前15位(形如 12/May/2026:20:30)
• 第二个 awk 按“IP+分钟”聚合计数,只输出单分钟超 80 次的记录
• 输出示例:137 192.168.100.45 12/May/2026:20:30
二、编写轻量级检测脚本,只处理目标网段且避免误封
新建脚本 /usr/local/bin/check_ip_segment.sh,内容如下:
#!/bin/bash
SEGMENT="192.168.100.0/24"
THRESHOLD=80
LOG_PATH="/var/log/nginx/access.log"
CONF_PATH="/etc/nginx/conf.d/block_segment.conf"
# 清空临时封禁列表(防止旧IP残留)
echo "# Auto-generated for $SEGMENT on $(date)" > "$CONF_PATH"
# 提取该网段中每分钟超阈值的IP(仅最新10分钟)
tail -n 5000 "$LOG_PATH" |
awk -v seg="192\.168\.100\." '$1 ~ seg {print $1, substr($4,2,15)}' |
awk '{key=$1" "$2} {c[key]++} END {for(i in c) if(c[i]>'$THRESHOLD') print $1}' |
sort -u | while read ip; do
echo "deny $ip;" >> "$CONF_PATH"
done
# 仅当有新IP写入时才重载,避免无效 reload
if [ $(wc -l nginx -t && nginx -s reload
echo "$(date): blocked $(grep 'deny ' $CONF_PATH | wc -l) IPs from $SEGMENT" >> /var/log/nginx/block_segment.log
fi
注意:
• 使用 tail -n 5000 而非全量扫描,降低 I/O 压力
• 封禁规则写入独立 conf 文件(block_segment.conf),便于隔离管理
• nginx -t 校验语法后再 reload,防配置错误导致服务中断
三、在 Nginx 主配置中启用该规则文件
编辑 /etc/nginx/nginx.conf 的 http{} 块末尾,加入:
include /etc/nginx/conf.d/block_segment.conf;
无需重启 Nginx,首次 reload 后即可生效。后续脚本每次更新 block_segment.conf 并 reload,只刷新该部分规则。
补充建议:
• 用 crontab 每 60 秒执行一次脚本(*/1 * * * * /usr/local/bin/check_ip_segment.sh)
• 若需自动解封,可在脚本末尾加 at now + 30 minutes 调用一个“清空 block_segment.conf 并 reload”的回滚脚本
• 对于更高频或更复杂的判断(如含 UA 特征、路径特征),建议升级为 OpenResty + Lua + Redis 方案,实现毫秒级动态黑白名单











