必须在location块内按“先allow后deny all”顺序配置,放行标准cidr格式内网网段(如10.0.0.0/8),代理环境下需用set_real_ip_from和real_ip_header还原真实ip。

要让 Nginx 只允许内网 IP 访问管理后台,核心是用 allow 明确放行内网地址段,再用 deny all 拦住其余所有请求——位置必须在 location 块里,顺序不能颠倒,代理环境下还得还原真实 IP。
必须写在 location 块内部
规则只在 location、server、http 或 limit_except 块中生效,但实际起作用的只有 location 和 limit_except。写在 http 或 server 顶层,或塞进 if 块里,全部无效。
- 正确做法:为管理路径单独定义块,比如
location /admin/ { ... }、location ^~ /manage/ { ... }或location /api/v1/manager { ... } - 避免误伤:不放在
server块里,否则静态资源、健康检查等也会被限制 - 常见错误:把
allow/deny放在upstream或配置最外层,配置能通过语法检测,但完全不生效
按标准 CIDR 格式写内网网段
内网常用私有地址段要写成合法 CIDR,不能漏掩码,也不能写错范围:
-
allow 127.0.0.0/8;—— 本机回环(建议保留,方便调试) -
allow 10.0.0.0/8;—— A 类私有网段 -
allow 172.16.0.0/12;—— B 类私有网段(覆盖 172.16–31.x.x) -
allow 192.168.0.0/16;—— C 类私有网段 - 如启用 IPv6,可加
allow 2001:db8::/32;
顺序严格:allow 在前,deny all 必须垫底
Nginx 从上到下逐行匹配,命中即停。白名单逻辑依赖“先放行、再兜底”:
- 每条
allow独占一行,支持多个网段并列 -
deny all;必须是该location中最后一条访问控制指令 - 后面不能再跟其他
allow或deny,否则会被忽略 - 漏掉
deny all?未匹配的 IP 默认放行,白名单就失效了
代理环境下必须还原真实客户端 IP
如果 Nginx 前面有 SLB、CDN、Traefik 或另一层 Nginx,$remote_addr 是代理 IP,不是用户真实出口 IP:
- 确认上游透传了
X-Forwarded-For头,且内容可信(需代理层清洗) - 在对应
location或server块中加入:set_real_ip_from 10.0.0.0/8;(替换成你可信代理的网段)real_ip_header X-Forwarded-For; - 之后
allow判的才是真实客户端 IP,否则规则形同虚设
验证是否真生效
别只测一个 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验证配置语法,尤其防/33这类非法 CIDR 掩码(Nginx 不报错但整块失效)











