用户权限 - Linux系统ACL控制

1. ACL访问控制概述

上一章节我们学习了一般权限、特殊权限,但所有的权限是针对某一类用户设置的, 如果希望对某个指定的用户进行单独的权限控制, 就需要用到文件的访问控制列表ACL。

1.1 ACL基本概念

ACL (Access Control List): 访问控制列表,可以对单个用户或组设置独立的权限。

特点:

  • 设定acl只能是root管理员用户
  • 相关命令: getfacl, setfacl
  • 可以对单个用户、单个组设置独立权限
  • 比传统权限更灵活

1.2 ACL基本使用方式

环境准备

1
2
3
4
5
6
# 环境准备
[root@liyanzhao ~]# cp /etc/passwd /root/passwd

# 文件在没有设定acl, 看到的和传统权限是一样
[root@liyanzhao ~]# ll passwd
-rw-r--r-- 1 root root 0 10-26 13:59 /home/test.txt

使用getfacl查看权限

1
2
3
4
5
6
7
8
# 使用getfacl查看权限
[root@liyanzhao ~]# getfacl passwd
# file: passwd
# owner: root
# group: root
user::rw- # 文件owner权限
group::r-- # 文件拥有组权限
other::r-- # 其他人权限

1.3 设定ACL权限案例

需求:

1
2
3
4
5
6
-rw-r--r-- 1 root root 1380 Feb 27 11:25 passwd

alice 拥有读写权限 rw
bgx 没有任何权限 -
jack 组拥有读权限 r
匿名用户拥有读写权限 rw

步骤1: 建立相关用户

1
2
3
[root@liyanzhao ~]# useradd alice
[root@liyanzhao ~]# useradd bgx
[root@liyanzhao ~]# useradd jack

步骤2: 设置ACL权限

1
2
3
4
5
6
7
8
9
10
11
# 增加用户 alice 权限
[root@liyanzhao ~]# setfacl -m u:alice:rw passwd

# 增加用户 bgx 权限(无权限)
[root@liyanzhao ~]# setfacl -m u:bgx:- passwd

# 增加匿名用户权限
[root@liyanzhao ~]# setfacl -m o::rw passwd

# 增加组权限
[root@liyanzhao ~]# setfacl -m g:jack:r passwd

注意: 如果用户同时属于不同的两个组,并且两个组设定了acl访问控制

  1. 根据acl访问控制优先级进行匹配规则
  2. 如有用户拥有多个组的权限不同的权限,优先使用最高权限(模糊匹配)

1.4 查看ACL权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 查看文件权限(注意+号表示有ACL权限)
[root@liyanzhao ~]# ll passwd
-rw-rw-rw-+ 1 root root 1531 Jan 26 07:52 passwd

# 查看详细ACL权限
[root@liyanzhao ~]# getfacl passwd
# file: passwd
# owner: root
# group: root
user::rw-
user:bgx:---
user:alice:rw-
group::r--
group:jack:r--
mask::rw-
other::rw-

1.5 移除ACL权限

1
2
3
4
5
6
7
8
9
10
11
# 移除jack组的acl权限
[root@liyanzhao ~]# setfacl -x g:jack passwd

# 移除bgx用户的acl权限
[root@liyanzhao ~]# setfacl -x u:bgx passwd

# 移除文件和目录所有acl权限
[root@liyanzhao ~]# setfacl -b passwd

# 删除目录的所有默认acl
[root@liyanzhao ~]# setfacl -k dir

1.6 查看ACL帮助

1
2
3
4
5
6
# EXAMPLES 示例文档
[root@liyanzhao ~]# man setfacl

# 复制 file1 的 ACL 权限给 file2
[root@liyanzhao ~]# setfacl -m u:alice:rw,u:bgx:r,g:jack:rw file1
[root@liyanzhao ~]# getfacl file1 |setfacl --set-file=- file2

1.7 setfacl常用选项

选项 功能
-m 修改ACL权限
-x 删除指定的ACL权限
-b 删除所有ACL权限
-k 删除默认ACL权限
-R 递归设置
-d 设置默认ACL权限

2. ACL高级特性MASK

2.1 MASK说明

MASK: 用于临时降低用户或组的权限,但不包括文件的属主和匿名用户,那么mask最主要的作用是用来决定他们的最高权限。

特点:

  • mask默认不会对匿名用户降低权限
  • 为了便于管理文件的访问控制,建议匿名用户的权限置为空

2.2 MASK使用示例

1
2
# 临时降低用户或组权限
[root@liyanzhao ~]# setfacl -m mask::rw filename

