在 Linux 服务器中,权限冲突问是一个非常常见的问题。
例如:
- Cron 定时任务:root 用户执行
- PHP(Nginx + PHP-FPM):www-data 或 www 用户执行
- Apache:apache 用户执行
- Tomcat:tomcat 用户执行
两个不同用户需要共同读写同一目录。
很多人第一反应就是:
1chmod -R 777 data/ 2
虽然能解决问题,但非常不安全。
Linux 提供了更好的方案——ACL(Access Control List)。
一、为什么传统权限解决不了?
Linux 普通权限只有三类:
1Owner(所有者) 2 3Group(所属组) 4 5Others(其他人) 6
例如
1-rw-r--r-- 2
表示
1Owner rw- 2Group r-- 3Other r-- 4
假设:
1root (定时任务) 2 3www (PHP) 4 5
目录
1/data/report/ 2
权限
1drwxr-x--- 2root root 3
那么:
root 可以
1读 2写 3删除 4创建 5
而 www:
1没有权限 2
如果改成
1775 2
那么要求:
1www 必须属于 root 组 2
现实中通常不是。
如果改成
1777 2
任何用户都能写。
安全性很差。
二、ACL 是什么?
ACL(Access Control List)
就是:
给某一个指定用户,单独赋予权限。
例如:
1目录属于 root 2 3但是允许 www 写 4
无需:
1修改 owner 2 3修改 group 4 5修改 777 6
ACL 就像:
1普通权限: 2 3Owner 4Group 5Other 6 7ACL: 8 9Owner 10Group 11Other 12+ 13www 14+ 15mysql 16+ 17backup 18+ 19... 20
因此更加灵活。
三、查看系统是否支持 ACL
Ubuntu:
1which setfacl 2 3which getfacl 4
如果没有:
Ubuntu
1sudo apt install acl 2
CentOS
1yum install acl 2
查看文件系统
1mount 2
例如:
1/dev/sda1 on / 2type ext4 3
现在:
Linux 大多数:
1ext4 2 3xfs 4 5btrfs 6
默认都支持 ACL。
四、ACL 常用命令
查看 ACL
1getfacl 文件 2
例如
1getfacl report 2
输出
1# file: report 2# owner: root 3# group: root 4 5user::rwx 6user:www:rwx 7 8group::r-x 9 10mask::rwx 11 12other::--- 13
说明:
1www 2 3拥有 rwx 4
设置 ACL
给 www 权限
1setfacl -m u:www:rwx report 2
解释:
1-m 2 3modify 4 5u 6 7user 8 9www 10 11用户名 12 13rwx 14 15权限 16
再查看
1getfacl report 2
会看到:
1user:www:rwx 2
说明成功。
五、解决 root 与 www 冲突
假设:
1/var/www/project/storage 2
root 定时写:
1cron 2 3shell 4
PHP:
1www 2
需要共同写。
设置:
1sudo setfacl -R -m u:www:rwx /var/www/project/storage 2
以后:
1root 2 3www 4 5都可以写 6
无需:
1777 2
六、递归设置
整个目录
1setfacl -R -m u:www:rwx data 2
查看
1getfacl data 2
如果目录很多:
1全部都会拥有 ACL 2
七、新建文件为什么又没权限?
很多人做到这里发现:
已有文件可以。
但是:
1root 新建文件 2 3www 又打不开。 4
为什么?
因为:
ACL 默认不会继承。
例如
1data/ 2 3
里面:
1旧文件 2 3有 ACL 4
后来 root:
1touch test.txt 2
结果:
1test.txt 2 3没有 ACL 4
这也是很多人踩坑的地方。
八、默认 ACL(Default ACL)
Linux 可以设置:
1以后新建文件 2 3自动继承 ACL 4
命令:
1setfacl -R -d -m u:www:rwx data 2
这里:
1-d 2 3default 4
查看:
1getfacl data 2
会看到:
1default:user:www:rwx 2
以后:
1mkdir 2 3touch 4 5cp 6
都会自动继承。
例如:
root
1touch data/a.txt 2
查看:
1getfacl data/a.txt 2
里面:
1user:www:rwx 2
已经自动存在。
九、同时给多个用户
例如:
1root 2 3www 4 5backup 6
都需要。
1setfacl -m u:www:rwx data 2
再:
1setfacl -m u:backup:r-x data 2
查看:
1user:www:rwx 2 3user:backup:r-x 4
互不影响。
十、给整个用户组
例如:
1group:www 2
1setfacl -m g:www:rwx data 2
查看:
1group:www:rwx 2
十一、删除 ACL
删除某用户
1setfacl -x u:www data 2
删除组
1setfacl -x g:www data 2
删除全部 ACL
1setfacl -b data 2
十二、mask 是什么?
查看 ACL:
1user::rwx 2user:www:rwx 3 4group::rwx 5 6mask::r-x 7 8other::--- 9
很多人疑惑:
1www 是 rwx 2 3为什么不能写? 4
因为:
1mask 2 3限制了 ACL 最大权限。 4
真正权限:
1user:www:rwx 2 3AND 4 5mask:r-x 6 7= 8 9r-x 10
所以:
1没有写权限。 2
修改:
1setfacl -m m:rwx data 2
或者:
1setfacl -m mask:rwx data 2
十三、实际生产环境案例
假设目录:
1/var/www/project/storage 2
需求:
- root(cron)可以读写
- www(PHP)可以读写
- 其他用户不能访问
- 新建文件自动继承权限
推荐方案:
1# 给 www 设置 ACL 2sudo setfacl -R -m u:www:rwx /var/www/project/storage 3 4# 设置默认 ACL,确保新文件继承 5sudo setfacl -R -d -m u:www:rwx /var/www/project/storage 6 7# 如有需要,调整 ACL mask 8sudo setfacl -R -m m:rwx /var/www/project/storage 9sudo setfacl -R -d -m m:rwx /var/www/project/storage 10
然后验证:
1getfacl /var/www/project/storage 2
应看到类似输出:
1user::rwx 2user:www:rwx 3group::r-x 4mask::rwx 5other::--- 6default:user::rwx 7default:user:www:rwx 8default:group::r-x 9default:mask::rwx 10default:other::--- 11
这样,root 的 Cron 任务和 **Web 服务(www 用户)**即可安全地共享该目录,而无需将权限放宽到 777。
十四、ACL 与 chmod/chown 对比
| 方案 | 灵活性 | 安全性 | 是否推荐 |
|---|---|---|---|
| chmod 777 | 很低 | ❌ 极低 | 不推荐 |
| chown www:www | 一般 | 中等 | 仅适用于 Web 独占目录 |
| chgrp + 775 | 较高 | 较高 | 同组协作时推荐 |
| ACL (setfacl) | 最高 | 高 | ⭐ 多用户协作场景首选 |