还在靠 vim 手动加 deny 1.2.3.4; ,然后 nginx -s reload ? 不仅效率低,还容易误操作、漏封、重启抖动……
别担心!本文为你带来 三种真正“动态”、无需复杂开发、生产可用的 Nginx 封 IP 方案 ,全部附带 完整配置 + 一行命令操作 ,让你的防护能力秒级生效,运维效率直接翻倍!
方案一:OpenResty + Redis 毫秒级动态封禁 实时生效|无需 reload|支持自动解封
1. 安装 OpenResty + Redis # Ubuntu 示例 sudo apt install redis-server -y 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 openresty 2. 配置 /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(一行命令) # 封 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 -y 2. 创建过滤器 /etc/fail2ban/filter.d/nginx-bad.conf [Definition] failregex = ^<HOST>.* "(GET|POST).*" ( 400 | 403 | 444 | 404 ) .* ignoreregex = 3. 配置 jail /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" ] sudo systemctl restart fail2ban 注:默认用 iptables 封 IP。如坚持只用 Nginx,请看方案三。
方案三:纯 Shell + 文件驱动 —— 最简原生 Nginx 封禁 零依赖|只用 Nginx|运维只需写文件
核心思想: 维护一个纯文本黑名单文件:/etc/nginx/blacklist.txt(每行一个 IP) 用一个 Shell 脚本自动转成 deny 配置并 reload 通过 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; } } 第五步:启动监听服务(后台运行) # 创建 systemd 服务(推荐)或直接运行: 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/nginx/blacklist.txt
# 示例内容 1.2.3.4 5.6.7.8 192.168.100.50 保存文件后,3 秒内自动封禁!无需任何命令!
优点: 只需一个 文本文件 + 一个 Shell 脚本 完全兼容原生 Nginx
三大方案怎么选? 不想装新软件、只要原生 Nginx、运维习惯改文件
写在最后: 封 IP 不该是体力活!
无论你是技术大牛还是初级运维,总有一款方案让你 告别手动 reload,把时间留给更有价值的事。
该文章在 2025/11/15 10:11:34 编辑过