Nginx封禁IP的三种高效方法
还在用vim手动添加deny 1.2.3.4;,然后执行nginx -s reload吗?这种方法不仅效率低,还容易出错、漏掉该封的IP、重启服务时还会影响正常访问……
别担心!本文介绍三种真正"动态"、不需要复杂开发、可以在生产环境中使用的Nginx封IP方案,都包含完整配置和简单命令操作。让你的防护能力秒级生效,运维效率大幅提升!
方案一:OpenResty + Redis 毫秒级动态封禁
特点: 实时生效、不需要reload、支持自动解除封禁
1. 安装OpenResty和Redis
# Ubuntu系统示例
sudo apt install redis-server -y
# 安装OpenResty
wget -O - https://openresty.org/package/pubkey.gpg | sudo gpg --dearmor -o /usr/share/keyrings/openresty-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/openresty-archive-keyring.gpg] http://openresty.org/package/debian $(lsb_release -sc) openresty" | sudo tee /etc/apt/sources.list.d/openresty.list
sudo apt update && sudo apt install -y openresty2. 配置/etc/openresty/nginx.conf
worker_processes auto;
events { worker_connections 1024; }
http {
server {
listen 80;
location / {
access_by_lua_block {
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then return end
local ip = ngx.var.remote_addr
if red:get("blacklist:" .. ip) ~= ngx.null then
ngx.exit(403)
end
red:close()
}
proxy_pass http://127.0.0.1:8080;
}
}
}3. 动态封禁和解封IP(一行命令)
# 封禁IP 1小时
redis-cli SETEX blacklist:1.2.3.4 3600 "abuse"
# 解除封禁
redis-cli DEL blacklist:1.2.3.4方案二:fail2ban + Nginx日志——自动分析恶意行为
特点: 自动封禁、防止爆破攻击、安装即用
1. 安装fail2ban
sudo apt install fail2ban -y2. 创建过滤器/etc/fail2ban/filter.d/nginx-bad.conf
[Definition]
failregex = ^<HOST>.*"(GET|POST).*" (400|403|444|404) .*
ignoreregex =3. 配置/etc/fail2ban/jail.local
[nginx-bad]
enabled = true
port = http,https
filter = nginx-bad
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 3600
action = iptables-multiport[name=nginx, port="80,443"]4. 启动服务
sudo systemctl restart fail2ban注意: 默认使用iptables封禁IP。如果想只用Nginx,请看方案三。
方案三:Shell脚本 + 文件监听——最简原生Nginx封禁
特点: 不依赖其他软件、只用Nginx、运维只需要编辑文本文件
核心思想:
维护一个纯文本黑名单文件:/etc/nginx/blacklist.txt(每行一个IP)
用Shell脚本自动转换成deny配置并重新加载
通过inotifywait监听文件变化,修改后立即生效
第一步:安装inotify-tools(监听文件变动)
sudo apt install inotify-tools -y第二步:创建黑名单目录和初始文件
sudo mkdir -p /etc/nginx/dynamic
echo "# 黑名单IP,每行一个,如:1.2.3.4" | sudo tee /etc/nginx/blacklist.txt
sudo touch /etc/nginx/dynamic/blacklist.conf第三步:编写转换脚本/usr/local/bin/gen_nginx_blacklist.sh
#!/bin/bash
INPUT="/etc/nginx/blacklist.txt"
OUTPUT="/etc/nginx/dynamic/blacklist.conf"
# 清空输出文件
echo "# Auto-generated from blacklist.txt. DO NOT EDIT." > "$OUTPUT"
# 读取blacklist.txt,跳过注释和空行,生成deny规则
while IFS= read -r line; do
line=$(echo "$line" | xargs) # 去除前后空格
if [[ -n "$line" && "$line" != \#* ]]; then
echo "deny $line;" >> "$OUTPUT"
fi
done < "$INPUT"
# 测试配置并重新加载
nginx -t && systemctl reload nginx赋予执行权限:
sudo chmod +x /usr/local/bin/gen_nginx_blacklist.sh第四步:在Nginx配置中引入黑名单
server {
listen 80;
include /etc/nginx/dynamic/blacklist.conf; # 关键配置!
location / {
proxy_pass http://127.0.0.1:8080;
}
}第五步:启动监听服务(后台运行)
# 直接运行
nohup inotifywait -m -e modify,move,create,delete /etc/nginx/blacklist.txt \
--format '%f' | while read file; do
echo "[$(date)] blacklist.txt changed, regenerating..."
/usr/local/bin/gen_nginx_blacklist.sh
done &更推荐的方法:创建systemd服务
创建服务文件/etc/systemd/system/nginx-blacklist.service:
[Unit]
Description=Nginx Blacklist Monitor
After=network.target
[Service]
Type=simple
ExecStart=/bin/bash -c 'inotifywait -m -e modify,move,create,delete /etc/nginx/blacklist.txt --format "%f" | while read file; do /usr/local/bin/gen_nginx_blacklist.sh; done'
Restart=always
User=root
[Install]
WantedBy=multi-user.target启动服务:
sudo systemctl daemon-reload
sudo systemctl enable nginx-blacklist
sudo systemctl start nginx-blacklist使用方法
运维人员只需要编辑/etc/nginx/blacklist.txt文件:
# 示例内容
1.2.3.4
5.6.7.8
192.168.100.50保存文件后,3秒内自动封禁!不需要执行任何命令!
优点:
只需要一个文本文件和一个Shell脚本
完全兼容原生Nginx
操作简单,维护方便
实际应用建议
场景一:高并发网站或api网关
如果网站访问量大,需要快速响应,推荐使用方案一(OpenResty + Redis)。
额外优化:
使用Redis集群提高可用性
设置白名单,避免误封
添加监控,记录封禁日志
场景二:WordPress或内容管理系统
如果运行WordPress等CMS系统,经常遇到暴力破解,推荐方案二(fail2ban)。
优化配置:
[wordpress-login]
enabled = true
filter = wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 300
bantime = 86400场景三:简单网站或传统运维环境
如果不想安装新软件,习惯用文本文件管理,推荐方案三(Shell脚本)。
高级用法:
添加IP段封禁功能
集成到现有运维系统
添加邮件通知功能
安全注意事项
1. 避免误封
设置管理IP白名单
定期检查黑名单
设置封禁时间,不要永久封禁
2. 监控和日志
记录所有封禁操作
监控封禁效果
定期分析封禁原因
3. 性能考虑
黑名单不宜过大
定期清理过期记录
考虑使用内存缓存
三种方案对比
| 特性 | 方案一(OpenResty+Redis) | 方案二(fail2ban) | 方案三(Shell脚本) |
|---|---|---|---|
| 生效速度 | 毫秒级 | 分钟级 | 秒级 |
| 是否需要reload | 不需要 | 不需要 | 需要 |
| 安装复杂度 | 中等 | 简单 | 简单 |
| 维护难度 | 中等 | 简单 | 简单 |
| 适用场景 | 高并发、API网关 | 防爆破、CMS系统 | 简单网站、传统运维 |
如何选择?
高并发、API网关、需要快速响应:选方案一(OpenResty + Redis)
防止暴力破解、WordPress等中小型网站:选方案二(fail2ban)
不想装新软件、只要原生Nginx、习惯用文件管理:选方案三(Shell脚本 + 文件监听)
写在最后
封禁IP不应该是费时费力的体力活!无论你是技术高手还是初级运维,总有一种方案能帮你告别手动reload,把时间花在更有价值的事情上。
根据实际需求和环境选择合适的方法,让安全防护变得更简单、更高效。记得定期检查和优化配置,确保既能有效防护,又不会影响正常用户访问。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!