nginx微服务网关中hsts必须统一在443 ssl server块配置,使用always参数确保全状态码生效,并proxy_hide_header屏蔽后端重复头,includesubdomains需按子域https就绪情况分阶段启用。

在微服务架构中,Nginx 通常作为统一入口网关(API Gateway)或反向代理集群存在。此时 HSTS 不应由各微服务自行输出,而必须由 Nginx 在最外层统一注入——这是唯一可控、可审计、防冲突的方案。
必须在 HTTPS 网关 server 块中配置
HSTS 只对加密连接生效,所以只能放在监听 443 ssl 的网关 server 块内,不能写在 HTTP(80 端口)块或全局 http{} 块里。例如:
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# ✅ 正确:紧贴 SSL 配置后,位于 location 外
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
若网关同时代理多个微服务域名(如 user.api.example.com、order.api.example.com),每个域名需独立定义 server 块,并分别配置 HSTS——不能靠 server_name *.api.example.com 通配,因为证书和策略可能不同。
所有响应状态码都必须携带 HSTS
微服务返回 401、404、500 或 302 重定向时,HSTS 仍需生效,否则策略链会中断。务必使用 always 参数:
- ❌
add_header Strict-Transport-Security "max-age=31536000";→ 仅 2xx 响应携带 - ✅
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;→ 3xx/4xx/5xx 全覆盖
尤其注意:Nginx 自身生成的错误页(如 502 Bad Gateway)、健康检查探针返回的 200/404,以及 /healthz 这类 endpoint,都依赖该设置确保头不丢失。
屏蔽后端微服务重复输出的 HSTS
Spring Boot、Node.js、Go Gin 等框架常默认注入 HSTS,若与 Nginx 冲突,浏览器可能因策略不一致拒绝加载。应在网关中显式隐藏:
proxy_hide_header Strict-Transport-Security;
加在 location 或 server 块内均可,推荐放在 server 块顶部,确保所有 upstream 请求都被处理。
子域名策略要按实际拓扑启用
includeSubDomains 不是“开箱即用”选项。微服务架构中常见子域分离部署(如 auth.api.example.com 由独立团队维护、metrics.api.example.com 走内网 HTTP),此时:
- 若任一子域尚未全量 HTTPS,禁用
includeSubDomains,先保障主网关域名(如api.example.com)生效 - 若已统一 TLS 终止在 Nginx 网关,且所有子域均通过同一证书或 SAN 证书覆盖,再启用
includeSubDomains -
preload仅当满足全站 HTTPS、max-age ≥ 31536000、所有子域响应头含完整 HSTS 时才提交至 hstspreload.org;测试环境严禁开启
不复杂但容易忽略











