403 forbidden是“找到资源但拒绝访问”,需按错误日志→用户权限→配置逻辑→selinux/ apparmor四层排查:先查/var/log/nginx/error.log中“(13: permission denied)”,再确认worker用户与目录属主匹配、各级路径有x权限、文件有r权限,最后排除selinux或apparmor拦截。

403 Forbidden 不是“找不到文件”,而是“找到了但不给看”——Root 指令指向的目录或其任意上级路径,只要有一层缺少执行(x)权限,Nginx 工作进程就进不去,直接返回 403。
确认 Nginx worker 进程的真实运行用户
主进程常以 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 就卡在门外。比如 root /var/www/myapp;,需逐级验证:
- ls -ld /var → 必须对 Nginx 用户有 x
- ls -ld /var/www → 同样要有 x
- ls -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











