Nginx 配置安全加固后网站打不开怎么办?
我按照网上教程给 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 策略太严格把静态资源拦了?但控制台也没看到具体报错,有点懵,该怎么排查?
default-src 'self'这个策略太狠了,只允许同源加载,WordPress站点一般都有主题/插件的静态资源,可能还用了CDN的字体或jQuery什么的,全被CSP拦住了,所以页面基本是白的。控制台没报错是因为CSP默认不显示详细信息。先快速确认是不是这个问题:
用curl看看返回的header对不对:
如果能看到你加的那些header,说明配置生效了。然后打开浏览器F12的Network面板,看看哪个资源显示blocked,或者哪个请求直接没返回。
解决思路有两个:
一是先放宽CSP,用Report-Only模式跑一段时间看都哪些资源被拦:
这样不会真正block资源,只是把违规报告发到/csp-report路径,你可以通过日志或自己写个接口收集一下,看看站点实际需要加载哪些外部资源。
二是直接配一个相对宽松但能用的策略,WordPress站点一般这样:
具体要放开哪些域名,看你站点实际用了什么CDN、统计脚本、字体服务之类的。
还有一个坑:Nginx的add_header在if块里会失效,另外如果你server块里已经有一个add_header,后面的会直接覆盖而不是合并。检查一下有没有这种情况。
如果改完reload还是502,先确认PHP-FPM正常没挂,简单的办法是直接访问一个PHP文件看看:
能返回200说明PHP没问题,那就还是CSP的问题。
先别慌,按这个顺序排查:
1. 临时先把CSP那行注释掉,reload看页面能不能恢复,确认是不是它的问题
2. 打开浏览器开发者工具,看Network面板,应该能看到被拦截的资源(虽然你说是空白,但可能有隐藏的报错)
3. 如果确认是CSP问题,可以先用这个宽松点的策略测试:
几个注意点:
- 加了unsafe-inline和unsafe-eval是为了兼容老式前端框架(虽然不太安全但能临时解决问题)
- 记得把yourcdn.com换成你实际用的CDN域名
- 静态资源如果是跨域的,必须显式声明域名
更好的写法是逐步收紧策略:先允许所有来源让页面能跑起来,然后根据浏览器控制台的报错一个个添加白名单。我上次搞这个调了整整两天,咖啡都喝吐了...
另外502可能是其他原因,检查下nginx error log,路径一般是/var/log/nginx/error.log,看有没有语法错误或者权限问题。