Nginx 配置安全加固后网站打不开怎么办?

Mr.东芳 阅读 63

我按照网上教程给 Nginx 做了安全加固,加了一些 header 和限制,结果一 reload 服务,前端页面就完全打不开了,浏览器报 502 或空白。我只改了 server 块里的配置,没动其他地方。

比如加了这些:

add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header Content-Security-Policy "default-src 'self';";

是不是 CSP 策略太严格把静态资源拦了?但控制台也没看到具体报错,有点懵,该怎么排查?

我来解答 赞 7 收藏
二维码
手机扫码查看
2 条解答
Zz新霞
Zz新霞 Lv1
兄弟,你猜对了,十有八九就是CSP把资源干了。

default-src 'self' 这个策略太狠了,只允许同源加载,WordPress站点一般都有主题/插件的静态资源,可能还用了CDN的字体或jQuery什么的,全被CSP拦住了,所以页面基本是白的。控制台没报错是因为CSP默认不显示详细信息。

先快速确认是不是这个问题:

用curl看看返回的header对不对:
curl -I https://你的域名


如果能看到你加的那些header,说明配置生效了。然后打开浏览器F12的Network面板,看看哪个资源显示blocked,或者哪个请求直接没返回。

解决思路有两个:

一是先放宽CSP,用Report-Only模式跑一段时间看都哪些资源被拦:
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' data: https:; font-src 'self' data:; report-uri /csp-report;";


这样不会真正block资源,只是把违规报告发到/csp-report路径,你可以通过日志或自己写个接口收集一下,看看站点实际需要加载哪些外部资源。

二是直接配一个相对宽松但能用的策略,WordPress站点一般这样:
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' *.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' data: https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https:;";


具体要放开哪些域名,看你站点实际用了什么CDN、统计脚本、字体服务之类的。

还有一个坑:Nginx的add_header在if块里会失效,另外如果你server块里已经有一个add_header,后面的会直接覆盖而不是合并。检查一下有没有这种情况。

如果改完reload还是502,先确认PHP-FPM正常没挂,简单的办法是直接访问一个PHP文件看看:
curl -I https://你的域名/index.php


能返回200说明PHP没问题,那就还是CSP的问题。
点赞 1
2026-03-14 00:03
小利娇
小利娇 Lv1
啊,这个我熟,刚踩过类似的坑。CSP策略确实很容易搞挂页面,尤其是当你的前端用了CDN或者一些第三方资源的时候。

先别慌,按这个顺序排查:
1. 临时先把CSP那行注释掉,reload看页面能不能恢复,确认是不是它的问题
2. 打开浏览器开发者工具,看Network面板,应该能看到被拦截的资源(虽然你说是空白,但可能有隐藏的报错)
3. 如果确认是CSP问题,可以先用这个宽松点的策略测试:
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob: *.yourcdn.com";


几个注意点:
- 加了unsafe-inline和unsafe-eval是为了兼容老式前端框架(虽然不太安全但能临时解决问题)
- 记得把yourcdn.com换成你实际用的CDN域名
- 静态资源如果是跨域的,必须显式声明域名

更好的写法是逐步收紧策略:先允许所有来源让页面能跑起来,然后根据浏览器控制台的报错一个个添加白名单。我上次搞这个调了整整两天,咖啡都喝吐了...

另外502可能是其他原因,检查下nginx error log,路径一般是/var/log/nginx/error.log,看有没有语法错误或者权限问题。
点赞 2
2026-03-07 16:11