403错误本质是系统拒绝访问,需按错误日志→worker用户权限→目录逐级x权限→root/alias路径拼接→SELinux/AppArmor顺序排查:先查/var/log/nginx/error.log中(13: Permission denied),再确认worker用户(如www-data)对/root路径各级目录均有x权限,文件有r权限,区分root追加与alias替换逻辑,并验证SELinux是否拦截。

排查 Nginx 中 root 或 alias 配置因权限不足导致访问失败,关键不是改配置,而是确认“Nginx worker 进程能否以它自己的身份,完整走通从根目录到目标文件的每一步”。403 错误本质是系统拒绝访问,不是路径写错。
先看错误日志,锁定具体失败点
打开 Nginx 错误日志,找带 (13: Permission denied) 的行:
- 运行
sudo tail -n 30 /var/log/nginx/error.log - 看到类似
open() "/var/www/app/index.html" failed (13: Permission denied),说明问题出在该路径的权限或 SELinux 上 - 如果报的是某个目录(如
/var/www/app)被拒绝,说明卡在了“进入目录”这一步,重点查x权限
确认真实 worker 用户,并逐级检查路径权限
Nginx master 可能是 root,但真正读文件的是 worker 进程,它的用户决定了权限边界:
- 查真实用户:
ps aux | grep "nginx: worker"(Ubuntu/Debian 多为www-data,CentOS/RHEL 多为nginx) - 对配置中涉及的每一级目录(比如
root /data/web;就要检查/→/data→/data/web),都执行:ls -ld /data /data/web - 确保每一级目录都有
x权限(即其他用户能“穿过”),例如drwxr-xr-x可以,drwx------不行 - 最终文件需有
r权限,目录需有r+x
区分 root 和 alias 的路径逻辑,避免拼错物理路径
权限再足,路径拼错了也白搭。必须搞清 Nginx 实际去哪找文件:
-
用
nginx -T输出生效配置,搜索对应location块,确认生效的root或alias值 -
root 拼接规则:完整 URI 直接追加。例如
location /api/ { root /opt/app; }+ 请求/api/v1/data.json→ 真实路径是/opt/app/api/v1/data.json -
alias 替换规则:匹配前缀被完全替换。同样请求
/api/v1/data.json,若配置location /api/ { alias /opt/app/; }→ 真实路径是/opt/app/v1/data.json(注意alias值末尾必须有/) - 手动拼出路径后,用
sudo -u www-data ls -l /拼出的完整路径验证是否可列、可读
检查 SELinux 或 AppArmor(尤其 CentOS/RHEL)
即使权限和路径都对,强制访问控制模块也可能拦截:
- 运行
sestatus,若为enforcing,就可能干扰 - 临时测试:
sudo setenforce 0,刷新页面看是否恢复;若恢复,就是 SELinux 导致 - 长期解决:
sudo chcon -Rt httpd_sys_content_t /你的网站目录(对静态资源)或httpd_sys_rw_content_t(需写入时) - 也可用
ls -Z /你的目录查看当前上下文是否匹配


