2.3 MASK提示

  1. mask会影响所有用户,但不会影响属主属组以及匿名用户
  2. mask权限决定了用户访问文件时的最高权限
  3. mask用于临时降低用户访问文件的权限
  4. 任何重新设置acl访问控制会清理mask所设定的权限

2.4 MASK示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 设置文件ACL权限
[root@liyanzhao ~]# setfacl -m u:alice:rwx,u:bgx:r-- passwd

# 查看ACL权限
[root@liyanzhao ~]# getfacl passwd
# file: passwd
# owner: root
# group: root
user::rw-
user:alice:rwx # alice有rwx权限
user:bgx:r-- # bgx有r权限
group::r--
mask::rwx # mask为rwx
other::r--

# 设置mask为rw,临时降低权限
[root@liyanzhao ~]# setfacl -m mask::rw passwd

# 再次查看ACL权限
[root@liyanzhao ~]# getfacl passwd
# file: passwd
# owner: root
# group: root
user::rw-
user:alice:rwx #effective:rw- # 实际权限被mask限制为rw
user:bgx:r-- #effective:r-- # 实际权限不变
group::r--
mask::rw- # mask变为rw
other::r--

3. ACL高级特性Default

3.1 Default说明

Default: 继承(默认),可以让新创建的文件或目录自动继承父目录的ACL权限。

应用场景: alice能够对/opt目录以及以后在/opt目录下新建的文件有读、写、执行权限

3.2 Default使用示例

1
2
3
4
5
# 赋予 alice 对/opt 读写执行权限(递归)
[root@liyanzhao ~]# setfacl -R -m u:alice:rwX /opt

# 赋予 alice 对以后在/opt 下新建的文件有读写执行权限(使 alice 的权限继承)
[root@liyanzhao ~]# setfacl -m d:u:alice:rwX /opt

说明:

  • -R: 递归设置现有文件
  • d:: 设置默认ACL权限(继承)
  • X: 表示如果原本有执行权限就保留,如果没有则不添加

3.3 检查对应的权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 检查对应的权限
[root@linux-node1 ~]# getfacl /opt/
getfacl: Removing leading '/' from absolute path names
# file: opt/
# owner: root
# group: bgx
user::rwx
user:alice:rwx
group::rwx
mask::rwx
other::rwx
default:user::rwx
default:user:alice:rwx
default:group::rwx
default:mask::rwx
default:other::rwx

3.4 Default权限说明

default权限项:

  • default:user::rwx - 默认文件所有者权限
  • default:user:alice:rwx - 默认alice用户权限
  • default:group::rwx - 默认组权限
  • default:mask::rwx - 默认mask权限
  • default:other::rwx - 默认其他用户权限

继承规则:

  • 在设置了default权限的目录下新建的文件和目录会自动继承default权限
  • 只对新建的文件和目录生效,不影响已存在的文件

4. ACL访问控制实践案例

4.1 案例1: 复杂权限控制

需求

将新建文件的属性修改tom:admin, 权限默认为644

要求:

  • tom对该文件有所有的权限
  • mary可以读写该文件
  • admin组可以读写执行该文件
  • jack只读该文件
  • 其他人一律不能访问该文件

步骤1: 建立用户和组

1
2
3
4
5
6
7
8
9
# 实验前, 建立几个普通用户
[root@liyanzhao ~]# useradd tom
[root@liyanzhao ~]# useradd bean
[root@liyanzhao ~]# useradd mary
[root@liyanzhao ~]# useradd jack
[root@liyanzhao ~]# useradd sutdent
[root@liyanzhao ~]# groupadd admin
[root@liyanzhao ~]# gpasswd -a mary admin
[root@liyanzhao ~]# gpasswd -a bean admin

步骤2: 检查用户属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 检查用户属性
[root@linux-node1 ~]# id tom
uid=1004(tom) gid=1004(tom) groups=1004(tom)

[root@linux-node1 ~]# id mary
uid=1006(mary) gid=1006(mary) groups=1006(mary),1007(admin)

[root@linux-node1 ~]# id bean
uid=1005(bean) gid=1005(bean) groups=1005(bean),1007(admin)

[root@linux-node1 ~]# id jack
uid=1002(jack) gid=1002(jack) groups=1002(jack)

[root@linux-node1 ~]# id sutdent
uid=1007(sutdent) gid=1008(sutdent) groups=1008(sutdent)

步骤3: 准备相关文件

1
2
3
4
5
6
7
8
9
10
11
12
13
# 准备相关文件
[root@linux-node1 ~]# cp /etc/passwd /root/
[root@linux-node1 ~]# chown tom:admin passwd
[root@linux-node1 ~]# chmod 644 passwd

# 检查设定前的acl列表
[root@linux-node1 ~]# getfacl passwd
# file: passwd
# owner: tom
# group: admin
user::rw-
group::r--
other::r--

