nginx中为https站点配置安全响应头必须在对应server块内使用add_header并加always参数;需按站点实际需求定制hsts、csp等头,严禁全局http块配置或遗漏错误状态码。

在 Nginx 中为指定虚拟主机(即某个 server 块)注入安全响应头,核心原则是:**每个 HTTPS 站点必须在自己的 server 块内显式配置 add_header,且必须带 always 参数**。这样既能精准适配该站点的证书状态、子域策略和资源加载逻辑,又能避免误伤其他站点。
必须放在 server 块内,不能放全局 http 块
Nginx 的 server 块对应一个或多个域名(如 server_name example.com www.example.com;)。所有安全头都应紧贴 SSL 配置写在该块内部,例如:
-
listen 443 ssl;下方或location外任意位置均可 - 若写在
http { }最外层,HTTP 站点也会被强制带上 HSTS,可能造成子站无法访问 - 多个站点共用一套头策略,容易因 CSP 过严导致白屏,或 HSTS 错误覆盖非 HTTPS 子域
务必加上 always 参数
默认情况下,add_header 只对 2xx 成功响应生效。但 301/302 重定向、404 页面、500 错误页同样需要安全防护:
- 不加
always:HSTS 在 404 响应中不会发送,浏览器无法记住强制 HTTPS - 加
always:所有状态码(包括错误页和跳转)都携带安全头,真正起效 - 正确写法:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
按站点实际需求定制关键头
不同站点用途不同,头部策略不能一刀切:
-
X-Frame-Options:主站可用SAMEORIGIN,管理后台建议DENY -
Content-Security-Policy:需结合前端资源来源设定,避免直接用'unsafe-inline',生产环境应限制 script-src 和 style-src -
Strict-Transport-Security:仅在已部署有效 TLS 证书的 HTTPSserver块中启用;includeSubDomains要谨慎,确保所有子域都支持 HTTPS -
Referrer-Policy推荐用strict-origin-when-cross-origin,兼顾隐私与功能
常见错误要避开
这些写法看似省事,实则隐患明显:
- 在
http块里统一写add_header→ 所有站点强制继承,不可控 - 把
add_header写在location /api里却没写在根location /→ 首页不带安全头 - HSTS 同时出现在
example.com和blog.example.com的独立server块中 → 若后者 HTTPS 不稳定,会连带主站被锁死 - CORS 头用
*且开启Access-Control-Allow-Credentials true→ 浏览器直接拒绝,必须指定具体域名











