安全头必须在https的server块内配置且带always参数,不可放在http顶层;csp需按业务定制并先用report-only模式测试。

直接在 server 块里加 add_header ... always;,位置要紧贴 SSL 配置或放在 location 外任意处,不能写在 http 块顶层。
必须放在 HTTPS 的 server 块内
每个 server 块对应一个域名(或一组域名),安全头要和 listen 443 ssl 共存。比如:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
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 Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
一定要带 always 参数
不加 always,add_header 只对 2xx 响应生效。而 301、404、500 等状态码同样需要防护——否则 HSTS 不会被浏览器记住,CSP 在错误页也不起作用。
别用全局配置
写在 http { } 最外层会让所有站点(包括 HTTP 站点)都继承这些头。比如给 HTTP 站点也加了 HSTS,浏览器会拒绝访问;CSP 过严还可能让子站白屏。
CSP 要按实际业务写
不能照搬模板。如果用了 Google Fonts,就得加 font-src fonts.gstatic.com;;嵌了 YouTube,就要加 frame-src youtube.com;。上线前建议先用 Content-Security-Policy-Report-Only 模式收集两周违规日志,再切正式策略。
宝塔用户不用手改
进【网站】→ 点击站点【设置】→【配置文件】选项卡,在 server 块里、location / 上方或下方粘贴 add_header 行即可。











