Linux setfacl命令

setfacl 是 Linux 系统中用于设置文件访问控制列表(ACL)的命令,它允许为文件或目录设置更细粒度的权限控制,超越了传统的 owner/group/others 权限模型。

命令简介

setfacl 用于设置文件或目录的访问控制列表(Access Control List,ACL)。ACL 是对传统 Linux 文件权限的扩展,允许为特定的用户或组设置单独的权限。

主要功能包括:

  • 为特定用户设置文件访问权限
  • 为特定组设置文件访问权限
  • 设置默认ACL(影响新创建的文件)
  • 修改和删除ACL条目
  • 备份和恢复ACL设置
使用setfacl前,请确保文件系统支持ACL(如ext3、ext4、XFS等),并且已挂载时启用了ACL选项(通常使用acl挂载选项)。

命令语法

setfacl [选项] [规则] 文件...
setfacl [选项] -b|-x|-X 文件...

ACL规则格式

ACL规则的基本格式:

[d[efault]:] [u[ser]:]用户ID[:权限]
[d[efault]:] g[roup]:组ID[:权限]
[d[efault]:] m[ask][:] [:权限]
[d[efault]:] o[ther][:] [:权限]

权限表示:

  • r - 读取权限
  • w - 写入权限
  • x - 执行权限
  • - - 无权限

常用选项

选项 说明
-m, --modify=acl 修改文件或目录的ACL条目
-x, --remove=acl 从文件或目录删除ACL条目
-b, --remove-all 删除所有扩展ACL条目
-k, --remove-default 删除默认ACL
--set=acl 设置ACL,替换现有ACL
--set-file=file 从文件读取ACL设置
-d, --default 应用到默认ACL
-R, --recursive 递归应用到子目录和文件
-n, --no-mask 不重新计算有效权限掩码
--mask 重新计算有效权限掩码
-v, --version 显示版本信息
-h, --help 显示帮助信息

命令示例

1. 查看ACL设置

使用 getfacl 命令查看文件或目录的ACL设置:

# 查看文件ACL
getfacl file.txt

# 查看目录ACL
getfacl /var/www/

# 查看并显示tab字符(方便脚本处理)
getfacl -t /shared/data

2. 为用户设置ACL

为特定用户设置文件或目录的访问权限:

# 为用户alice添加读写权限
setfacl -m u:alice:rw file.txt

# 为用户ID 1001添加读写执行权限
setfacl -m u:1001:rwx script.sh

# 为多个用户设置权限
setfacl -m u:alice:rw,u:bob:r file.txt

# 为用户设置目录权限(递归)
setfacl -R -m u:alice:rwx /var/www/

3. 为组设置ACL

为特定组设置文件或目录的访问权限:

# 为developers组添加读写权限
setfacl -m g:developers:rw file.txt

# 为组ID 1001添加读取权限
setfacl -m g:1001:r document.pdf

# 为多个组设置权限
setfacl -m g:developers:rw,g:testers:r file.txt

4. 设置默认ACL

为目录设置默认ACL,影响该目录下新建的文件和子目录:

# 为目录设置默认ACL
setfacl -d -m u:alice:rwx /shared/data

# 为目录及其现有内容设置ACL
setfacl -R -d -m u:alice:rwx /shared/data

# 同时设置访问ACL和默认ACL
setfacl -m u:alice:rwx -d -m u:alice:rwx /shared/data

# 查看目录的默认ACL
getfacl -d /shared/data

5. 删除ACL条目

删除特定的ACL条目:

# 删除用户alice的ACL条目
setfacl -x u:alice file.txt

# 删除developers组的ACL条目
setfacl -x g:developers file.txt

# 删除默认ACL中的用户条目
setfacl -d -x u:alice /shared/data

# 删除所有扩展ACL条目
setfacl -b file.txt

# 删除默认ACL(保留基本ACL)
setfacl -k /shared/data

6. 设置完整的ACL

替换文件的整个ACL设置:

# 设置完整的ACL(替换所有现有ACL)
setfacl --set u::rw,u:alice:rw,g::r,o::- file.txt

# 从文件读取ACL设置
getfacl file1.txt > acl_backup.txt
setfacl --set-file=acl_backup.txt file2.txt

# 设置目录及其子目录的ACL
setfacl -R --set u::rwx,u:alice:rwx,g::rx,o::- /shared/

7. 权限掩码(Mask)操作

