https重定向必须在nginx入口网关的listen 80 server块中集中控制,使用return 301 https://$host$request_uri;,目标域名须与ssl证书一致;禁用proxy_pass后重定向,防范host头注入需配合map白名单校验,并仅信任cdn设置的x-forwarded-proto以确保协议判断准确。

重定向必须落在入口网关的 80 端口 server 块里
所有 HTTP 流量(listen 80)必须由 Nginx 主动拦截并 301 跳转,不能交给后端或嵌套在 location /proxy_pass 之后。否则会绕过控制、引发循环跳转或证书不匹配。
- 正确写法:
return 301 https://$host$request_uri;放在server { listen 80; }中 - 目标域名必须与 SSL 证书一致(CN 或 SAN),例如证书含
api.example.com,就别跳www.example.com - 禁用
rewrite在 proxy_pass 后做跳转——那已是代理响应,不属于网关级控制
跳转目标要固定或白名单校验,拒绝 Host 头注入
用户可随意伪造 Host 请求头,直接用 $host 构造跳转 URL 有风险。生产环境应限制可跳转的域名范围。
- 推荐方式:用固定域名,如
return 301 https://api.example.com$request_uri; - 若需多域名支持,配合
map指令白名单校验:map $host $valid_host { default ""; api.example.com "api.example.com"; admin.example.com "admin.example.com"; }
再用return 301 https://$valid_host$request_uri;,非法 host 直接返回 444 或 400
多层网关嵌套时,只信任最外层的协议信号
当架构为 CDN → Nginx 网关 → 微服务时,X-Forwarded-Proto 只能由 CDN 设置并信任,中间层 Nginx 必须设为不可信,否则可能被伪造导致误判 HTTP/HTTPS。
- 在 Nginx 中明确指定可信代理段:
set_real_ip_from 192.168.0.0/16;(填 CDN 回源 IP 段) - 启用:
real_ip_header X-Forwarded-For;和real_ip_recursive off; - 判断是否 HTTPS 时,只认
$scheme或$http_x_forwarded_proto(且仅当该 header 来自可信源)
微服务路径路由与重定向要解耦
重定向解决的是“协议升级”,路径路由(如 /user/ → user-service)是另一层逻辑。两者不能混在一起配置,否则容易因 proxy_redirect 或后端 302 导致跳转错乱。
- 确保所有
location块只出现在server { listen 443 ssl; }下,listen 80块只做跳转,不配任何proxy_pass - 后端服务返回的重定向(如 302)需用
proxy_redirect重写,避免暴露内网地址或错误路径:proxy_redirect http://user-svc:8001/ /user/; - 若后端返回
Location: http://...,先用proxy_redirect改写协议和域名,再确保它走 HTTPS











