前言

在Linux系统管理中,文件权限是保障系统安全的第一道防线。通常我们使用chmodchown命令基于ugo(用户、组、其他)模型来分配读、写、执行权限。然而,在实际生产环境中,这种传统的权限模型往往无法满足复杂的需求——比如:希望某个特定用户对文件只有读权限,但该用户所在的组却拥有写权限;或者需要对某个目录下的不同子目录设置不同的用户组权限。

这时,ACL(Access Control List,访问控制列表) 就派上了用场。ACL允许我们为单个文件或目录设置更精细的权限规则,为任意指定的用户或组赋予特定的权限,从而突破ugo模型的限制。本文将全面介绍Linux ACL的原理、配置方法及实战案例,帮助你彻底掌握这一强大工具。


一、传统Linux权限的局限性

传统的文件权限只有三组对象:

  • 所有者(u)

  • 所属组(g)

  • 其他人(o)

每组只能设置rwx三种权限。例如,如果希望让用户zhangsan能够读一个文件,而这个文件属于web组,且zhangsan不是文件所有者也不在web组中,传统方式要么将zhangsan加入web组(会导致他获得组的所有权限,可能过高),要么修改文件的“其他人”权限为可读(带来安全风险)。

ACL的出现正是为了解决这种“要么全有,要么全无”的尴尬局面


二、什么是ACL?

ACL(Access Control List)是一个附加的权限列表,它允许我们为单个文件或目录指定比传统ugo更灵活的权限规则。通过ACL,可以为任意指定的用户用户组默认组设置单独的权限。

Linux中主要使用两个命令来管理ACL:

  • getfacl:查看文件或目录的ACL

  • setfacl:设置、修改、删除ACL


三、检查文件系统是否支持ACL

目前主流Linux发行版(如CentOS 7/8、Ubuntu 18.04+)默认在ext4、xfs等文件系统上开启了ACL支持。如果你的系统比较旧或手动编译内核,需要确认一下。

bash

# 查看文件系统挂载选项
mount | grep -E " / (ext4|xfs)"

如果输出中包含acl(如defaults,acl),说明支持ACL。若没有acl,可以临时挂载开启:

bash

mount -o remount,acl /

永久开启需要修改/etc/fstab,在对应挂载项的options中加入acl,然后重新挂载。


四、核心命令:setfacl 与 getfacl

4.1 setfacl 命令语法

基本格式:

bash

setfacl [选项] 规则 文件/目录

常用选项:

  • -m:修改或添加ACL规则

  • -x:删除指定的ACL规则

  • -b:删除所有扩展ACL规则

  • -d:设置默认ACL(仅对目录生效,影响新建子文件/目录)

  • -k:删除默认ACL

  • -R:递归应用ACL到子文件/目录

规则写法:

  • 给用户:u:用户名:权限 或 u:UID:权限

  • 给组:g:组名:权限 或 g:GID:权限

  • 其他:o::权限(很少使用)

  • 掩码:m:权限(限定用户或组的有效权限)

权限可以用rwx字母组合,或数字(如7=读+写+执行,5=读+执行)。

4.2 getfacl 命令

查看ACL信息非常直观:

bash

getfacl 文件或目录

五、实战:设置用户和组的独立权限

环境准备

我们创建两个测试用户tomjerry,一个组team,以及一个测试文件secret.txt

bash

# 创建用户(假设已有则跳过)
sudo useradd tom
sudo useradd jerry
sudo groupadd team

# 创建测试文件
echo "Hello ACL" > secret.txt
sudo chown root:root secret.txt
sudo chmod 640 secret.txt   # 所有者读写,组读,其他无权限

此时文件权限:-rw-r----- 所有者root可读写,组root可读,其他人无任何权限。

5.1 单独给用户tom增加写权限

我们希望用户tom能够写入该文件,而不改变其他用户和组的权限。

bash

sudo setfacl -m u:tom:rw secret.txt

查看ACL:

bash

getfacl secret.txt

输出示例:

text

# file: secret.txt
# owner: root
# group: root
user::rw-
user:tom:rw-          # tom的私有条目
group::r--
mask::rw-
other::---

可以看到多了一条user:tom:rw-。此时tom可以修改文件了,jerry仍然不能访问。
测试:sudo -u tom echo "add by tom" >> secret.txt 成功。

5.2 给组team增加读权限

bash

sudo setfacl -m g:team:r secret.txt
getfacl secret.txt | grep team

输出:group:team:r--

5.3 递归设置ACL到目录

如果要对目录下已有所有文件和子目录都应用ACL,使用-R选项:

bash

sudo setfacl -R -m u:tom:rw /var/www/html/project/

注意递归操作可能大量修改,建议谨慎使用。


六、理解 Mask 权限(掩码)

当你为文件设置了多个用户或组的ACL后,系统会引入一个mask值。mask表示所有命名的用户(非所有者、非其他)和命名的组以及所属组能够获得的最大有效权限

换句话说,即使你给了某个用户rwx权限,但如果mask只有r--,那么该用户的有效权限也只是r--

示例说明

继续上面的secret.txt,观察mask::rw-。假如我们想限制tom只能读不能写,可以修改mask:

bash

sudo setfacl -m m:r secret.txt
getfacl secret.txt

输出:

text

