Nginx 所有文件都报 403 Forbidden 怎么排查?
Nginx 全站 403 的系统排查:文件与目录权限链、SELinux 上下文、root 指向错误、deny 规则误伤,按命中率排序的检查清单与 FAQ。
全站 403 按命中率从高到低排查:① Nginx 用户对文件/目录无权限;② SELinux 上下文不对;③ root 指向了错误目录;④ deny/allow 规则误伤。 先看 error.log 里的具体原因,能省一半时间。
第 0 步:先看 error.log 说什么
tail -50 /var/log/nginx/error.log
日志会直接告诉你性质:
Permission denied→ 权限问题(走第 1、2 步)directory index of ... is forbidden→ 目录无默认文件(配 index 或 autoindex)access forbidden by rule→ 被自己的 allow/deny 规则拦了
第 1 步:权限链检查(最常见)
# Nginx 以谁运行?
ps aux | grep nginx # 通常是 www-data 或 nginx
# 逐级检查路径
namei -l /var/www/html/index.html
要求:文件可读,路径上每一级目录有 x(进入)权限。常见踩坑:把站点放在 /root/ 或某用户家目录下——父目录 700,Nginx 根本进不去。
修复模板:
sudo chown -R www-data:www-data /var/www/html # 或至少授读权限
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;
第 2 步:SELinux(CentOS/RHEL 高频)
getenforce # Enforcing 就要查
ls -Z /var/www/html/ # 看文件上下文
Web 内容需要 httpd_sys_content_t 上下文。修复:
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"
sudo restorecon -Rv /var/www/html
应急验证:setenforce 0 后 403 消失 → 确诊是 SELinux,改上下文后记得 setenforce 1 恢复。
第 3 步:root 指向对不对
nginx -T | grep -A5 'server_name'
ls -la <root 指向的目录> # 目录真的存在吗?里面有文件吗?
部署脚本改路径、符号链接失效都会让 root 悬空——Nginx 对不存在的目录请求会返回 403(而非 404)。
第 4 步:allow/deny 规则
location / {
allow 192.168.1.0/24;
deny all; # ← 误伤全站就是这么来的
}
nginx -T 全局搜 deny,确认没有过宽的拒绝规则。
修复后重试首页、静态资源和受限路径,核对预期允许与拒绝的请求是否都正确。使用观测云时,可把 HTTP 拨测设为检查关键 URL 的预期状态码;若已采集访问日志,再按 URI 查看 403 分布,区分权限配置错误与正常访问控制。
常见问题(FAQ)
Q:chmod 777 能解决问题吗?
A:能,但等于开门揖盗——任何进程都能改你的网站文件。正确答案是 755/644 + 正确属主,永远不要用 777 掩盖权限问题。
Q:只有 PHP 文件 403,静态文件正常?
A:那不是文件权限问题,而是 PHP-FPM 那一层(看 listen 的 socket/端口权限、security.limit_extensions 配置)。
Q:docker 容器里的 Nginx 也按这套查?
A:思路一样,但权限映射更绕:宿主机目录挂载进容器后,容器内 nginx 用户的 UID 与宿主机文件属主对不上就会 403。挂载时用 -u 或调整宿主机目录属主解决。