应使用$http_host透传原始host头,因其完整保留客户端请求的域名和端口,避免签名失败、重定向异常等问题;每级nginx代理均需统一配置proxy_set_header host $http_host,并同步设置x-real-ip与x-forwarded-for。

多层代理下 Host 头被层层改写,后端应用拿到的 Host 往往不是客户端原始请求的域名,导致签名失败、静态资源路径错误、重定向跳转异常等问题。关键在于让 Host 头在每一级 Nginx 代理中都稳定透传原始值,而不是被替换成 upstream 地址或中间代理的 server_name。
优先使用 $http_host 保证原始 Host 完整透传
客户端发起的 HTTP 请求中,Host 头可能包含端口(如 api.example.com:8080)。$http_host 变量直接取自原始请求头,原样保留域名和端口,不作任何归一化处理。这对依赖完整 Host 做签名、鉴权或路由的后端系统最安全。
- 配置示例:proxy_set_header Host $http_host;
- 适用场景:Java Spring Boot、Node.js 等直接读取 request.getHeader("Host") 的服务
- 注意:若客户端未带 Host 头(极少见),$http_host 为空,Nginx 会返回 400 错误,符合 HTTP/1.1 规范
慎用 $host —— 默认端口会被自动剥离
$host 变量在有 Host 请求头时等价于 $http_host,但当 Host 中端口是 80 或 443 时,Nginx 会主动省略该端口。例如客户端请求 Host: app.example.com:80,后端收到的却是 app.example.com。签名算法若严格校验 Host 字符串,就会失败。
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 配置示例:proxy_set_header Host $host;
- 风险点:破坏端口敏感型签名逻辑;重定向 Location 头生成错误(如 302 跳转缺端口)
- 仅建议用于纯域名路由且后端不校验端口的简单场景
禁用 $proxy_host —— 它指向 upstream 地址,非客户端意图
$proxy_host 是 proxy_pass 指令中指定的目标地址(如 10.10.2.5:8080 或 backend-svc)。用它设置 Host 头会使后端看到的是内部服务名或 IP,完全丢失客户端原始上下文,签名必然失效。
- 默认行为:未显式配置 proxy_set_header Host 时,Nginx 自动使用 $proxy_host
- 后果:后端日志里 Host 全是内网地址;API 网关无法按域名分发流量;HTTPS 下 SNI 与 Host 不一致
- 务必显式覆盖,避免隐式行为
多层代理链中每级都要统一配置
假设请求路径为:Client → Nginx-A → Nginx-B → Backend。若只在 Nginx-A 设置 $http_host,Nginx-B 若未配置或用了 $host,则 Host 在第二跳就被篡改。必须确保链上所有 Nginx 实例的 location 块中均含:
- proxy_set_header Host $http_host;
- 同时补全真实 IP 传递:proxy_set_header X-Real-IP $remote_addr; 和 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- 避免某一级遗漏导致整条链失效










