讲解 Linux 文件与目录 rwx 含义、运行用户、chmod、chown、setgid、umask、ACL 和 Permission denied 排查。
Linux 文件权限不是“报 Permission denied 就加到 777”。应先确认进程以哪个用户运行、路径上的每一级目录是否可进入、文件由谁拥有,再决定使用用户、用户组、传统权限位或 ACL。权限放得过宽会让 Web 服务、部署账号和其他进程互相越权。

先读懂 rwx 对文件和目录的差别
| 权限 | 普通文件 | 目录 |
|---|---|---|
r | 读取内容 | 列出目录项名称 |
w | 修改内容 | 创建、删除或重命名目录项,通常还需 x |
x | 执行程序或脚本 | 进入目录并访问已知名称 |
删除文件主要由父目录权限决定,不是由文件自身的写权限决定。给网站目录递归增加写权限之前,应明确应用到底需要写上传目录、缓存目录,还是整套代码。
定位实际身份和拒绝位置
id
ps -o user,group,comm -p PROCESS_ID
namei -l /srv/app/storage/example.log
stat -c '%A %a %U:%G %n' /srv/app/storage/example.log
getfacl -p /srv/app/storage/example.log
namei -l 能检查完整路径的每一级目录。服务通过 systemd 运行时,还应查看单元中的 User=、Group=、只读路径和保护选项,不能只用当前 SSH 用户测试。
chmod、chown 和 chgrp 分别解决什么
sudo chown -R appuser:appgroup /srv/app
sudo find /srv/app -type d -exec chmod 0750 {} +
sudo find /srv/app -type f -exec chmod 0640 {} +
chown 改所有者,chgrp 改所属组,chmod 改权限位。递归操作前先列出目标范围;不要对 /、系统目录或不明确的变量执行递归命令。代码目录通常不需要 Web 进程写入,可把可写范围限制在上传、缓存和运行目录。
多人协作目录怎么保持组权限
sudo chgrp -R deploy /srv/www
sudo find /srv/www -type d -exec chmod 2775 {} +
sudo find /srv/www -type f -exec chmod 0664 {} +
目录上的 setgid 位可让新建文件继承目录的组,但新文件最终权限仍受进程 umask 影响。部署用户与 Web 用户共享组时,需同时核对组成员关系、umask 和服务重启后的实际身份。
什么时候使用 ACL
当单个用户需要额外权限、又不适合改变主要用户组时,可使用 ACL。ACL 的 mask 会限制命名用户和组的有效权限,因此设置后必须查看结果。
sudo setfacl -m u:deploy:rwx /srv/app/storage
sudo setfacl -d -m u:deploy:rwx /srv/app/storage
getfacl -p /srv/app/storage
第一条修改当前目录访问 ACL,第二条设置默认 ACL,使之后创建的对象继承规则。默认 ACL 不会自动修复已经存在的文件。跨文件系统迁移时也要确认工具是否保留 ACL 和扩展属性。
Permission denied 仍未解决时
- 检查文件系统是否以只读方式挂载;
- 检查磁盘是否已满或 inode 耗尽;
- 检查 AppArmor、SELinux、systemd 沙箱或容器挂载限制;
- 确认程序访问的真实路径,没有被符号链接或 bind mount 改变;
- 确认 NFS 等远端文件系统的身份映射与服务端权限。
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /srv/app
df -h /srv/app
df -i /srv/app
systemctl show APP.service -p User -p Group -p ProtectSystem -p ReadWritePaths
常见权限方案
| 对象 | 常见目标 | 注意 |
|---|---|---|
| 应用代码 | 部署用户可写,运行用户只读 | 避免 Web 进程修改代码 |
| 上传目录 | 运行用户可写 | 限制脚本执行和公开访问 |
| 私钥 | 仅所有者读取 | 通常使用 0600,目录使用 0700 |
| 共享部署目录 | 共享组协作 | 结合 setgid、umask 或默认 ACL |
操作边界
权限调整应遵循最小授权并保留回退记录。对生产目录执行递归 chown 或 chmod 可能破坏软件包、容器卷和服务隔离;不确定范围时先在副本验证。

