Nginx IP访问控制核心是location块内按序配置allow放行内网网段、deny all兜底拒绝,且须通过set_real_ip_from和real_ip_header还原真实IP;写在http/server顶层或if块中均不生效。

在 Linux 上用 Nginx 实现 IP 访问控制,核心就是 allow 和 deny 指令的组合使用——不是“加白”,而是“先放行、再全拒”,顺序和位置稍错,整套规则就失效。
必须写在 location 块里才生效
这两个指令只在 http、server 或 location 块中有效,但实际业务中强烈建议只放在 location 里。比如限制后台路径 /admin/,就该这样写:
location /admin/ {allow 10.20.0.0/16;allow 172.16.100.0/24;deny all;}
写在 server 或 http 块里可能影响其他路径;写在 if 块里语法不报错,但完全不执行访问控制逻辑。
顺序不能颠倒:allow 必须在 deny all 前面
Nginx 从上到下逐行匹配,命中即停。所以:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 所有
allow行必须排在最前面,支持单 IP(如allow 192.168.5.20;)、IPv4 网段(如allow 10.0.0.0/8;)、IPv6(如allow 2001:db8::/32;) -
deny all;必须是该location中最后一条访问控制指令 - 漏掉
deny all;,未匹配的请求默认放行,白名单形同虚设 - 如果写成
deny all; allow 10.0.0.0/16;,那所有请求第一步就被拒绝,后面那行永远不执行
代理环境下要还原真实客户端 IP
如果 Nginx 前面有 SLB、CDN 或 Traefik,$remote_addr 是代理 IP,不是用户真实出口 IP,直接 allow 就会失准。
- 确认上游透传了
X-Forwarded-For(或X-Real-IP)头,且内容可信(需代理层清洗) - 在
http块中添加:set_real_ip_from 192.168.10.0/24;(替换成你实际的可信代理网段)real_ip_header X-Forwarded-For; - 配置后,
allow判定的对象才是真实客户端 IP - 漏掉
set_real_ip_from,就算写了real_ip_header也无效
验证是否真正生效
别只测一个内网 IP,要覆盖典型场景:
- 用内网最大地址(如
10.20.255.255)访问,应返回200 - 用非内网 IP(如
11.0.0.1)访问,必须返回403 Forbidden - 查错误日志:
tail -f /var/log/nginx/error.log,看到access forbidden by rule表示规则已加载但未放行 - 重载前务必运行
nginx -t验证语法,避免非法 CIDR(如/33)导致整块失效










