Linux系统之访问控制列表
首先我们来了解下权限,在Linux里常规的权限有r(读)w(写)x(执行),特殊权限有SUID,SGID,Sticky权限,分别作用在文件(或目录)的所有者,所属组和其他(既不是所有者,也不是所属组的其他用户)上。在没有acl之前,我们只能对文件或目录的所有者,所属组,或其他用户进行授权。这样授权不是很灵活,比如我想在不影响原有的权限外单独给某一个用户授权,该怎么做呢?acl就提供了便利,它打破了传统授权的不灵活性。acl实现了灵活的权限管理,除了文件的所有者,所属组和其他人授权外,它还可以对更多的用户设置权限。ACL功能依赖文件系统,centos7默认创建的xfs和ext4文件系统,这两个文件系统都具有ACL功能,在7之前的版本,如果是手工创建的ext4文件系统,需要使用到ACL功能就需要手动添加。添加命令如下,有关SUID,SGID,Sticky权限介绍请参考:https://www.cnblogs.com/qiuhom-1874/p/9838468.html
tune2fs -o acl /dev/sdb1 mount -o acl /dev/sdb1 /mnt/test
说明:tune2fs命令是针对ext系列文件系统命令,在xfs文件系统上不能查看文件系统参数,只能在ext系列文件系统上使用。
接下来介绍两个命令的使用,getfacl、setfacl
getfacl:查看文件的acl权限列表
用法:
Usage: getfacl [-aceEsRLPtpndvh] file ...
常用选项:
-a, --access 仅显示文件访问控制列表
-d, --default 只显示默认的访问控制列表
-c, --omit-header 不显示注释头
-e, --all-effective 打印所有有效权限
-E, --no-effective 打印无效权限
-R, --recursive 递归到子目录
[root@test ~]$setfacl -dm u:qiuhom:rwx xx [root@test ~]$ [root@test ~]$getfacl xx # file: xx # owner: root # group: root user::rwx user:tom:rwx group::r-x mask::rwx other::r-x default:user::rwx default:user:qiuhom:rwx default:group::r-x default:mask::rwx default:other::r-x [root@test ~]$getfacl -a xx # file: xx # owner: root # group: root user::rwx user:tom:rwx group::r-x mask::rwx other::r-x [root@test ~]$getfacl -d xx # file: xx # owner: root # group: root user::rwx user:qiuhom:rwx group::r-x mask::rwx other::r-x [root@test ~]$getfacl -c xx user::rwx user:tom:rwx group::r-x mask::rwx other::r-x default:user::rwx default:user:qiuhom:rwx default:group::r-x default:mask::rwx default:other::r-x [root@test ~]$getfacl -e xx # file: xx # owner: root # group: root user::rwx user:tom:rwx #effective:rwx group::r-x #effective:r-x mask::rwx other::r-x default:user::rwx default:user:qiuhom:rwx #effective:rwx default:group::r-x #effective:r-x default:mask::rwx default:other::r-x [root@test ~]$getfacl -E xx # file: xx # owner: root # group: root user::rwx user:tom:rwx group::r-x mask::rwx other::r-x default:user::rwx default:user:qiuhom:rwx default:group::r-x default:mask::rwx default:other::r-x [root@test ~]$getfacl -R xx # file: xx # owner: root # group: root user::rwx user:tom:rwx group::r-x mask::rwx other::r-x default:user::rwx default:user:qiuhom:rwx default:group::r-x default:mask::rwx default:other::r-x # file: xx/aac # owner: root # group: root user::rw- user:tom:rwx group::r-- mask::rwx other::r-- # file: xx/aad # owner: root # group: root user::rw- user:tom:rwx group::r-- mask::rwx other::r-- # file: xx/abc # owner: root # group: root user::rw- user:qiuhom:rwx user:tom:rwx group::r-x mask::rwx other::r-- # file: xx/aab # owner: root # group: root user::rw- user:tom:rwx group::r-- mask::rwx other::r-- [root@test ~]$
setfacl :设置文件的acl权限列表
用法:
Usage: setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ...
常用选项:
-m: --modify=acl 修改文件当前的acl(在没有设置ACL的文件上使用就表示添加ACL)
[root@test ~]$ll total 4 -r--r----- 1 root root 18 Oct 29 18:07 test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- group::r-- other::--- [root@test ~]$setfacl -m u:qiuhom:rwx test.txt [root@test ~]$ll total 4 -r--rwx---+ 1 root root 18 Oct 29 18:07 test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:qiuhom:rwx group::r-- mask::rwx other::--- [root@test ~]$setfacl -m u:qiuhom:w test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:qiuhom:-w- group::r-- mask::rw- other::--- [root@test ~]$
说明:在设置添加acl的文件后,用ls -l 可以看到权限位最后多了一个+,这个加号表示该文件有acl权限。getfacl命令是专门查看文件的acl详情。
-M, --modify-file=file 批量设置指定文件里的acl权限。
[root@test ~]$ls test.txt [root@test ~]$cat >xx.acl u:qiuhom:rw g:root:rx ^C [root@test ~]$cat xx.acl u:qiuhom:rw g:root:rx [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:qiuhom:-w- group::r-- mask::rw- other::--- [root@test ~]$setfacl -M xx.acl test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:qiuhom:rw- group::r-- group:root:r-x mask::rwx other::--- [root@test ~]$
说明:在用-M指定文件的时候,文件内容是一行对应一条acl权限,内容只需要我们希望设置的用户或组的acl权限。
-x, --remove=acl 删除指定的acl权限
[root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:qiuhom:rw- group::r-- group:root:r-x mask::rwx other::--- [root@test ~]$setfacl -x u:qiuhom test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- group::r-- group:root:r-x mask::r-x other::--- [root@test ~]$
说明:删除acl权限 只指定用户或者组,不需要指定对应的权限
-X, --remove-file=file 删除指定文件内容的acl权限
[root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:tom:rw- user:jerry:--x group::r-- group:root:r-x mask::rwx other::--- [root@test ~]$cat > xxx.acl u:tom u:jerry g:root ^C [root@test ~]$cat xxx.acl u:tom u:jerry g:root [root@test ~]$setfacl -X xxx.acl test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- group::r-- mask::r-- other::--- [root@test ~]$
说明:和批量增加acl一样,这个指定的文件里面只需要写好需要删除acl就好,一行一个acl权限。和单端删除acl一样,不需要写明对应的权限。
-b, --remove-all 清空文件的acl权限列表
[root@test ~]$setfacl -m u:tom:rwx test.txt [root@test ~]$setfacl -m u:jerry:rwx test.txt [root@test ~]$setfacl -m g:tom:r test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:tom:rwx user:jerry:rwx group::r-- group:tom:r-- mask::rwx other::--- [root@test ~]$setfacl -b test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- group::r-- other::--- [root@test ~]$
-d, --default 设置默认的acl(这个选项只用于对目录的设定)
[root@test ~]$mkdir xx [root@test ~]$getfacl xx # file: xx # owner: root # group: root user::rwx group::r-x other::r-x [root@test ~]$setfacl -d -m u:qiuhom:rwx xx [root@test ~]$getfacl xx # file: xx # owner: root # group: root user::rwx group::r-x other::r-x default:user::rwx default:user:qiuhom:rwx default:group::r-x default:mask::rwx default:other::r-x [root@test ~]$cd xx/ [root@test xx]$touch abc [root@test xx]$getfacl abc # file: abc # owner: root # group: root user::rw- user:qiuhom:rwx #effective:rw- group::r-x #effective:r-- mask::rw- other::r-- [root@test xx]$
说明:用-d指定了默认的acl权限后,文件的acl权限列表里多了几项default,对目录设置了默认acl权限后,在其目录下新建的文件将继承该目录设置的默认acl权限列表(若新建的是文件x权限将不继承,若新建的是目录将全部继承)。
-k, --remove-default 删除默认的acl权限
[root@test ~]$getfacl xx/ # file: xx/ # owner: root # group: root user::rwx group::r-x other::r-x default:user::rwx default:user:qiuhom:rwx default:group::r-x default:mask::rwx default:other::r-x [root@test ~]$setfacl -k xx/ [root@test ~]$getfacl xx # file: xx # owner: root # group: root user::rwx group::r-x other::r-x [root@test ~]$getfacl xx/abc # file: xx/abc # owner: root # group: root user::rw- user:qiuhom:rwx #effective:rw- group::r-x #effective:r-- mask::rw- other::r-- [root@test ~]$
[root@test ~]$setfacl -dm u:tom:rwx xx [root@test ~]$setfacl -dm g:jerry:wx xx [root@test ~]$setfacl -m u:tom:r xx [root@test ~]$getfacl xx # file: xx # owner: root # group: root user::rwx user:tom:r-- group::r-x mask::r-x other::r-x default:user::rwx default:user:tom:rwx default:group::r-x default:group:jerry:-wx default:mask::rwx default:other::r-x [root@test ~]$setfacl -k xx [root@test ~]$getfacl xx # file: xx # owner: root # group: root user::rwx user:tom:r-- group::r-x mask::r-x other::r-x [root@test ~]$
说明:删除默认的acl权限后,不影响其目录下已经存在的文件的acl权限,此选项删除-d指定的默认acl权限,使用-k选项可以不用指定其权限,只要是默认的acl他都将清除。
--set=acl 设置acl权限,覆盖已有的acl权限
[root@test ~]$setfacl -m u:tom:rw test.txt [root@test ~]$setfacl -m g:tom:r test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- user:tom:rw- group::r-- group:tom:r-- mask::rw- other::r-- [root@test ~]$setfacl --set u::r,g::r,o::-,u:qiuhom:rwx test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:qiuhom:rwx group::r-- mask::rwx other::--- [root@test ~]$
[root@test ~]$setfacl --set g:tom:rx test.txt setfacl: test.txt: Malformed access ACL `group:tom:r-x,mask::r-x': Missing or wrong entry at entry 1 [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::r-- user:qiuhom:rwx group::r-- mask::rwx other::--- [root@test ~]$setfacl --set u::rw,g::rw,o::rw test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- group::rw- other::rw- [root@test ~]$
说明:使用--set选项设置权限,需要设置,包括所有者,所属组,其他用户的权限都设置才可以,否则提示缺少权限,不让设置,当然我们只设置所有者,所属组和其他,的权限,就相当于-b选项清空acl权限。
设置修改acl权限的mask权限。看下面的例子你就会明白mask到底是干嘛用的了。
[root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- user:qiuhom:rwx group::rw- mask::rwx other::rw- [root@test ~]$setfacl -m mask::r test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- user:qiuhom:rwx #effective:r-- group::rw- #effective:r-- mask::r-- other::rw- [root@test ~]$
说明:心细的你一定发现,后面的acl列表里多了两条注释的东西,这到底是什么呢?查阅了下字典,它说的意思是有效的。不难理解它想表达的意思是,我们虽然设置了qiuhom用户对文件的acl权限是rwx,但是有效的权限只有r生效。这到底为什么呢? 对,这就是mask的作用,它可以很好的限制文件的最大权限。它的作用只能限制除所有者和other之外的人和组的最大权限。也就是说自定义用户和组的权限必须存在mask权限设定的范围内才会生效。mask需要与我们设置的用户权限进行逻辑与运算后才能才能变成有效的权限。
[root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- user:qiuhom:r-- user:jerry:rwx group::r-- group:tom:rw- mask::rwx other::--- [root@test ~]$ll test.txt -rw-rwx---+ 1 root root 0 Oct 29 18:39 test.txt [root@test ~]$chmod g=rw test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- user:qiuhom:r-- user:jerry:rwx #effective:rw- group::r-- group:tom:rw- mask::rw- other::--- [root@test ~]$
说明:我们修改mask的权限也可以通过修改文件的属组权限来修改mask权限。这里需要注意的是,在没有设置acl的文件上用以上方法是修改文件属组的权限,在拥有acl后,以上方法就是修改mask的权限,并非文件属组权限。
-R, --recursive 递归设置acl权限
[root@test ~]$ll xx total 0 -rw-r--r-- 1 root root 0 Oct 29 19:25 aab -rw-r--r-- 1 root root 0 Oct 29 19:25 aac -rw-r--r-- 1 root root 0 Oct 29 19:25 aad -rw-rw-r--+ 1 root root 0 Oct 29 18:47 abc [root@test ~]$getfacl xx/aab xx/aac xx/aad # file: xx/aab # owner: root # group: root user::rw- group::r-- other::r-- # file: xx/aac # owner: root # group: root user::rw- group::r-- other::r-- # file: xx/aad # owner: root # group: root user::rw- group::r-- other::r-- [root@test ~]$setfacl -R -m u:tom:rwx xx [root@test ~]$getfacl -R xx # file: xx # owner: root # group: root user::rwx user:tom:rwx group::r-x mask::rwx other::r-x # file: xx/aac # owner: root # group: root user::rw- user:tom:rwx group::r-- mask::rwx other::r-- # file: xx/aad # owner: root # group: root user::rw- user:tom:rwx group::r-- mask::rwx other::r-- # file: xx/abc # owner: root # group: root user::rw- user:qiuhom:rwx user:tom:rwx group::r-x mask::rwx other::r-- # file: xx/aab # owner: root # group: root user::rw- user:tom:rwx group::r-- mask::rwx other::r-- [root@test ~]$
说明:很多命令-R都有递归的意思,比如chmod -R chown -R 这些都是递归的意思,批量做一件事,这里的setfacl 和getfacl 也是这个意思。
--set-file=file 从指定文件里读入要设置的acl权限
[root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- user:qiuhom:r-- user:jerry:rwx group::r-- group:tom:rw- mask::rwx other::--- [root@test ~]$getfacl test.txt >test.acl [root@test ~]$touch aa [root@test ~]$getfacl aa # file: aa # owner: root # group: root user::rw- group::r-- other::r-- [root@test ~]$setfacl --set-file test.acl aa [root@test ~]$getfacl aa # file: aa # owner: root # group: root user::rw- user:qiuhom:r-- user:jerry:rwx group::r-- group:tom:rw- mask::rwx other::--- [root@test ~]$
说明:--set-file实现了acl权限复制,备份,我们可以通过getfacl 把文件的acl导入到一个文件,然后用--set-file指定该文件 来设置其他文件的acl,当然上面的命令有些罗嗦,我们可以用一条命令搞定。如下:
[root@test ~]$setfacl -b test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- group::r-- other::--- [root@test ~]$getfacl aa |setfacl --set-file=- test.txt [root@test ~]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- user:qiuhom:r-- user:jerry:rwx group::r-- group:tom:rw- mask::rwx other::--- [root@test ~]$
说明:上面的命令用到了- ,这里说一下‘-’的作用,它的作用是将上一个命令的标准输出,用- 代替,这里也就是说getfacl test.txt 的输出 用‘-’代替。
接下来看看ACL生效的顺序
[root@test tmp]$id qiuhom uid=500(qiuhom) gid=500(qiuhom) groups=500(qiuhom),504(webs) [root@test tmp]$getfacl test.txt # file: test.txt # owner: root # group: root user::rw- user:qiuhom:r-- group::r-- group:db:r-- group:webs:-w- mask::rw- other::--- [root@test tmp]$su qiuhom [qiuhom@test tmp]$cat test.txt xxxx [qiuhom@test tmp]$echo "qiuhom" >> test.txt bash: test.txt: Permission denied [qiuhom@test tmp]$
说明:以上例子证明了一个acl生效顺序,acl自定义用户的权限优先级高于自定义用户组的权限,在上例中可以看到,qiuhom这个用户不是文件的所有者,也不属于root组,所以不匹配所有者上的权限,接着系统有开始匹配是不是指定用户,如果是系统就不匹配后面的权限,就直接执行匹配的权限,虽然用户qiuhom所在的附加组webs有写的权限,但是优先级比指定用户要低所以无效。
[root@test tmp]$chmod 400 test.txt [root@test tmp]$ll test.txt -r-------- 1 qiuhom qiuhom 5 Oct 29 20:29 test.txt [root@test tmp]$setfacl -m u:qiuhom:w test.txt [root@test tmp]$getfacl test.txt # file: test.txt # owner: qiuhom # group: qiuhom user::r-- user:qiuhom:-w- group::--- mask::-w- other::--- [root@test tmp]$su qiuhom [qiuhom@test tmp]$cat test.txt xxxx [qiuhom@test tmp]$echo "test " >> test.txt bash: test.txt: Permission denied [qiuhom@test tmp]$
说明:可以看到,所有者的权限优先级高于自定义权限优先级。系统首先匹配到了所有者的权限,所以后面的权限就不去看了。
[root@test tmp]$ll test.txt -r---w-r--+ 1 qiuhom qiuhom 5 Oct 29 20:29 test.txt [root@test tmp]$getfacl test.txt # file: test.txt # owner: qiuhom # group: qiuhom user::r-- user:tom:-w- group::--- mask::-w- other::r-- [root@test tmp]$su tom [tom@test tmp]$cat test.txt cat: test.txt: Permission denied [tom@test tmp]$echo "tom write" >>test.txt [tom@test tmp]$exit exit [root@test tmp]$setfacl -m mask::r test.txt [root@test tmp]$getfacl test.txt # file: test.txt # owner: qiuhom # group: qiuhom user::r-- group::--- group:tom:r-- mask::r-- other::-w- [root@test tmp]$su tom [tom@test tmp]$cat test.txt xxxx tom write abc [tom@test tmp]$echo "abcdddd" >> test.txt bash: test.txt: Permission denied [tom@test tmp]$
说明:以上示例可以看出,自定义用户的权限优先级大于其他户的优先级,自定义用户组的优先级大于其它优先级。
总结:
我们知道在没有设置acl的文件里,系统权限优先级是,所有者 > 所属组 > 其他用户。但是在设置了acl的文件里权限的优先级是这样的,所有者 > 自定义用户 > 自定义组 > 其他用户。
ACL文件上的group权限是mask值,而非传统的组权限,默认设置了acl权限后,原有的group的权限就不显示,只显示mask权限,但是原有的group权限不变。
通过ACL赋予目录默认x权限,目录内文件也不会继承x权限
mask只影响除所有者和other的之外的人和组的最大权限,Mask需要与用户的权限进行逻辑与运算后,才能变成有限的权限(EffectivePermission),用户或组的设置必须存在于mask权限设定范围内才会生效。