nginx中deny指令用于ip黑名单控制,须与allow配合并遵循“先匹配先生效”原则,必须成对出现且以allow all结尾;支持ipv4/ipv6地址及cidr网段,不可用于if块或含动态变量;推荐在location块中配置,结合geo模块可提升大规模黑名单管理效率。

Nginx 中的 deny 指令用于在 http、server 或 location 块中拒绝指定 IP 或 IP 段的访问,是实现简单 IP 黑名单的核心方法。它配合 allow 使用,遵循“先匹配先生效”原则,且必须成对出现(通常以 allow all 结尾,否则默认全部拒绝)。
deny 指令的基本语法和位置要求
deny 必须写在 allow 之后(除全拒绝场景外),且只能出现在以下上下文中:http、server、location。Nginx 不支持在 if 块中使用 deny,也不支持动态变量(如 $remote_addr)直接参与判断。
-
deny 192.168.1.100;—— 拒绝单个 IPv4 地址 -
deny 2001:db8::/32;—— 拒绝 IPv6 网段 -
deny 192.168.1.0/24;—— 拒绝 CIDR 格式子网 -
deny all;—— 拒绝所有未被前面allow显式放行的请求
配置 IP 黑名单的典型写法(推荐 location 级)
将黑名单逻辑放在 location / 或具体接口路径下更安全,避免影响静态资源或健康检查端点。注意顺序:先 allow 白名单(可选),再 deny 黑名单,最后用 allow all 放行其余合法流量。
location / {
allow 10.0.0.0/8; # 内网允许
deny 203.201.10.5; # 封禁恶意单 IP
deny 198.51.100.0/24; # 封禁整个可疑网段
allow all; # 允许其他所有 IP(必需!否则全拒)
}
若省略 allow all,Nginx 默认行为是拒绝所有未明确 allow 的请求,容易误伤正常用户。
结合 geo 模块实现更灵活的黑名单管理
当黑名单 IP 较多时,硬编码 deny 会导致配置臃肿且 reload 频繁。推荐用 geo 指令预定义黑名单变量,再在 map 或 if 中控制响应:
geo $bad_ip {
default 0;
203.201.10.5 1;
198.51.100.128/25 1;
}
<p>server {
if ($bad_ip) {
return 403;
}</p><h1>后续正常处理...</h1><p>}</p>
这种方式便于维护(可单独文件 include)、支持大列表,且 reload 时只加载变量,不影响主流程性能。
验证与调试要点
配置后务必测试是否生效,常见问题包括:指令位置错误、顺序颠倒、缺少 allow all、IPv6 地址格式不规范。
- 用
nginx -t检查语法正确性 - 用
curl -I -x "" --header "Host: example.com" http://your-server/模拟不同 IP(需配合代理或修改 hosts + X-Forwarded-For,注意 realip 模块影响) - 查看 error.log 中是否有
client denied by rule日志(需开启error_log ... notice;) - 若使用 CDN 或反向代理,确保封禁的是真实客户端 IP(启用
set_real_ip_from和real_ip_header)











