在 nginx 的 http 块中使用 add_header ... always 指令统一注入安全头,可实现全站覆盖且确保错误页不遗漏;需避免子配置覆盖,并通过 curl 和在线工具验证各状态码响应头是否完整生效。

在 Nginx 中,http 块是全局配置层级,所有 server(虚拟主机)都会继承其中的设置。利用它注入安全头,是最简洁、最可靠的全站统一防护方式——无需修改每个应用代码或重复配置多个 location。
一、在 http 块中直接添加 add_header 指令
打开 Nginx 主配置文件(通常是 /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' 'unsafe-eval'; style-src 'self' 'unsafe-inline'" always;
注意:必须加 always 参数。否则 Nginx 默认只对 2xx/3xx 响应添加头,而错误页(如 404、500)将缺失这些头,导致防护不完整。
二、避免被子配置覆盖的关键原则
安全头需“强制生效”,但 Nginx 的 add_header 在低层级(如 server 或 location)中会完全覆盖上级同名头,而非追加。因此要确保:
- 所有 server 块中不要重复写
add_header X-Frame-Options等语句,除非有明确的差异化策略 - 若某个 location 需要额外头(如 API 接口加
Access-Control-Allow-Origin),应显式重新声明全部必需头,或改用more_set_headers(需安装 headers-more-nginx-module)实现追加 - 检查是否启用了可能干扰的模块,例如某些缓存插件或反向代理配置可能清除或重写响应头
三、验证与调试方法
配置完成后,执行 nginx -t 测试语法,再 nginx -s reload 生效。验证是否生效:
- 用 curl 查看响应头:
curl -I https://yoursite.com - 访问任意路径(包括不存在的 404 页面),确认所有状态码响应都包含上述头
- 使用在线工具如 securityheaders.com 扫描主域名,检查评分和缺失项
若发现某类请求(如静态资源)未携带头,常见原因是:该请求被其他 location 块匹配并终止了继承链——此时应在对应 location 内补全 add_header ... always;,或统一收口到 http 块管理。










