Nginx需主动修正后端返回的不安全Location头,用proxy_redirect重写为公网HTTPS地址,并透传X-Forwarded-Proto等头使后端识别真实协议,同时校验Host防止注入。

HTTPS 重定向后,若后端返回的 Location 响应头仍是 http:// 或内网地址,浏览器会跳转失败或触发安全降级,甚至引发重定向循环。规范处理的关键不是“转发原样”,而是“主动修正”——Nginx 必须在响应发出前,把不安全、不对外的跳转地址,替换成用户实际访问的公网 HTTPS 地址。
用 proxy_redirect 精准重写 Location 头
这是最直接有效的手段。它只作用于响应头中的 Location 和 Refresh,不影响正文,也不依赖后端逻辑。
- 基础写法:匹配所有 HTTP/HTTPS 内部地址,统一转为当前协议+域名
- 若后端固定返回
http://127.0.0.1:8080/,可精准替换
- 注意:
proxy_redirect必须放在proxy_pass指令之后才生效 - 斜杠规则要严格对齐:比如
proxy_pass https://backend/;(末尾带/),则proxy_redirect中的替换路径也需以/开头
透传并信任 X-Forwarded-Proto,避免协议误判
仅靠重写 Location 不够。如果后端生成跳转时仍基于自身监听地址(如 http://localhost:8080),说明它没识别出原始是 HTTPS。这时必须让后端“知道真相”。
- 在
location块中设置:proxy_set_header X-Forwarded-Proto $scheme; - 若前端有 CDN(如 Cloudflare),优先读取已有头,再兜底 fallback:
default $http_x_forwarded_proto;
"" $scheme;
}
proxy_set_header X-Forwarded-Proto $real_scheme;
- 后端框架(如 Spring Boot、Django)需启用对
X-Forwarded-Proto的信任,否则该头会被忽略
禁止透传恶意 Host,防止 Host 注入跳转
重定向目标中的域名不能来自客户端输入。若用 $host 或 $http_host 拼接跳转地址,攻击者可伪造 Host 头,诱导用户跳转到钓鱼站点。
- 重定向时优先使用
$server_name(配置中声明的合法域名) - 多域名场景下,必须白名单校验后再跳转:
return 301 https://$host$request_uri;
}
return 403;
- 同时,在 server 入口启用
default_server,拦截未匹配server_name的非法 Host 请求
同步传递 Host 与其它上下文头
后端构建完整跳转 URL 不仅需要协议,还需要真实域名、端口和路径。缺失任一字段,都可能导致拼出 localhost 或错误端口。
-
proxy_set_header Host $host;—— 保证后端看到的是用户访问的域名,而非上游地址 -
proxy_set_header X-Forwarded-Host $host;和proxy_set_header X-Forwarded-Port $server_port; -
proxy_set_header X-Real-IP $remote_addr;和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;


















