必须将allow指令置于deny all之前,使用标准cidr格式精确匹配运维网段,并在location块中配置;代理环境下需配合set_real_ip_from和real_ip_header获取真实ip,再通过geo模块预判或直接allow/deny控制访问。

要精准放行特定运维内网网段,核心是用好 allow 指令配合严格顺序和正确网段格式,同时确保匹配的是真实客户端 IP。
只在 location 块中配置,且作用域必须明确
allow 和 deny 不能写在 events、upstream 或全局顶层,只在 http、server、location 或 limit_except 块中生效。管理后台类路径(如 /admin、/manage)建议直接在对应 location 块里配,避免被更高层规则覆盖。
- 正确示例:
location /admin { allow 10.20.0.0/16; allow 172.16.100.0/24; deny all; } - 错误示例:把
allow写在http块里,又在location里重复写但没加deny all,会导致非预期放行
网段必须用标准 CIDR 格式,且范围要够用
运维出口网段常有多个,比如办公网 10.20.0.0/16、跳板机网段 172.16.100.0/24、容器节点段 10.96.0.0/12。每个都得单独写一行 allow,掩码位数必须准确。
-
10.20.0.0/16覆盖10.20.0.1–10.20.255.255,别错写成/24(只到10.20.0.255) - 非法掩码如
10.0.0.0/33不报错但整条规则失效,务必执行nginx -t验证 - IPv6 网段同样支持,例如
allow 2001:db8::/32;
代理环境下必须拿到真实 IP 才能生效
如果 Nginx 前面有 SLB、CDN 或 Traefik,$remote_addr 是代理地址,直接 allow 就会失准。需配合 set_real_ip_from 和 real_ip_header 提取真实源 IP。
- 在
http或server块开头加上:set_real_ip_from 10.100.0.0/16;(替换成你可信代理的网段)real_ip_header X-Forwarded-For; - 再用
geo模块预判是否在允许范围内更稳妥:geo $real_ip_allowed { default 0; 10.20.0.0/16 1; 172.16.100.0/24 1; }
然后在location中:if ($real_ip_allowed = 0) { return 403; }
验证是否真生效,不能只靠单点测试
上线前必须交叉验证边界值和典型误配场景:
- 从网段最大地址发起请求,比如
10.20.255.255访问/admin,应返回200 - 用网段外 IP(如
10.21.0.1)测试,必须返回403 - 查错误日志:
tail -f /var/log/nginx/error.log,看到access forbidden by rule表示规则已加载但未命中白名单 - 加调试头确认实际匹配的 IP:
add_header X-Debug-Remote-Addr $remote_addr;











