直接用deny指令封禁单个恶意ip最快速低开销,适合应急;必须置于server块顶层(location前),按deny在前、allow all在后的顺序配置,改完执行nginx -t && nginx -s reload生效。

直接用 deny 指令封禁单个恶意 IP 是最快速、低开销的方式,适合应急响应——比如刚在日志里发现某个 IP 正在高频请求 /wp-login.php 或反复试探 /api/admin 接口。
必须写对位置:只允许放在 server 块顶层
deny 指令不能写在 location 块里,否则 Nginx 会静默忽略或启动报错。正确位置是网站配置文件中 server { } 的大括号内、所有 location 块之前。
- ✅ 正确示例:
server {
listen 80;
server_name example.com;
deny 203.0.113.45;
location / { ... }
} - ❌ 错误写法:
location / {
deny 203.0.113.45; ← 这里不生效
}
规则顺序和兜底逻辑要严谨
多个 deny 可并列,但若混用 allow,顺序就决定结果。拉黑单个 IP 时,推荐用“黑名单模式”:先 deny,再 allow all。
- 想只拦一个 IP,其余全放行?写两行:
deny 203.0.113.45;allow all; - 注意:
allow all;必须放在所有deny之后,否则它会提前放行,让前面的deny失效 - 不需要写
deny all;——那是白名单场景的兜底,这里不用
操作后务必重载,不是重启
改完配置保存后,执行以下命令使规则立即生效:
-
nginx -t→ 先检查语法是否正确 -
nginx -s reload→ 重载配置(不是systemctl restart nginx)
重载后,该 IP 再访问任何路径都会收到 403 Forbidden 响应,且不进入后续处理流程(如 PHP 执行、代理转发),性能影响极小。
别忘了排查更高层拦截干扰
如果加了 deny 却发现 IP 还能访问,可能是被其他机制提前放行或阻断了:
- 云厂商安全组是否开放了
0.0.0.0/0?如果是,Nginx 根本收不到包 - 用了 CDN(如 Cloudflare)?此时
$remote_addr是 CDN 节点 IP,需配合real_ip模块和可信代理列表才能识别真实源 IP - 系统防火墙(iptables/firewalld)有没有针对该 IP 的
ACCEPT或DROP规则?它优先级高于 Nginx