步骤4: 设定ACL权限

1
2
# 设定acl权限
[root@linux-node1 ~]# setfacl -m u::rwx,u:mary:rw,u:jack:r,g:admin:rwx,o::- passwd

权限说明:

  • u::rwx - 文件所有者(tom)有rwx权限
  • u:mary:rw - mary用户有rw权限
  • u:jack:r - jack用户有r权限
  • g:admin:rwx - admin组有rwx权限
  • o::- - 其他用户无权限

步骤5: 检查ACL权限

1
2
3
4
5
6
7
8
9
10
11
12
# 检查acl权限
[root@linux-node1 ~]# getfacl passwd
# file: passwd
# owner: tom
# group: admin
user::rwx
user:jack:r--
user:mary:rw-
group::r--
group:admin:rwx
mask::rwx
other::---

ACL控制规则说明

ACL的控制规则是从上往下匹配:

  1. tom: 由于是文件的拥有者,所以直接按照user::rwx指定的权限去操作

  2. mary: 用户从上往下寻找匹配规则,发现user:mary:rw-能够精确匹配mary用户,尽管mary属于admin组,同时admin组有rwx的权限,但是由于mary用户的规则在前面,所有优先生效。

  3. bean: 由于找不到精确匹配的规则,而bean是属于admin组,根据文件的定义,该文件是属于admin组,所以bean的权限是按照group:admin:rwx的权限去操作。

  4. jack: 用户从上往下寻找匹配规则,发现user:jack:r--能够精确匹配jack用户。

  5. student: 用户找不到精确匹配的user定义规则, 也找不到相关组的定义规则,最后属于other。

4.2 案例2: lab acl setup

需求

controller组成员有: student

sodor组成员有: thomas, james

目录: /shares/steamies

文件: /shares/steamies/file

脚本: /shares/steamies/test.sh

要求:

  1. controller属于该目录的所属组, 新建文件必须属于controller组
  2. sodor组的成员对该目录拥有rwx权限
  3. sodor组成员james对该目录及子目录(包括以后新建立的文件)没有任何权限

步骤1: 准备用户

1
2
3
4
5
6
# 准备用户
[root@linux-node1 ~]# groupadd controller
[root@linux-node1 ~]# groupadd sodor
[root@linux-node1 ~]# useradd student -G controller
[root@linux-node1 ~]# useradd thomas -G sodor
[root@linux-node1 ~]# useradd james -G sodor

步骤2: 准备目录

1
2
3
4
5
6
7
# 准备目录
[root@linux-node1 ~]# mkdir /shares/steamies -p
[root@linux-node1 ~]# echo "file" >> /shares/steamies/file
[root@linux-node1 ~]# echo "echo 123" >> /shares/steamies/test.sh
[root@linux-node1 ~]# chmod 755 /shares/steamies/test.sh
[root@linux-node1 ~]# chown -R :controller /shares/steamies/
[root@linux-node1 ~]# chmod g+s /shares/steamies/

步骤3: 设定权限

1
2
# 设定权限(X表示,如果原本有执行权限就保留,如果没有则不添加)
[root@linux-node1 ~]# setfacl -R -m g:sodor:rwX,u:james:- /shares/steamies/

权限说明:

  • g:sodor:rwX - sodor组有rwX权限(X表示保留执行权限)
  • u:james:- - james用户无权限

步骤4: 设定继承规则

1
2
# 设定继承规则
[root@linux-node1 ~]# setfacl -R -m d:g:sodor:rwX,d:u:james:- /shares/steamies/

继承规则说明:

  • d:g:sodor:rwX - 默认sodor组有rwX权限
  • d:u:james:- - 默认james用户无权限

步骤5: 检查权限

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@linux-node1 steamies]# getfacl /shares/steamies/
getfacl: Removing leading '/' from absolute path names
# file: shares/steamies/
# owner: root
# group: controller
# flags: -s-
user::rwx
user:james:---
group::r-x
group:sodor:rwx
mask::rwx
other::r-x
default:user::rwx
default:group::r-x
default:group:sodor:rwx
default:mask::rwx
default:other::r-x

步骤6: 验证测试

测试1: thomas用户访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 切换到thomas用户
su - thomas

# 进入目录
cd /shares/steamies

# 可以查看文件
cat file

# 可以执行脚本
./test.sh

# 可以创建文件
touch thomas_file.txt

# 可以删除文件(自己的文件)
rm -f thomas_file.txt

测试2: james用户访问

1
2
3
4
5
6
7
8
9
10
# 切换到james用户
su - james

