403 forbidden 错误本质是“找到资源但拒绝访问”,日志中“(13: permission denied)”明确指向权限链断裂;需逐级检查nginx工作用户对路径各层的x权限及文件r权限,并排除selinux/apparmor拦截。

403 Forbidden 不是“找不到文件”,而是“找到了但不给看”。当 Nginx 日志里出现 (13: Permission denied),基本可锁定为权限链断裂——从根目录到目标文件的任一环节,Nginx 工作用户缺了执行(x)或读取(r)权限。
看错误日志,确认是不是权限问题
先打开 Nginx 错误日志,定位真实线索:
- 默认路径:/var/log/nginx/error.log
- 重点找含 "403" 或 "(13: Permission denied)" 的行,例如:
open() "/var/www/myapp/index.html" failed (13: Permission denied) - 如果看到这类提示,说明不是配置写错、也不是文件不存在,就是权限卡住了
查 Nginx 真实运行用户,别信配置文件里的注释
Nginx 主进程常以 root 启动,但真正干活的是 worker 进程,它的用户才决定权限边界:
- 运行命令查实际用户:
ps aux | grep "nginx: worker process",看 USER 列(常见为www-data、nginx或nobody) - 别只看
nginx.conf里的user行——它可能被注释、被 include 覆盖,或根本没生效 - 用该用户身份模拟访问:
sudo -u www-data ls -l /your/root/path/index.html,报错即说明权限不通
逐级验证路径权限,x 权限一个都不能少
Linux 中“进入目录”必须有 x 权限。缺任意一级,Nginx 就进不去,直接 403:
- 假设
root /var/www/myapp;,需逐级检查:ls -ld /var→ 必须对 Nginx 用户有 xls -ld /var/www→ 同样要有 xls -ld /var/www/myapp→ 目录本身也要有 x(否则连 index.html 都列不出来)ls -l /var/www/myapp/index.html→ 文件需有 r 权限 - 快捷命令:
namei -l /var/www/myapp/index.html,会清晰列出每级路径的权限、属主、属组
修复权限与归属,拒绝 chmod 777
按最小权限原则调整,兼顾安全与可用:
- 把网站目录属组设为 Nginx 用户所在组:
sudo chgrp -R www-data /var/www/myapp - 给目录加
r-x(755):sudo chmod -R 755 /var/www/myapp - 给静态文件加
r--(644):sudo chmod 644 /var/www/myapp/*.html - 若目录原属 root 且无法改组,可改属主:
sudo chown -R www-data:www-data /var/www/myapp
排除 SELinux 或 AppArmor 的静默拦截
即使前面全对,CentOS/RHEL 上 SELinux、Ubuntu 上 AppArmor 仍可能拦住访问:
- 查状态:
sestatus(SELinux)或aa-status | grep nginx(AppArmor) - 临时测试:
sudo setenforce 0(SELinux)或sudo systemctl stop apparmor(AppArmor),再刷新页面 - 若恢复,说明是安全模块导致——永久解决请打正确上下文,如:
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/myapp(/.*)?",再sudo restorecon -Rv /var/www/myapp











