启用 includesubdomains 会强制所有一级子域(如 api.example.com)独立支持 https 并返回带 always 的完整 hsts 头,否则主域可能被浏览器永久拦截;必须逐项验证子域证书、端口、响应头及 cdn 透传,并灰度测试 max-age=300 后再上线。

在 Nginx 中为 HSTS 添加 includeSubDomains,不是简单加个参数就完事——它会把安全策略强制扩展到所有一级子域名(如 api.example.com、www.example.com、cdn.example.com),一旦启用,这些子域必须独立支持 HTTPS,否则用户将无法访问,且浏览器可能永久拒绝加载主域。
必须满足的硬性前提
启用前请逐项确认:
- 所有一级子域名已配置有效 TLS 证书,并监听 443 端口(不能只靠 HTTP 301 跳转)
- 每个子域的 HTTPS 响应(含 404、500、302 页面)都返回完整 HSTS 头,且带 always 参数
- 主站和全部子域均已实现全站 HTTPS,无任何 HTTP 明文入口(包括管理后台、测试路径)
- CDN(如 Cloudflare)已开启 Strict-Transport-Security 透传,不过滤或覆盖该头
Nginx 配置写法(仅限 HTTPS server 块)
以下为正确示例,必须放在 listen 443 ssl 的 server 块内:
- 不能写在 http 或 location 顶层;否则可能被覆盖或误生效
- always 不可省略:确保错误页、重定向也携带 HSTS,避免策略中断
- 若暂未全量覆盖子域,先去掉
includeSubDomains和preload,仅对主站生效
上线前必须做的验证动作
别跳过这步,否则可能引发大面积访问失败:
- 用
curl -I https://api.example.com检查每个子域:状态码必须是 2xx,且响应头中含相同 HSTS 字段 - 访问子域的 404 页面(如
https://api.example.com/xxx),确认 HSTS 头依然存在 - 检查 Nginx 错误日志,搜索
ssl_handshake_failed或no suitable certificate - 灰度阶段先设
max-age=300(5 分钟),观察至少 15 分钟再逐步上调
注意 includeSubDomains 不递归生效
它只作用于一级子域,例如:
-
includeSubDomains→ 保护api.example.com、www.example.com -
不保护
dev.api.example.com或staging.www.example.com - 如需保护二级子域,需单独为其配置 HTTPS + HSTS











