直接封禁恶意IP用deny最快,适合临时少量;超几十条应改用geo或map模块防性能下降;需注意location作用域、匹配顺序、HTTP/HTTPS双配置同步及日志审计。
直接封禁恶意IP,用 deny 最快,但只适合临时、少量封禁;超过几十条就该换 geo 或 map 模块,否则 reload 后性能明显下降。
用 deny 指令快速封禁单个或少量 IP
这是最直白的方式,适合应急:发现某个 IP 在疯狂刷 /login,立刻加一条 deny 203.0.113.45;。
-
deny必须写在location块里(云虚拟主机等受限环境甚至只允许在location中用),不能放在server顶层 - 顺序很重要:Nginx 从上到下匹配,第一条命中即终止;所以多个
deny可以并列,但不要混allow和deny—— 容易因顺序错乱导致放行本该拦截的 IP - 不建议对
/根路径全局deny,应限定在高危路径下,比如:location /wp-login.php { deny 198.51.100.22; } - 封完要执行
nginx -t && nginx -s reload,否则不生效
用 geo + if 实现可维护的黑名单(推荐百条以内)
当你要封的 IP 超过 20 条,或者需要跨多个 server 复用规则,硬写 deny 就难维护了。用 geo 模块定义变量更清晰,也支持 include 外部文件。
CentOS Linux 7.9.2009
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离线兼容性测试。
下载
- 在
http块顶部加定义:geo $blocked_ip { default 0; 192.168.1.100 1; 203.0.113.0/24 1; include /etc/nginx/ip_blacklist.map; } - 在目标
location中加判断:if ($blocked_ip) { return 403; } -
ip_blacklist.map文件内容必须是纯键值对格式,每行一个:"198.51.100.12" 1; "2001:db8::1" 1;
注意引号和分号不能漏
- 这个方案 reload 不影响已有连接,且变量计算在请求早期完成,比线性扫描
deny快得多
避免踩坑:HTTP 和 HTTPS server 是两套独立配置
很多人 reload 后发现 HTTPS 流量没被拦截,就是因为只在 server { listen 80; } 里配了黑名单,忘了 server { listen 443 ssl; } 也要同步加。
- 检查时务必确认两个
server块都包含相同的geo引用或deny规则 - 如果用了
include,确保路径在两个server中都能读取(权限、SELinux 上下文都要过一遍) - 返回状态码别用
return 444:它直接断连,监控系统收不到日志,排查时会丢线索;统一用403 - 记得给被拦 IP 单独记日志,比如在
log_format里加$blocked_ip字段,不然审计时找不到依据
真正麻烦的不是加一条 deny,而是当攻击 IP 每分钟变一批时,靠人肉 grep + sed + reload 根本跟不上——这时候就得上 fail2ban 或 Lua + Redis 这类自动闭环方案,否则运维就是在给攻击者打工。
