最常用可靠的方式是在Nginx的location块中配置allow和deny指令。1.在目标接口location中用^~精准匹配,逐条allow后必须deny all;2.通过set_real_ip_from和real_ip_header还原真实IP;3.避免规则位置错误、if误用等常见错误;4.用curl直连服务器IP验证返回状态码。

直接在 Nginx 的 location 块中配置 allow 和 deny 指令,是最常用、最可靠的方式。关键不是“代理”本身,而是把访问控制规则写在代理路径对应的 location 里,并确保规则顺序和真实 IP 解析正确。
1. 在目标接口的 location 中写白名单规则
比如只允许运维主机和内网访问 /api/internal/ 接口:
- 用
^~ /api/internal/确保前缀匹配精准,避免被更宽泛的 location 覆盖 - 先逐条写
allow(支持 IPv4/IPv6/CIDR),例如:allow 192.168.5.10;、allow 10.0.0.0/8; - 最后必须加
deny all;,且不能换位置——它必须是该 location 中最后一条访问控制指令
2. 处理代理或 CDN 导致的真实 IP 丢失
如果请求经过 Cloudflare、Nginx 反向代理或其他中间层,$remote_addr 默认是代理 IP,白名单会失效:
- 在
http块开头添加真实 IP 还原配置,例如:set_real_ip_from 173.245.48.0/20;<br>set_real_ip_from 103.21.244.0/22;<br>real_ip_header X-Forwarded-For;
-
set_real_ip_from必须填你所用代理的实际可信 IP 段,漏掉就不起作用 - 配完后,
allow/deny才真正基于用户原始 IP 判断
3. 避免常见配置错误
这些错误会让限制形同虚设:
- 把
allow/deny写在upstream、events或顶层无作用域位置 → 启动报错 - 规则写在错误的 location 里,比如把
/admin/的规则误放在location / { }中 → 不生效 - 用
if ($remote_addr = ...)替代allow→ Nginx 明确不支持,会被忽略 - 测试时没绕过 CDN,直接用域名访问 → 看到的是 CDN 返回结果,不是 Nginx 原始拦截
4. 验证是否生效
别依赖浏览器,用 curl 直连服务器 IP 测试:
- 从白名单 IP 执行:
curl -sI http://<server-ip>/api/internal/test</server-ip>→ 应返回 200 - 从非白名单 IP 执行相同命令 → 应返回
403 Forbidden - 加
-v查看响应头,确认是 Nginx 返回的 403,而非后端应用返回


















