nginx 配置 hsts 需同时实现 http 301 跳转与 https 的 strict-transport-security 响应头:80 端口用 return 301 强制跳转,443 端口在 ssl server 块中 add_header ... always;启用 includesubdomains 和 preload 前须确保所有子域 https 可用且证书有效,并先以 max-age=300 灰度测试。

要在 Linux 上用 Nginx 配置 HSTS 强制客户端使用 HTTPS,核心是两件事:让首次 HTTP 请求安全跳转,再让浏览器记住“以后只走 HTTPS”。单靠跳转不行,单靠 HSTS 也不行——必须配合。
80 端口必须做 301 跳转
这是用户第一次访问 http:// 时的唯一防线。配置一个干净的 server 块,只负责跳转:
- 监听
80端口,不启用 SSL,不加任何 location 或证书配置 - 用
return 301 https://$host$request_uri;(不是 rewrite) -
$host自动匹配请求头中的域名,支持多域名;$request_uri完整保留路径和查询参数 - 别写
ssl on或证书路径,否则nginx -t会报错
443 端口必须启用有效 HTTPS 并加 HSTS 头
HSTS 只能通过 HTTPS 响应生效,且必须配置在 listen 443 ssl 的 server 块里:
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
- 确认证书路径正确:
ssl_certificate指向fullchain.pem,ssl_certificate_key指向privkey.pem - 加上这行:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; -
always很关键:确保 404、500、304 等响应也带 HSTS 头,避免策略中断 - 不要放在 http 块或 location 块顶层——server 块内才可靠;location 里若另配 add_header,会覆盖 server 级的头
谨慎启用 includeSubDomains 和 preload
这两个参数扩大影响范围,启用前必须验证到位:
-
includeSubDomains:意味着api.example.com、cdn.example.com等所有一级子域都必须能 HTTPS 访问且证书有效 -
preload:用于提交到浏览器预加载列表,要求更严——主站 + 所有子域都要 HTTPS、重定向闭环、max-age ≥ 31536000、且必须含includeSubDomains - 首次上线建议先用
max-age=300(5 分钟)灰度测试,确认跳转、证书、子域全正常后再调高 - 若后端(如 Java/Python 应用)自己返回 HSTS 头,需在 proxy_pass 的 location 中加
proxy_hide_header Strict-Transport-Security,避免冲突
上线前必须验证的三件事
配置写完只是开始,漏一项就可能失效:
- 运行
sudo nginx -t检查语法,重点看证书路径是否存在、Nginx 用户是否有读取权限(尤其privkey.pem) - 用
curl -I http://example.com确认返回 301;再用curl -I https://example.com确认响应头含Strict-Transport-Security - 打开浏览器开发者工具 → Network 标签,访问 HTTPS 页面,检查各类型资源(HTML、JS、PHP、图片)响应头是否都有该字段