# 尝试进入目录(应该失败)
cd /shares/steamies
# 输出: bash: cd: /shares/steamies: Permission denied

# 尝试查看文件(应该失败)
cat /shares/steamies/file
# 输出: cat: /shares/steamies/file: Permission denied

测试3: student用户访问

1
2
3
4
5
6
7
8
9
10
# 切换到student用户
su - student

# 进入目录
cd /shares/steamies

# 创建文件(应该属于controller组)
touch student_file.txt
ll student_file.txt
# 输出: -rw-r--r-- 1 student controller 0 Feb 4 10:00 student_file.txt

4.3 完整实验脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash
# ACL访问控制实验脚本

# 创建组
groupadd controller
groupadd sodor

# 创建用户
useradd student -G controller
useradd thomas -G sodor
useradd james -G sodor

# 创建目录和文件
mkdir -p /shares/steamies
echo "file" >> /shares/steamies/file
echo "echo 123" >> /shares/steamies/test.sh
chmod 755 /shares/steamies/test.sh

# 设置目录属组和SGID
chown -R :controller /shares/steamies/
chmod g+s /shares/steamies/

# 设置ACL权限
setfacl -R -m g:sodor:rwX,u:james:- /shares/steamies/

# 设置默认ACL权限(继承)
setfacl -R -m d:g:sodor:rwX,d:u:james:- /shares/steamies/

# 验证
echo "=== 用户信息 ==="
id student
id thomas
id james

echo "=== 目录权限 ==="
getfacl /shares/steamies/

echo "=== 实验完成 ==="
echo "thomas可以访问目录"
echo "james无法访问目录"
echo "新建文件自动属于controller组"

5. ACL权限匹配规则

5.1 匹配优先级

ACL权限匹配按照以下优先级:

  1. 文件所有者 (user::) - 最高优先级
  2. 指定用户 (user:username:) - 精确匹配
  3. 文件属组 (group::) - 如果用户属于该组
  4. 指定组 (group:groupname:) - 如果用户属于该组
  5. 其他用户 (other::) - 最低优先级

5.2 匹配规则说明

规则类型 匹配方式 优先级
文件所有者 精确匹配 最高
指定用户 精确匹配
文件属组 组匹配
指定组 组匹配
其他用户 默认 最低

5.3 权限冲突处理

  • 用户权限优先于组权限: 如果用户有明确的ACL权限,优先使用用户权限
  • 多个组权限: 如果用户属于多个组,使用最高权限
  • 精确匹配优先: 指定用户/组的权限优先于通用组权限

6. ACL最佳实践

6.1 使用建议

  1. 合理使用ACL: 只在需要精细权限控制时使用ACL
  2. 使用Default继承: 对于需要统一权限的目录,使用default权限
  3. 定期检查ACL: 使用getfacl定期检查ACL权限
  4. 清理无用ACL: 及时清理不再需要的ACL权限
  5. 配合SGID使用: 在共享目录中配合SGID使用,确保文件属组正确

6.2 安全建议

  1. 最小权限原则: 只授予必要的权限
  2. 定期审计: 定期检查ACL权限设置
  3. 文档记录: 记录ACL权限设置的原因和用途
  4. 测试验证: 设置ACL后,使用不同用户测试验证

6.3 常见问题

问题1: ACL权限不生效

1
2
3
4
5
# 检查文件系统是否支持ACL
mount | grep acl

# 如果文件系统不支持,需要重新挂载
mount -o remount,acl /dev/sda1 /mountpoint

问题2: Default权限不继承

1
2
# 确保使用d:前缀设置默认权限
setfacl -m d:u:alice:rwX /directory

问题3: MASK限制权限

1
2
3
4
5
# 检查mask权限
getfacl file | grep mask

# 调整mask权限
setfacl -m mask::rwx file

7. 命令总结

7.1 ACL管理命令

命令 功能 示例
setfacl -m u:user:rw file 设置用户ACL权限
setfacl -m g:group:rx file 设置组ACL权限
setfacl -m o::rw file 设置其他用户ACL权限
setfacl -x u:user file 删除用户ACL权限
setfacl -b file 删除所有ACL权限
setfacl -R -m ... dir 递归设置ACL权限
setfacl -m d:u:user:rwX dir 设置默认ACL权限
getfacl file 查看ACL权限

7.2 ACL权限格式

格式 说明 示例
u:username:rwx 指定用户权限 u:alice:rw
g:groupname:rwx 指定组权限 g:admin:rwx
u::rwx 文件所有者权限 u::rwx
g::rwx 文件属组权限 g::r--
o::rwx 其他用户权限 o::---
m::rwx mask权限 m::rw-
d:u:username:rwx 默认用户权限 d:u:alice:rwX