ACL访问控制列表
ACL访问控制列表
ACL:Access Control List,实现灵活的权限管理
除了文件的所有者,所属组和其它人,可以对更多的用户设置权限
CentOS7默认创建的xfs和ext4文件系统具有ACL功能
CentOS7之前版本,默认手工创建的ext4文件系统无ACL功能,需手动增加
tune2fs –o acl /dev/sdb1
mount –o acl /dev/sdb1 /mnt/test
ACL生效顺序:所有者,自定义用户,自定义组,其他人
ACL文件上的group权限是mask 值(自定义用户,自定义组,拥有组的最大权限,全局控制最大权限),而非传统的组权限
getfacl可看到特殊权限:flags
通过ACL赋予目录默认x权限,目录内文件也不会继承x权限
mask只影响除所有者和other的之外的人和组的最大权限
Mask需要与用户的权限进行逻辑与运算后,才能变成有效的权限(Effective Permission)
用户或组的设置必须存在于mask权限设定范围内才会生效setfacl-m mask::rxfile
1、setfacl(Set file access control lists)
直译过来是设置文件访问控制列表 ,其主要功能是用于设置文件ACL策略规则。FACL即文件访问控制列表策略,通过该技术可以更加精准的控制权限的分配。
这样子说可能有些难理解它真正的含义是什么,可以举一个例子,例如仅允许某个用户访问指定目录,或仅有某个用户才具有写入权限,把权限约束在一个极小的范围内,系统也就更加安全。
语法格式
setfacl的语法格式是:setfacl 【参数】【文件/目录】
setfacl [-bkndRLPvh] [{-m|-x} acl_spec] [{-M|-X} acl_file] file ...
setfacl --restore=file
基本参数
命令的常用参数是以下这些,一起来看看
-b 删除所有扩展访问控制列表,保留基本的信息
-k 移除默认访问控制列表
-d 应用到默认访问控制列表的操作,针对目录使用(目录内可继承的默认权限)
-P 跳过所有符号链接,包括符号链接文件
-R 递归操作子目录
-m 更改文件访问控制列表
-x 根据文件中访问控制列表移除条目
-X 从文件读取访问控制列表条目并删除
-M 从文件读取访问控制列表条目更改
--restore=file 从文件恢复备份的ACL规则,通过这种机制可以恢复整个目录树的ACL规则
--test 测试模式,不会改变任何文件的ACL规则,操作后的ACL规格将被列出
参考实例
-
对目录进行FACL策略规则设置
可以看到加上-d参数后,显示的规则多了一些目录默认规则信息[root@localhost ~]# setfacl -d -m u:test:rwx namedir/ [root@localhost ~]# getfacl namedir/ # file: namedir/ # owner: root # group: root user::rwx user:root:rwx user:test1:rwx group::r-x mask::rwx other::r-x default:user::rwx default:user:root:rwx default:group::r-x default:mask::rwx default:other::r-x
-
获取文件的ACL信息
获取文件的ACL信息会需要用到getfacl这个命令,一起来看下默认显示的ACL是咋样的[root@localhost ~]# touch a.txt [root@localhost ~]# getfacl a.txt # file: a.txt # owner: root # group: root user::rw- group::r-- other::r--
3.更改文件的ACL规则
更改文件的ACL规则会需要用到-m的参数,设置用户test的权限为读写执行,并且设置用户test1的权限为000权限。
[root@localhost ~]# setfacl -m u:test:rwx a.txt
[root@localhost ~]# setfacl -m u:test1:- a.txt
[root@localhost ~]# getfacl a.txt
# file: a.txt
# owner: root
# group: root
user::rw-
user:root:rwx
user:test1:---
group::r--
mask::rwx
other::r--
若是要修改所有组对这个文件的访问权限,可以将u改成g,一起来试试
[root@localhost ~]# groupadd grp
[root@localhost ~]# usermod -G grp test1
[root@localhost ~]# useradd -G grp test2
[root@localhost ~]# setfacl -m g:grp:- a.txt
[root@localhost ~]# getfacl a.txt
# file: a.txt
# owner: root
# group: root
user::rw-
group::r--
group:grp:---
mask::r--
other::r--
[root@localhost ~]# su - test1
上一次登录:日 3月 5 16:39:21 CST 2023pts/1 上
[test1@localhost ~]$ cat /root/a.txt
cat: /root/a.txt: 权限不够
4.去掉所有的ACL规则
直接使用-b参数即可
[root@localhost ~]# setfacl -b a.txt
[root@localhost ~]# getfacl a.txt
# file: a.txt
# owner: root
# group: root
user::rw-
group::r--
other::r--
5.移除一条ACL规则
-x参数是可以直接移除一个规则的,若在工作中,只想移除一个ACL规则,可以使用这个参数了,因为-b相当于是全部删掉,只保留原来的ACL信息。
这里的话移除用户test2的规则
[root@localhost ~]# setfacl -Rm u:test1:rwx namedir
[root@localhost ~]# setfacl -Rm u:test2:rwx namedir
[root@localhost ~]# getfacl namedir
# file: namedir
# owner: root
# group: root
user::rwx
user:root:rwx
user:test1:rwx
user:test2:rwx
group::r-x
mask::rwx
other::r-x
[root@localhost ~]# setfacl -x u:test2 namedir #执行这一条命令
[root@localhost ~]# getfacl namedir/
# file: namedir/
# owner: root
# group: root
user::rwx
user:root:rwx
user:test1:rwx
#原本这里有一行test2的规则,现在已经移除了
group::r-x
mask::rwx
other::r-x
小案例
老师使用 root 用户,并作为 /project 的所有者,对 project 目录拥有 rwx 权限;
新建 tgroup 群组,并作为 project 目录的所属组,包含本班所有的班级学员(假定只有 zhangsan 和 lisi),拥有对 project 的 rwx 权限;
将其他用户访问 project 目录的权限设定为 0(也就是 ---)。
对于试听学员 st 来说,我们对其设定 ACL 权限,令该用户对 project 拥有 rx 权限。
具体的设置命令如下:
[root@localhost ~]# useradd zhangsan
[root@localhost ~]# useradd lisi
[root@localhost ~]# useradd st
[root@localhost ~]# groupadd tgroup <-- 添加需要试验的用户和用户组,省略设定密码的过程
[root@localhost ~]# mkdir /project <-- 建立需要分配权限的目录
[root@localhost ~]# chown root:tgroup /project <-- 改变/project目录的所有者和所属组
[root@localhost ~]# chmod 770 /project <-- 指定/project目录的权限
[root@localhost ~]# ll -d /project
drwxrwx---. 2 root tgroup 4096 Apr 16 12:55 /project
#这时st学员来试听了,如何给她分配权限
[root@localhost ~]# setfacl -m u:st:rx /project
#给用户st赋予r-x权限,使用"u:用户名:权限" 格式
[root@localhost /]# cd /
[root@localhost /]# ll -d /project
drwxrwx---+ 2 root tgroup 4096 Apr 16 12:55 /project
#如果查询时会发现,在权限位后面多了一个"+",表示此目录拥有ACL权限
[root@localhost /]# getfacl project
#查看/prpject目录的ACL权限
#file:project <--文件名
#owner:root <--文件的所有者
#group:tgroup <--文件的所属组
user::rwx <--用户名栏是空的,说明是所有者的权限
user:st:r-x <--用户st的权限
group::rwx <--组名栏是空的,说明是所属组的权限
mask::rwx <--mask权限
other::--- <--其他人的权限
可以看到,通过设定 ACL 权限,我们可以单独给 st 用户分配 r-x 权限,而无需给 st 用户设定任何身份。
同样的道理,也可以给用户组设定 ACL 权限,例如:
[root@localhost /]# groupadd tgroup2
#添加新群组
[root@localhost /]# setfacl -m g:tgroup2:rwx project
#为组tgroup2纷配ACL权限
[root@localhost /]# ll -d project
drwxrwx---+ 2 root tgroup 4096 1月19 04:21 project
#属组并没有更改
[root@localhost /]# getfacl project
#file: project
#owner: root
#group: tgroup
user::rwx
user:st:r-x
group::rwx
group:tgroup2:rwx <-用户组tgroup2拥有了rwx权限
mask::rwx
other::---
setfacl -d:设定默认 ACL 权限
既然已经对 project 目录设定了 ACL 权限,那么,如果在这个目录中新建一些子文件和子目录,这些文件是否会继承父目录的 ACL 权限呢?执行以下命令进行验证:
[root@localhost /]# cd project
[root@localhost project]# touch abc
[root@localhost project]# mkdir d1
#在/project目录中新建了abc文件和d1目录
[root@localhost project]#ll
总用量4
-rw-r--r-- 1 root root 01月19 05:20 abc
drwxr-xr-x 2 root root 4096 1月19 05:20 d1
可以看到,这两个新建立的文件权限位后面并没有 "+",表示它们没有继承 ACL 权限。这说明,后建立的子文件或子目录,并不会继承父目录的 ACL 权限。
当然,我们可以手工给这两个文件分配 ACL 权限,但是如果在目录中再新建文件,都要手工指定,则显得过于麻烦。这时就需要用到默认 ACL 权限。
默认 ACL 权限的作用是,如果给父目录设定了默认 ACL 权限,那么父目录中所有新建的子文件都会继承父目录的 ACL 权限。需要注意的是,默认 ACL 权限只对目录生效。
例如,给 project 文件设定 st 用户访问 rx 的默认 ACL 权限,可执行如下指令:
[root@localhost /]# setfacl -m d:u:st:rx project
[root@localhost project]# getfacl project
# file: project
# owner: root
# group: tgroup
user:: rwx
user:st:r-x
group::rwx
group:tgroup2:rwx
mask::rwx
other::---
default:user::rwx <--多出了default字段
default:user:st:r-x
default:group::rwx
default:mask::rwx
default:other::---
[root@localhost /]# cd project
[root@localhost project]# touch bcd
[root@localhost project]# mkdir d2
#新建子文件和子目录
[root@localhost project]# ll 总用量8
-rw-r--r-- 1 root root 01月19 05:20 abc
-rw-rw----+ 1 root root 01月19 05:33 bcd
drwxr-xr-x 2 root root 4096 1月19 05:20 d1
drwxrwx---+ 2 root root 4096 1月19 05:33 d2
#新建的bcd和d2已经继承了父目录的ACL权限
大家发现了吗?原先的 abc 和 d1 还是没有 ACL 权限,因为默认 ACL 权限是针对新建立的文件生效的。
对目录设定的默认 ACL 权限,可直接使用 setfacl -k 命令删除。例如:
[root@localhost /]# setfacl -k project
通过此命令,即可删除 project 目录的默认 ACL 权限,读者可自行通过 getfacl 命令查看。
setfacl -R:设定递归 ACL 权限
递归 ACL 权限指的是父目录在设定 ACL 权限时,所有的子文件和子目录也会拥有相同的 ACL 权限。
例如,给 project 目录设定 st 用户访问权限为 rx 的递归 ACL 权限,执行命令如下:
[root@localhost project]# setfacl -m u:st:rx -R project
[root@localhost project]# ll
总用量 8
-rw-r-xr--+ 1 root root 01月19 05:20 abc
-rw-rwx--+ 1 root root 01月19 05:33 bcd
drwxr-xr-x+ 2 root root 4096 1月19 05:20 d1
drwxrwx---+ 2 root root 4096 1月19 05:33 d2
#abc和d1也拥有了ACL权限
注意,默认 ACL 权限指的是针对父目录中后续建立的文件和目录会继承父目录的 ACL 权限;递归 ACL 权限指的是针对父目录中已经存在的所有子文件和子目录会继承父目录的 ACL 权限。
setfacl -x:删除指定的 ACL 权限
使用 setfacl -x 命令,可以删除指定的 ACL 权限,例如,删除前面建立的 st 用户对 project 目录的 ACL 权限,执行命令如下:
[root@localhost /]# setfacl -x u:st project
#删除指定用户和用户组的ACL权限
[root@localhost /]# getfacl project
# file:project
# owner: root
# group: tgroup
user::rwx
group::rwx
group:tgroup2:rwx
mask::rwx
other::---
#st用户的权限已被删除
setfacl -b:删除指定文件的所有 ACL 权限
此命令可删除所有与指定文件或目录相关的 ACL 权限。例如,现在我们删除一切与 project 目录相关的 ACL 权限,执行命令如下:
[root@localhost /]# setfacl -b project
#会删除文件的所有ACL权限
[root@localhost /]# getfacl project
#file: project
#owner: root
# group: tgroup
user::rwx
group::rwx
other::---
#所有ACL权限已被删除
前面,我们已经学习如何使用 setfacl 和 getfacl 为用户或群组添加针对某目录或文件的 ACL 权限。例如:
[root@localhost /]# getfacl project
#file: project <-文件名
#owner: root <-文件的属主
#group: tgroup <-文件的属组
user::rwx <-用户名栏是空的,说明是所有者的权限
group::rwx <-组名栏是空的,说明是所属组的权限
other::--- <-其他人的权限
[root@localhost ~]# setfacl -m u:st:rx /project
#给用户st设定针对project目录的rx权限
[root@localhost /]# getfacl project
#file: project
#owner: root
#group: tgroup
user::rwx
user:st:r-x <-用户 st 的权限
group::rwx
mask::rwx <-mask 权限
other::---
对比添加 ACL 权限前后 getfacl 命令的输出信息,后者多了 2 行信息,一行是我们对 st 用户设定的 r-x 权限,另一行就是 mask 权限。
mask 权限,指的是用户或群组能拥有的最大 ACL 权限,也就是说,给用户或群组设定的 ACL 权限不能超过 mask 规定的权限范围,超出部分做无效处理。
举个例子,如果像上面命令那样,给 st 用户赋予访问 project 目录的 r-x 权限,此时并不能说明 st 用户就拥有了对该目录的读和访问权限,还需要和 mask 权限对比,r-x 确实是在 rwx 范围内,这时才能说 st 用户拥有 r-x 权限。
需要注意的是,这里将权限进行对比的过程,实则是将两权限做“按位相与”运算,最终得出的值,即为 st 用户有效的 ACL 权限。这里以读(r)权限为例,做相与操作的结果如表 1 所示:
表 1 读权限做相与操作
A B and
r r r
r - -
- r -
- - -
但是,如果把 mask 权限改为 r--,再和 st 用户的权限 r-x 比对(r-- 和 r-w 做与运算),由于 r-w 超出 r-- 的权限范围,因此 st 用户最终只有 r 权限,手动赋予的 w 权限无效。这就是在设定 ACL 权限时 mask 权限的作用。
大家可以这样理解 mask 权限的功能,它将用户或群组所设定的 ACL 权限限制在 mask 规定的范围内,超出部分直接失效。
mask 权限可以使用 setfacl 命令手动更改,比如,更改 project 目录 mask 权限值为 r-x,可执行如下命令:
[root@localhost ~]# setfacl -m m:rx /project
#设定mask权限为r-x,使用"m:权限"格式
[root@localhost ~]# getfacl /project
#file:project
#owner:root
#group:tgroup
user::rwx
group::rwx
mask::r-x <--mask权限变为r-x
other::---
不过,我们一般不更改 mask 权限,只要赋予 mask 最大权限(也就是 rwx),则给用户或群组设定的 ACL 权限本身就是有效的。