nginx如何添加CSP策略
在 Nginx 中添加 Content-Security-Policy (CSP) 头部可以通过在 Nginx 配置文件中使用 add_header 指令来实现。CSP 是一种安全机制,用于限制页面加载的资源(如脚本、样式、图片等)的来源,从而减少 XSS(跨站脚本攻击)等安全风险。以下是详细步骤和示例代码。
一.实现步骤
1.确定 CSP 策略:
- 定义你的 CSP 策略,指定允许的资源来源(如 default-src、script-src、style-src 等)。
- 常见的 CSP 指令包括:default-src:默认资源来源。
script-src:脚本来源。 style-src:样式表来源。 img-src:图片来源。 connect-src:AJAX/fetch 请求来源。 frame-src:框架来源。 font-src:字体来源。 object-src:对象(如 Flash)来源。 report-uri:违反 CSP 的报告发送地址。 |
# 正确的 Content-Security-Policy 配置
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: lx: 'unsafe-inline'; script-src 'self' 'unsafe-eval' 'unsafe-inline' http: https:;" always;
2.修改 Nginx 配置文件:
- 使用 add_header 指令在 HTTP 响应中添加 Content-Security-Policy 头部。
- 可以全局配置(在 http 块中)或针对特定站点(在 server 或 location 块中)。
3.测试和验证:
- 重载 Nginx 配置并测试 CSP 是否生效。
- 使用浏览器的开发者工具(F12 -> Console)检查 CSP 错误或警告。
二.示例代码
以下是一个在 Nginx 中添加 CSP 的示例,限制脚本和样式仅从自身域名加载,并允许图片从任意来源加载:
示例 1:基本 CSP 配置
http { server { listen 80; server_name example.com; # 添加 Content-Security-Policy 头部 add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src *; connect-src 'self';"; location / { root /var/www/html; index index.html; } } } |
说明
default-src 'self':默认只允许从当前域名加载资源。 script-src 'self':脚本只允许从当前域名加载。 style-src 'self':样式表只允许从当前域名加载。 img-src *:图片允许从任意来源加载。 connect-src 'self':AJAX/fetch 请求只允许发送到当前域名。 add_header:将 CSP 头部添加到所有响应中。 |
示例 2:更复杂的 CSP 配置
如果你需要支持外部资源(如 CDN)或内联脚本,可以进一步扩展 CSP:
http { server { listen 80; server_name example.com; # 复杂的 CSP 配置 add_header Content-Security-Policy "default-src 'self'; " "script-src 'self' https://cdn.example.com 'unsafe-inline'; " "style-src 'self' https://cdn.example.com 'unsafe-inline'; " "img-src 'self' data: https://images.example.com; " "connect-src 'self' https://api.example.com; " "frame-src 'none'; " "font-src 'self' https://fonts.example.com; " "report-uri /csp-report;"; # CSP 报告收集接口(可选) location /csp-report { # 假设后端处理 CSP 报告 proxy_pass http://backend/csp-report; } location / { root /var/www/html; index index.html; } } } |
说明
'unsafe-inline':允许内联脚本和样式(需谨慎,可能降低安全性)。 data::允许通过 data: URL 加载图片(如 base64 编码的图片)。 https://cdn.example.com:允许从特定 CDN 加载脚本或样式。 frame-src 'none':禁止加载任何框架(iframe)。 report-uri /csp-report:将 CSP 违反报告发送到指定接口(需要后端支持)。 外部域名:明确指定可信的外部域名(如 https://api.example.com)。 |
三.测试和重载配置
1.验证配置文件:
nginx -t
确保配置文件语法正确。
2.重载 Nginx:
systemctl reload nginx
或:
nginx -s reload
3.验证 CSP 是否生效:
- 打开浏览器,访问你的网站。
- 按 F12 打开开发者工具,切换到 Network 面板,检查响应头是否包含 Content-Security-Policy。
- 在 Console 面板查看是否有 CSP 相关的错误或警告。
四.注意事项
- 逐步测试 CSP:
CSP 配置可能导致页面资源加载失败(如脚本、样式、图片等)。建议先使用 Content-Security-Policy-Report-Only 头部进行测试:
add_header Content-Security-Policy-Report-Only "default-src 'self'; report-uri /csp-report;"; |
这不会阻止资源加载,但会报告违反 CSP 的情况。
- 动态内容:
如果你的 Vue 应用使用内联脚本(如 <script>alert('test')</script>)或内联样式(如 <style>body { color: red; }</style>),需要添加 'unsafe-inline',但这会降低安全性。推荐使用 CSP 非ce 或哈希值(sha256-...)来允许特定内联内容:
add_header Content-Security-Policy "script-src 'self' 'sha256-<hash-of-script>';"; |
- 报告收集:
如果启用了 report-uri,需要后端支持接收和处理 CSP 报告(例如使用 Node.js、Python 等)。
- 性能和兼容性:
CSP 头部过长可能影响性能,尽量精简策略。
确保 CSP 配置与你的 Vue 应用和其他前端框架兼容,避免阻塞必要的资源。
- 调试工具:
使用在线工具(如 https://csp-evaluator.withgoogle.com/)评估你的 CSP 配置。
检查浏览器 Console 中的错误,逐步调整策略。
五.示例日志
如果你结合之前的请求日志需求,可以在 Nginx 日志中记录 CSP 头(通过响应头记录)。但通常 CSP 是作为响应头添加的,请求日志不会直接包含它。如果需要记录,可以通过 Lua 模块或其他方式捕获响应头。