Nginx直连客户端时,HTTP→HTTPS跳转首选return 301 https://$server_name$request_uri;;在Azure网关等代理后,须依据X-Forwarded-Proto头判断原始协议并禁用$host动态跳转;Ingress场景下应由控制器统一管理跳转,避免手动配置冲突。

HTTPS 重定向在纯 Nginx 环境下最直接
当 Nginx 是唯一入口(直连客户端)时,HTTP → HTTPS 跳转可由 return 301 https://$server_name$request_uri; 一行完成。它不依赖外部信号,$server_name 安全可靠,$request_uri 完整保留原始编码,无中间变量污染风险。这种配置简单、高效、可控,是标准场景下的首选。
在 Azure 应用网关后端时,Nginx 不能按原逻辑跳转
应用网关会做 SSL 卸载,前端 HTTPS 请求到达网关后,被解密并以 HTTP 方式转发给后端 Nginx(通常走内网 80 端口)。此时 Nginx 收到的请求协议是 HTTP,但真实用户访问的是 HTTPS —— 如果仍用 return 301 https://...,会导致循环跳转或错误跳转。
正确做法是:依据 X-Forwarded-Proto 头判断原始协议:
- 若
$http_x_forwarded_proto = "https",说明前端已是 HTTPS,Nginx 不需再跳转 - 若为
"http",才执行跳转,且目标应指向网关暴露的公网 HTTPS 域名(如https://example.com$request_uri),而非 Nginx 自身地址 - 务必禁用基于 $host 的动态跳转,避免 Host 注入
在 Kubernetes Ingress 场景中,重定向常由控制器统一接管
Nginx Ingress Controller 默认提供 ssl-redirect: "true" 和 force-ssl-redirect: "true" 注解,自动在 HTTP 端口注入 301 跳转逻辑。此时不应在自定义 ConfigMap 或 backend server 块里重复写 return/rewrite,否则易冲突。
关键点:
- 跳转目标域名由 Ingress resource 的
host字段决定,不是 $server_name - 若需移动端差异化跳转(如跳 m.example.com),必须在 Ingress annotation 中启用 custom snippet,或改用 Gateway API + Nginx Gateway Fabric 实现精细控制
- 所有跳转均发生在网关层,Pod 内 Nginx 只处理已加密的 HTTPS 流量,不再参与协议判断
多层网关嵌套时,需逐层剥离可信信号
例如:CDN → 应用网关 → Nginx → 后端服务。每层都可能修改或添加 X-Forwarded 头,但并非所有头都可信。安全做法是:
- 只信任最外层网关(如 CDN)设置的
X-Forwarded-Proto,其余层设为不可信 - 在 Nginx 中通过
set_real_ip_from明确指定可信代理 IP 段,并启用real_ip_header X-Forwarded-For; - 构造跳转 URL 时,始终使用固定域名或白名单校验后的 $host,拒绝未经验证的 Host 头输入


















