Nginx中实现内网IP免密、其余用户强制认证,需用map基于$remote_addr定义豁免变量,再通过正则location捕获白名单并break,由前缀location兜底认证;务必启用HTTPS并保护.htpasswd权限。

在 Nginx 中实现“特定内网 IP 免密,其余用户强制认证”,关键不是绕过 auth_basic,而是让认证逻辑根据客户端真实 IP 动态生效。核心方法是:用 map 指令预判是否豁免,再通过 location 分支或变量控制 auth_basic 的实际执行——不能在 if 块里直接写 auth_basic,也不能给它赋变量值(如 auth_basic $auth_off 无效)。
用 map 定义豁免标识变量
在 http 块中定义映射,基于真实源 IP 判断是否属于白名单:
- 优先使用
$remote_addr;若前端有 CDN、负载均衡等代理,需先启用real_ip_module,并配置set_real_ip_from和real_ip_header,确保$remote_addr是用户真实 IP - 示例:对
192.168.0.0/16、10.0.0.0/8及单个运维 IP172.16.5.100免密
map $remote_addr $no_auth {
default 0;
192.168.0.0/16 1;
10.0.0.0/8 1;
172.16.5.100 1;
}
用两个 location 分支实现条件认证
这是最稳妥、兼容性最好的做法。Nginx 不允许在 if 中启用 auth_basic,但支持靠匹配顺序和精确度来分流请求:
- 第一个 location 使用正则匹配路径(如
~ ^/admin/),内部不设 auth_basic,仅用于捕获白名单请求并提前终止 - 第二个 location 用前缀匹配(
^~ /admin/),默认启用认证,所有未被上一分支拦截的请求都会落到此处
location ~ ^/admin/ {
if ($no_auth = 1) {
break;
}
}
location ^~ /admin/ {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://backend;
}
注意:break 会跳出当前 location 并继续执行后续匹配,而这里后续只有带 ^~ 的分支,所以白名单用户不会进入认证流程。
静态资源可单独放行(按需)
如果后台路径下含无需认证的 JS/CSS/图片,比如 /admin/static/,可加一个更精确的 location 关闭认证:
location ^~ /admin/static/ {
auth_basic off;
alias /var/www/app/static/;
}
这个块必须写在带认证的 location 之前,或至少保证匹配优先级更高(^~ 和 = 优先级高于正则),否则会被覆盖。
必须确认 HTTPS 已启用
Basic Auth 的凭证本质是 Base64 编码明文,HTTP 下极易被截获:
- 确保 server 块监听
443 ssl,且已配置有效证书 - 访问地址必须是
https://开头,浏览器才允许发送 Authorization 头 - .htpasswd 文件权限设为
640,属主为root:www-data,不可放在 Web 根目录下


