user::rw-
user:tom:rw-        # effective: r--
group::r--          # effective: r--
mask::r--
other::---

有效权限列(effective)表明tom实际只有读权限。所以调整ACL时一定要留意mask的值是否满足你的期望。

通常,当你用setfacl -m添加新规则时,系统会自动更新mask为所有规则权限的并集。你也可手动修改mask来统一限制。


七、默认ACL:让新文件自动继承权限

目录可以设置默认ACL(default ACL),作用于该目录下新建的文件和子目录。对于父目录已有的子文件/子目录不会影响。这在团队协作目录中非常有用。

设置默认ACL

bash

mkdir team_share
# 设置默认ACL:让该目录下新建的文件自动拥有组team的读写权限
sudo setfacl -d -m g:team:rw team_share

查看:

bash

getfacl team_share/

输出会多出类似:

text

default:user::rwx
default:group::r-x
default:group:team:rw-
default:mask::rwx
default:other::---

验证继承效果

team_share中新建一个文件:

bash

touch team_share/test.txt
getfacl team_share/test.txt

发现该文件自动继承了默认ACL中的group:team:rw-规则。注意:文件的默认权限还会受到umask影响,但ACL中的mask和规则最终生效。

删除默认ACL

bash

sudo setfacl -k team_share   # 删除默认ACL

八、删除ACL规则

  • 删除特定用户的ACL:

bash

sudo setfacl -x u:tom secret.txt
  • 删除特定组的ACL:

bash

sudo setfacl -x g:team secret.txt
  • 删除所有扩展ACL(恢复为传统ugo模式):

bash

sudo setfacl -b secret.txt

执行-b后,getfacl将只剩下文件所有者、组和其他三项标准权限。


九、备份与恢复ACL

生产环境中,备份ACL配置可以防止误操作。使用getfaclsetfacl的组合。

备份整个目录的ACL

bash

getfacl -R /path/to/dir > acl_backup.txt

恢复ACL

bash

setfacl --restore=acl_backup.txt

恢复时会自动根据文件路径应用之前保存的ACL,非常方便。


十、注意事项与最佳实践

  1. 文件系统挂载:确保目标文件系统已开启acl支持,否则setfacl会报错“Operation not supported”。

  2. 性能影响:大量使用ACL可能会使ls -lgetfacl等操作变慢(因为需要额外读取扩展属性)。但对于一般服务器负载可忽略。

  3. 递归设置谨慎使用setfacl -R会遍历所有子文件,如果目录层级深、文件多,会造成IO压力,建议在无人操作时段执行。

  4. mask陷阱:修改权限后,注意检查mask值是否符合预期,特别是当你觉得权限“明明设置了但无效”时,大概率是mask在限制。

  5. 复制与移动文件的影响

    • cp默认不会保留ACL,需要加-p参数(preserve)才会保留。

    • mv移动文件在同一文件系统内会保留ACL;跨文件系统则类似cp,需要显式保留。

    • tar打包时需加--acls选项才能备份ACL。

  6. 与SELinux的配合:如果开启了SELinux,注意ACL不会绕过SELinux策略,两者独立生效。


十一、综合实战案例

场景:开发团队目录/data/dev,要求:

  • 目录所有者为root,所属组为devgroup

  • 用户alice需要拥有rwx权限。

  • 用户bob只需要r-x权限。

  • devgroup的成员默认有rwx权限。

  • 在该目录下新建的任何文件,自动赋予devgrouprw权限,alicebob权限自动继承。

步骤分解

  1. 创建目录和组,添加测试用户:

bash

sudo mkdir /data/dev
sudo groupadd devgroup
sudo usermod -aG devgroup alice   # 假设已存在alice
sudo usermod -aG devgroup bob
sudo chown root:devgroup /data/dev
sudo chmod 770 /data/dev   # 传统权限所有者/组全权
  1. 设置针对alice和bob的ACL:

bash

sudo setfacl -m u:alice:rwx /data/dev
sudo setfacl -m u:bob:r-x /data/dev
  1. 设置默认ACL,让后续新文件自动继承:

bash

sudo setfacl -d -m g:devgroup:rw /data/dev
sudo setfacl -d -m u:alice:rwx /data/dev
sudo setfacl -d -m u:bob:r-x /data/dev
sudo setfacl -d -m mask:rwx /data/dev   # 确保mask足够大
  1. 验证:

bash

touch /data/dev/testfile
getfacl /data/dev/testfile

可以看到新文件的ACL中包含了预期的alicebobdevgroup的默认规则。


十二、总结

Linux ACL是系统管理员应对复杂权限需求的一大利器。它让我们能够:

  • 为任意用户/组单独分配权限,摆脱ugo限制。

  • 通过mask统一控制最大有效权限。

  • 对目录设置默认ACL,实现继承机制。

  • 结合getfacl/setfacl轻松管理和备份。

掌握ACL不仅提升了系统的安全性,更使得多人协作环境的权限控制变得清晰和精准。建议在生产环境中优先使用ACL处理精细权限需求,而不是盲目扩大传统权限的范围。

最后,多练习、多用getfacl查看实际效果,理解maskdefault的行为,你就能灵活运用ACL来解决各种权限难题。

本文完全原创,如有不足之处欢迎指正。如果觉得文章对你有帮助,请点赞、收藏、支持一下!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