最稳妥方式是在每个https server块内配置add_header ... always;,安全头须紧贴ssl配置、覆盖所有状态码,并按站点实际资源定制hsts与csp策略。

直接在每个 HTTPS 的 server 块内配置 add_header ... always;,是最稳妥、最推荐的方式。安全头必须紧贴 SSL 配置,覆盖所有响应状态码,并按站点实际资源加载逻辑定制策略。
必须放在 HTTPS server 块中,不能放全局
Nginx 每个 server 块对应一个域名或一组域名,安全头要和 listen 443 ssl 共存于同一作用域。例如:
- ✅ 正确位置:SSL 证书配置下方、
location外的任意处 - ❌ 错误做法:写在
http { }最外层,会导致 HTTP 站点误带 HSTS,或子站因 CSP 过严白屏 - ❌ 不要放在 80 端口 server 块里——HSTS 在非加密连接下被浏览器直接忽略
务必加上 always 参数
默认情况下,add_header 只对 2xx 成功响应生效。但 301/302 重定向、404 页面、500 错误页同样需要安全防护,否则策略会中断失效。
- ❌
add_header Strict-Transport-Security "max-age=31536000";→ 404 不带 HSTS,浏览器不会记住强制 HTTPS - ✅
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;→ 所有状态码都携带 - 同理,X-Content-Type-Options、CSP、Referrer-Policy 等关键头也建议统一加
always
按站点实际启用 HSTS 和 CSP
HSTS 的 includeSubDomains 和 CSP 的源列表不是通用模板,必须匹配真实部署情况。
- HSTS 启用
includeSubDomains前,确保所有一级子域(如api.example.com、cdn.example.com)已部署有效 HTTPS 证书,否则会锁死访问 - CSP 不能照搬示例:
– 用了 Google Fonts?补上font-src fonts.gstatic.com;
– 嵌了 YouTube 视频?加frame-src youtube.com;
– 初次上线建议先用Content-Security-Policy-Report-Only观察两周,再切正式拦截
基础安全头推荐配置(HTTPS 站点)
以下为兼顾兼容性与防护力的常用组合,可直接放入 HTTPS server 块:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;add_header X-Content-Type-Options "nosniff" always;add_header X-Frame-Options "DENY" always;add_header X-XSS-Protection "1; mode=block" always;add_header Referrer-Policy "strict-origin-when-cross-origin" always;add_header Content-Security-Policy "default-src 'self'; script-src 'self'; connect-src 'self'; img-src 'self' data:;" always;











