最稳妥简洁的全站安全响应头注入方式是在http块统一配置add_header ... always,覆盖所有状态码(含404/500/302/304),避免防护断层;必须加always参数,否则仅对2xx/3xx生效。

在 Nginx 中,最稳妥、最简洁的全站安全响应头注入方式,就是在 http 块层级统一配置 add_header ... always。它天然覆盖所有 server 和 location,包括 404、500 等错误页面,避免遗漏导致防护断层。
必须写在 http 块里,且加 always 参数
打开主配置文件(如 /etc/nginx/nginx.conf),找到 http { } 区域,在 include /etc/nginx/mime.types; 之后、任何 server { } 之前插入:
add_header X-Frame-Options "SAMEORIGIN" always;add_header X-Content-Type-Options "nosniff" always;add_header X-XSS-Protection "1; mode=block" always;add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'" always;
重点:always 不可省略。没有它,Nginx 默认只对 2xx/3xx 成功响应添加头,而 404、503、500 页面将完全不携带这些头——这是线上常见疏漏点。
防止被子配置意外覆盖
add_header 在低层级(如 server 或 location)中会完全替换同名上级头,不是追加。因此要严格遵守:
- 检查所有
server块,删除重复的add_header X-Frame-Options等语句 - 若某个
location需额外头(例如 API 接口要加Access-Control-Allow-Origin),必须显式重写全部必需安全头,或改用more_set_headers模块(需提前编译安装) - 禁用可能清除响应头的模块,比如某些缓存插件或自定义代理逻辑
验证是否真正全状态码生效
重载配置后,不能只测首页:
- 用
curl -I https://yoursite.com/查看正常响应头 - 用
curl -I https://yoursite.com/404-not-exist查看 404 页面是否也带齐所有头 - 访问一个故意触发 500 的路径(如后端崩溃接口),确认 500 响应同样包含
- 用 securityheaders.com 扫描主域名,查看评分和缺失项
若发现静态资源(如 .js/.css)没带头,大概率是被某个独立 location ~ \.js$ { } 块拦截并终止了继承链——此时需在该 location 内补全带 always 的安全头。
宝塔面板用户的快捷路径
如果你用的是宝塔面板,不建议直接改站点配置文件(易被面板覆盖)。推荐两种更稳定的方式:
-
全局配置法:进入【软件商店】→ 找到 Nginx → 【设置】→ 【配置修改】→ 在
http块内粘贴上述add_header ... always代码,保存后重载 -
反向代理注入法:适用于 Node/Python 等后端应用。进网站【设置】→ 【反向代理】→ 编辑代理 → 在【发送头部信息】里逐行填入:
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security: max-age=31536000; includeSubDomains
勾选启用即可,所有代理请求自动带上











