Nginx中实现敏感接口IP白名单,须在location块内按序配置allow(支持IPv4/IPv6及网段)后接deny all;路径匹配推荐^~前缀或正则,代理场景需用real_ip_module还原真实IP。

在 Nginx 中,可以通过 location 块结合 allow / deny 指令实现对特定敏感接口(如 /api/admin/、/healthz、/debug/)的 IP 白名单访问控制。核心是精准匹配路径 + 严格拒绝默认访问 + 只放行指定 IP 或网段。
1. 基础白名单配置(精确匹配路径)
适用于固定前缀的敏感接口,例如只允许运维网段访问 /api/v1/internal/:
location ^~ /api/v1/internal/ {
# 允许指定 IP 和内网网段
allow 192.168.10.5;
allow 10.0.0.0/8;
allow 172.16.0.0/12;
# 拒绝所有其他请求
deny all;
<pre class="brush:php;toolbar:false;"># 后续代理或处理逻辑(可选)
proxy_pass http://backend;
proxy_set_header Host $host;}
说明:
• ^~ 表示前缀匹配且优先于正则匹配,适合接口路径控制;
• allow 必须写在 deny all 之前,Nginx 按顺序匹配,遇到第一条满足规则即生效;
• 单个 IP 写法为 allow 1.2.3.4;,CIDR 网段如 allow 192.168.1.0/24;。
2. 配合正则匹配更灵活的接口控制
当敏感接口路径不规整(如含版本号或随机后缀),可用正则匹配:
location ~ ^/api/(admin|debug|metrics)/ {
allow 123.45.67.89;
allow 2001:db8::/32; # 支持 IPv6
deny all;
<pre class="brush:php;toolbar:false;">proxy_pass http://internal_api;}
注意:
• 正则匹配优先级低于 ^~,但高于普通字符串匹配;
• 若同时存在 ^~ /api/ 和 ~ ^/api/admin/,Nginx 会优先选 ^~(因它更高效),所以建议敏感路径用唯一前缀或明确用正则避免冲突;
• IPv6 白名单需确保 Nginx 编译时启用了 IPv6 支持(默认通常开启)。
3. 使用 geo + map 实现动态白名单(推荐用于多环境)
当白名单需频繁变更或按环境区分(如测试环境放开本地,生产仅限堡垒机),避免反复 reload 配置,可用 geo + map 预定义变量:
# 在 http 块中定义
geo $remote_addr $is_trusted {
default 0;
192.168.1.100 1;
10.10.0.0/16 1;
203.0.113.5 1;
}
<p>map $is_trusted $allowed {
1 "yes";
0 "no";
}</p><h1>在 server 或 location 中使用</h1><p>location /api/sensitive/ {
if ($allowed = "no") {
return 403;
}
proxy_pass <a href="https://www.php.cn/link/6846e5a9bd703e60c27e0a71c7c0060b">https://www.php.cn/link/6846e5a9bd703e60c27e0a71c7c0060b</a>;
}优势:
• 白名单集中管理,无需修改 location 块;
• 支持嵌套逻辑(比如结合 $http_x_forwarded_for 处理反向代理场景);
• 配合 Lua 模块还可对接数据库或 Redis 动态加载白名单(需编译 lua-nginx-module)。
4. 注意事项与常见避坑点
-
不要忽略 X-Forwarded-For:如果 Nginx 前还有 CDN 或负载均衡,真实客户端 IP 在
$http_x_forwarded_for中,此时需用set_real_ip_from+real_ip_header正确识别源 IP,否则$remote_addr是上一跳地址; - deny all 不等于防火墙拦截:它返回 403,仍会消耗 Nginx 连接和日志,高频扫描下建议配合 fail2ban 或云 WAF 做二层防护;
-
location 匹配顺序很重要:若存在
location /api/和location /api/admin/,后者必须用^~ /api/admin/或正则确保优先匹配,否则可能被宽泛规则提前捕获; - 测试务必用 curl -v 模拟不同 IP,并检查 access.log 中 status 和 remote_addr 是否符合预期。
配置完成后执行 nginx -t 校验语法,再 nginx -s reload 生效。白名单机制简单直接,关键是路径匹配准确、IP 来源可信、拒绝逻辑无遗漏。


















