Nginx可通过map指令基于IP段控制HTTPS重定向:在http块定义$skip_https_redirect变量,默认1(跳转),白名单IP正则匹配设为0;80端口server中if判断该变量为1时301跳转HTTPS,否则走后续location;443端口必须正确配置SSL证书及TLS版本。

要让 Nginx 根据访客 IP 段决定是否执行 HTTPS 重定向,核心思路是:在 80 端口的 server 块中,先识别请求来源是否属于内网白名单(如 172.16.0.0/12、192.168.0.0/16、10.0.0.0/8),命中则跳过重定向,允许其继续以 HTTP 访问;其余所有流量统一 301 跳转到 HTTPS。
用 map 指令定义跳转开关
这是最推荐、最清晰的方式。Nginx 的 map 指令支持正则匹配 IP,且在请求处理早期生效,性能稳定、逻辑可读性强。
- 在 http 块顶层(server 外)定义一个变量,比如
$skip_https_redirect - default 设为 1,表示默认需要跳转
- 对每个白名单网段写一行正则匹配规则,值设为 0(不跳转)
- 注意正则需转义点号,并用
^锚定开头,避免误匹配(例如~^192\.168\.)
示例配置:
map $remote_addr $skip_https_redirect {
default 1;
~^172\.16\. 0;
~^192\.168\. 0;
~^10\. 0;
}
在 80 端口 server 中统一判断并跳转
把上面定义的变量用在 listen 80 的 server 块里,只需一条 if + return,简洁可靠。
- if 判断变量是否为 1,是则执行
return 301 https://$host$request_uri - 不需要 else 分支,未命中 if 的请求自然进入后续 location 处理
- 白名单 IP 的请求会跳过 return,继续走下面的 location 规则,比如直接代理 /healthz 或 /verify/
示例片段:
server {
listen 80;
server_name example.com;
if ($skip_https_redirect = 1) {
return 301 https://$host$request_uri;
}
location /healthz {
return 200 "OK";
}
location /verify/ {
proxy_pass http://backend_verify;
}
}
用 location + allow/deny 实现路径级豁免(备选)
如果只希望某几个路径(如 /captcha/、/debug/)对内网开放 HTTP,其他路径一律跳转,可用此方式。
- 用
location ^~ /captcha/这类前缀匹配,优先级高、不进正则阶段 - 内部用
allow明确放行网段,再用deny all拦截非白名单 - 这个 location 不写 return 或 rewrite,HTTP 请求就原样处理
- 注意:它不控制“是否跳转”,而是控制“能否访问该路径”,需配合全局跳转规则使用
示例:
location ^~ /captcha/ {
allow 192.168.0.0/16;
allow 172.16.0.0/12;
deny all;
proxy_pass http://captcha_service;
}
443 端口必须完整启用 HTTPS
跳转只是第一步,后端服务必须能正确响应 HTTPS 请求,否则白名单用户虽绕过跳转,但直连 443 仍会失败。
- listen 443 ssl 指令不可省略
- ssl_certificate 和 ssl_certificate_key 必须指向有效证书文件
- 建议启用 TLSv1.2+,禁用不安全协议(如 SSLv3、TLSv1.0)
- 若需兼容内网 HTTP 客户端调试,443 server 块中可额外配 location 处理 /http-test 等路径,返回明文响应


















