Nginx 所有文件都报 403 Forbidden 怎么排查?

Nginx 全站 403 的系统排查:文件与目录权限链、SELinux 上下文、root 指向错误、deny 规则误伤,按命中率排序的检查清单与 FAQ。

最佳实践
Nginx 所有文件都报 403 Forbidden 怎么排查?封面

全站 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,确认没有过宽的拒绝规则。

观测云对照

全站 403 是生产事故级故障,不该靠用户反馈发现。观测云的站点可用性监测定期探测关键 URL,返回码异常立刻告警;Nginx 访问日志接入后,403 的来源 IP、URI 分布实时可查,配合状态码异常告警,故障从"被动等投诉"变成"分钟级主动发现"。

常见问题(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 或调整宿主机目录属主解决。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台