权限掩码定义了ACL条目的最大有效权限:

# 查看权限掩码
getfacl file.txt | grep mask

# 设置权限掩码
setfacl -m m::rx file.txt

# 不重新计算掩码
setfacl -n -m u:alice:rwx file.txt

# 强制重新计算掩码
setfacl --mask -m u:alice:rwx file.txt

实用场景示例

场景1:共享目录权限管理
# 创建共享目录
mkdir /shared
chmod 770 /shared

# 设置目录所有者
chown root:developers /shared

# 为多个用户和组设置ACL
setfacl -m u:alice:rwx,u:bob:rwx,g:developers:rwx,g:testers:rx /shared

# 设置默认ACL(新文件继承)
setfacl -d -m u:alice:rwx,u:bob:rwx,g:developers:rwx,g:testers:rx /shared

# 验证设置
getfacl /shared
场景2:Web服务器目录权限
# Web目录设置
chown -R www-data:www-data /var/www/html
chmod -R 755 /var/www/html

# 允许开发者访问
setfacl -R -m u:developer:rwx /var/www/html

# 设置默认ACL
setfacl -R -d -m u:developer:rwx /var/www/html

# 特定文件只允许www-data写入
setfacl -m u:www-data:rw,g:www-data:r,o::r /var/www/html/config.php
场景3:备份和恢复ACL
# 备份目录ACL
getfacl -R /shared > /backup/shared_acls.txt

# 恢复目录ACL
setfacl --restore=/backup/shared_acls.txt

# 备份多个目录
find /data -exec getfacl {} \; > /backup/all_acls.txt

ACL权限计算规则

ACL权限检查顺序:

  1. 如果进程的有效用户ID与文件的用户所有者匹配,使用用户所有者权限
  2. 否则,如果进程的有效用户ID与ACL中的用户条目匹配,使用该条目权限
  3. 否则,如果进程的有效组ID或补充组ID与文件的组所有者匹配,使用组所有者权限
  4. 否则,如果进程的有效组ID或补充组ID与ACL中的组条目匹配,使用该条目权限
  5. 否则,使用其他权限

注意:权限掩码(mask)会限制除用户所有者和其他人之外的所有条目的有效权限。

常见问题

可能的原因:

  1. 文件系统不支持ACL(需要ext3/ext4/XFS等支持ACL的文件系统)
  2. 挂载时未启用ACL选项(需要acl挂载选项)
  3. 权限掩码(mask)限制了有效权限
  4. 传统权限与ACL权限冲突

检查方法:

# 检查文件系统是否支持ACL
tune2fs -l /dev/sda1 | grep acl

# 检查挂载选项
mount | grep /data

# 重新挂载启用ACL
mount -o remount,acl /data

有几种方法可以检查文件是否有ACL设置:

# 使用ls命令(+号表示有扩展ACL)
ls -l file.txt
# -rw-rw-r--+ 表示有ACL设置

# 使用getfacl命令
getfacl file.txt

# 检查ACL标志位
lsattr file.txt
# 如果显示"e+"表示有扩展属性

传统权限和ACL权限的关系:

  • 传统权限显示为 rwxrwxrwx(用户/组/其他)
  • 当设置ACL时,传统权限可能会被修改以反映ACL中的条目
  • 使用chmod修改传统权限时,可能会影响ACL的掩码
  • getfacl显示的结果中,#后面的是传统权限

示例:

# 查看传统权限和ACL的关系
$ getfacl file.txt
# file: file.txt
# owner: root
# group: root
user::rw-
user:alice:rwx        #effective:rw-
group::r--            #effective:r--
mask::rw-
other::r--

重要注意事项

  • 使用-R递归选项时要小心,可能会影响大量文件
  • ACL备份文件应妥善保管,包含敏感权限信息
  • 默认ACL只对目录有效,文件不能有默认ACL
  • 复制文件时(如cp命令),ACL可能不会被保留,使用cp -pcp --preserve=all
  • 归档工具(如tar)可能默认不保存ACL,使用tar --acls选项
  • NFS共享时,ACL支持取决于NFS版本和服务端配置

相关命令

  • getfacl - 获取文件或目录的ACL
  • chmod - 修改文件传统权限
  • chown - 修改文件所有者和组
  • lsattr - 查看文件扩展属性
  • chattr - 修改文件扩展属性
  • umask - 设置默认权限掩码