一、问题背景:安全评分仅70分
使用安全扫描工具检测站点时,发现多个基于宝塔面板+Nginx搭建的Z-Blog站点(包括 aiqixie.com、ally.ren、maolaoban.com 等)安全评分仅为70/100。扫描报告显示缺失以下关键响应头:
Content-Security-Policy(CSP)— 高风险
X-Frame-Options — 高风险
X-Content-Type-Options — 中风险
Referrer-Policy — 缺失
同时,配置中已有的 Strict-Transport-Security(HSTS)缺少 includeSubDomains 与 always 参数,导致错误响应时安全头不生效。
二、七项核心安全响应头配置详解
以下所有配置均放置在 Nginx 主站 server 块的 #SECURITY-HEADERS-START 区域内,保存后执行 nginx -t && nginx -s reload 即可生效。
1. Strict-Transport-Security(HSTS)
强制浏览器一年内只通过 HTTPS 访问站点,包含子域名,并在所有响应(包括错误页)中生效。
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
2. X-Content-Type-Options
禁止浏览器猜测文件 MIME 类型,防止恶意脚本伪装成图片执行。
add_header X-Content-Type-Options "nosniff" always;
3. X-Frame-Options
防止点击劫持,允许同域 iframe 嵌入,禁止第三方站点嵌套。
add_header X-Frame-Options "SAMEORIGIN" always;
4. X-XSS-Protection
启用浏览器内置 XSS 过滤器,发现攻击时阻断页面加载。
add_header X-XSS-Protection "1; mode=block" always;
5. Referrer-Policy
控制跨站请求时 Referrer 的发送策略,保护用户隐私。
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
6. Permissions-Policy
禁用浏览器敏感设备 API,防止广告或恶意脚本调用摄像头、麦克风等。
add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" always;
7. Content-Security-Policy(CSP)— 重点
CSP 是提升安全评分最关键的配置,用于限制页面可加载的外部资源来源。由于站点同时投放了 Google AdSense、Google Analytics、Google Fonts,并集成了百度自动推送和字节跳动站点推送,策略必须覆盖这些域名的全部动态子域名。
特别注意:Google 注册了 .google 品牌顶级域名(如 ep1.adtrafficquality.google),常规 *.google.com 通配符无法匹配,必须额外加入 *.google。
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.google.com https://*.google https://*.googlesyndication.com https://*.doubleclick.net https://*.google.cn https://*.googletagservices.com https://*.google-analytics.com https://*.googletagmanager.com https://*.bytegoofy.com https://*.bdstatic.com https://*.googleapis.com; style-src 'self' 'unsafe-inline' https://*.googleapis.com; img-src 'self' data: http: https: https://*.google.com https://*.google https://*.googlesyndication.com https://*.doubleclick.net https://*.google-analytics.com; font-src 'self' data: https://*.gstatic.com; connect-src 'self' https://*.google.com https://*.google https://*.googlesyndication.com https://*.doubleclick.net https://*.google-analytics.com https://*.bytegoofy.com https://*.bdstatic.com; frame-src 'self' https://*.google.com https://*.google https://*.googlesyndication.com https://*.doubleclick.net; object-src 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests;" always;
三、CSP实战踩坑记录
在配置过程中,浏览器控制台先后出现以下 CSP 拦截报错,需按序补充域名:
Google AdSense 脚本:
pagead2.googlesyndication.com、googletagservices.com、adservice.google.com、tpc.googlesyndication.comGoogle 反欺诈/质量检测:
ep1.adtrafficquality.google、ep2.adtrafficquality.google(属于*.googleTLD)Google Funding Choices / GDPR 消息:
fundingchoicesmessages.google.comGoogle Fonts:
fonts.googleapis.com(style-src)、fonts.gstatic.com(font-src)百度自动推送:
zz.bdstatic.com字节跳动(头条/抖音)推送:
lf1-cdn-tos.bytegoofy.com
使用 *.google.com、*.google、*.googlesyndication.com、*.doubleclick.net 等通配符后,可覆盖未来可能出现的动态子域名,避免反复修改配置。
四、Nginx配置中的其他关键优化
1. always 参数不可省略
Nginx 的 add_header 默认只在 200/201/204 等成功响应中生效。加入 always 可确保 404/500 等错误页面也下发安全头,防止攻击者通过触发错误页绕过 CSP。
2. 正则语法修正
部分历史配置中证书验证目录写为 location ~ /\.well-known,反斜杠在正则中有歧义,统一修正为:
location ~ \.well-known {
allow all;
}3. TLS 协议与加密套件升级
移除不安全的 TLSv1.1 和 3DES 套件,仅保留 TLSv1.2 + TLSv1.3:
ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:!MD5;
4. 拆分 80 与 443 server 块
对于使用 if ($server_port !~ 443) 做跳转的站点,建议拆分为独立的 listen 80 和 listen 443 server 块,使用 return 301 跳转,避免 Nginx if 指令的性能损耗和潜在异常。
五、多站点通用配置模板
以下模板适用于宝塔面板下的 Z-Blog PHP 站点或 Go 反向代理站点,仅需替换域名和证书路径:
# HTTP 统一跳转 HTTPS
server {
listen 80;
server_name example.com www.example.com;
location ~ \.well-known { allow all; }
return 301 https://www.example.com$request_uri;
}
# 裸域 HTTPS 跳转 WWW
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
return 301 https://www.example.com$request_uri;
}
# 主站业务逻辑
server {
listen 443 ssl http2;
server_name www.example.com;
root /www/wwwroot/example.com;
index index.php index.html;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:!MD5;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# 安全响应头
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.google.com https://*.google https://*.googlesyndication.com https://*.doubleclick.net https://*.google.cn https://*.googletagservices.com https://*.google-analytics.com https://*.googletagmanager.com https://*.bytegoofy.com https://*.bdstatic.com https://*.googleapis.com; style-src 'self' 'unsafe-inline' https://*.googleapis.com; img-src 'self' data: http: https: https://*.google.com https://*.google https://*.googlesyndication.com https://*.doubleclick.net https://*.google-analytics.com; font-src 'self' data: https://*.gstatic.com; connect-src 'self' https://*.google.com https://*.google https://*.googlesyndication.com https://*.doubleclick.net https://*.google-analytics.com https://*.bytegoofy.com https://*.bdstatic.com; frame-src 'self' https://*.google.com https://*.google https://*.googlesyndication.com https://*.doubleclick.net; object-src 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests;" always;
add_header Permissions-Policy "accelerometer=(), camera=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), payment=(), usb=()" always;
location / {
try_files $uri $uri/ /index.php?$args;
}
# PHP 或反向代理配置...
}六、验证方法
配置生效后,通过以下命令验证响应头:
curl -I https://www.example.com
确认返回中包含 content-security-policy、x-frame-options、referrer-policy、permissions-policy 等字段。随后使用在线安全扫描工具重新检测,评分应从 70/100 提升至 95+/100。
七、总结
网站安全响应头的配置是一项“一次性投入、全站受益”的基础加固工作。本文提供的 CSP 策略经过 Google AdSense、Analytics、Fonts、百度推送及字节跳动推送的实际兼容性验证,可直接应用于生产环境。后续如接入新的第三方服务,只需根据浏览器控制台 CSP 报错补充对应域名即可。