使用ACL规划linux详细权限


Linux的权限概念是非常重要的! 传统的文件权限身份只有三种,分别是owner, group和others,搭配三种权限r,w,x, 并没有办法单纯的针对某一个使用者或某一个群组来设定特定的权限需求, 此时就得要使用ACL机制了!

1.什么是ACL

回到顶部
ACL是Access Control List的缩写,主要目的是在提供传统的owner,group,others的read,write,execute权限之外的细部权限设定。 ACL可以针对单一使用者,单一文件或目录来进行r,w,x的权限规范,对于需要特殊权限的使用状况非常有帮助。
那ACL主要针对一下几个项目来控制权限:
使用者(user):可以针对使用者来设定权限;
群组(group):针对群组为对象来设定其权限;
默认属性(mask):还可以针对在该目录下在建立新文件/目录时,规范新数据的默认权限;
如果有一个目录,需要给一堆人使用,每个人或每个群组所需要的权限都不相同, 传统的Linux三种身份的三种权限是无法达到的, 传统的Linux权限只能针对一个用户、一个群组及非此群组的其他人设定权限而已, 无法针对单一用户或个人来设计权限。而ACL就是为了要改变这个问题啊!

2.查看系统是否支持ACL

回到顶部
如何让文件系统可以支持ACL! ACL原本是unix-like操作系统的额外支持项目,近年来Linux系统对权限细部设定的需求越来越强烈, 目前几乎所有的linux文件系统(ext2/ext3/ext4/xfs等)默认都会支持ACL,ACL是可以直接使用的。 可以通过观察内核启动时打印的信息查看是否支持ACL:
[root@study ~]# dmesg | grep -i acl
[    8.225017] systemd[1]: systemd 237 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD -IDN2 +IDN -PCRE2 default-hierarchy=hybrid)
[    8.225042] systemd[1]: Detected virtualization oracle.
            
可以看上输出中有+ACL,表明系统已经支持ACL了。

3.setfacl命令

回到顶部
好了,既然知道我们的 filesystem 有支持 ACL 之后,接下来该如何设定与观察 ACL 呢? 很简单, 利用这两个指令就可以了:
getfacl:取得某个文件/目录的ACL设定项目;
setfacl:设定某个目录/文件的ACL规范。
            [root@study ~]# setfacl [-bkRd] [{-m|-x} acl 参数] 目标文件名
            
选项与参数:
-m :设定后续的acl参数给文件使用,不可与-x合用;
-x :删除后续的acl参数,不可与-m合用;
-b :移除所有的ACL设定参数;
-k :移除预设的ACL参数,关于所谓的预设参数于后续范例中介绍;
-R :递归设定acl,亦即包括次目录都会被设定起来;
-d :设定预设acl参数的意思!只对目录有效,在该目录新建的数据会引用此默认值
上面谈到的是 acl 的选项功能,那么如何设定 ACL 的特殊权限呢? 特殊权限的设定方法有很多,我们先来谈谈最常见的,就是针对单一使用者的设定方式:

4.针对某个用户设置文件权限

回到顶部
设定参数为: u:[用户账号列表]:[rwx]
我们用root身份创建一个文件acltest:
            [root@study ~]# touch acltest
            [root@study ~]# ls -l acltest 
            -rw-r--r-- 1 root root 0 Feb 23 19:00 acltest
            
通过ls -l可以观察到acltest文件的拥有者和所属用户组均为root, 其他用户对该文件具有r--权限,现在希望peter用户对该文件具有rw-权限。 如果将other权限修改为rw-,那么包括peter在内的所有other用户的权限都会变成rw-。 这里是希望只修改peter对该文件的权限,而不影响ohter用户的其他用户。 setfacl针对peter的权限设置如下:
            [root@study ~]# setfacl -m u:peter:rw acltest
            
再用ls -l观察acltest文件的权限:
            [root@study ~]# ls -l acltest 
            -rw-rw-r--+ 1 root root 0 Feb 23 19:00 acltest
            
权限部分发生了变化,-rw-r--r--变成了-rw-rw-r--+,后面多了一个+,和我们之前理解的权限不太一样。 只要使用ACL设置过权限后,就会多出一个+号! 如果用户列表为空,表示设置文件拥有者的权限,例如将root的权限设置为rwx:
            [root@study ~]# setfacl -m u::rwx acltest
            [root@study ~]# ls -l acltest 
            -rwxrw-r--+ 1 root root 0 Feb 23 19:00 acltest
            
文件拥有者root的权限部分变成了rwx!
使用'-m u:使用者:权限'的方式就可以针对某个用户来设置文件的权限了!

5.getfacl命令

回到顶部
设置了acl权限后,会发现用ls -l观察的文件权限和预期的有点不一样。 此时就可以通过getfacl观察文件的详细权限了。
getfacl命令常用格式如下:
            [root@study ~]# getfacl filename
            
getfacl的选项几乎与setfacl相同!这里省去选项的说明!
用getfacl命令查看acltest文件的权限:
[root@study ~]# getfacl acltest
# file: acltest
# owner: root
# group: root
user::rwx
user:peter:rw-
group::r--
mask::rw-
other::r--

            
上面可以看到第一行为文件名,第二行为文件拥有者,第三行为文件所属用户组;
从第四行开始就是文件的权限描述了,格式和用-m设置权限的时候是一样的:
user::rwx用户列表为空,表示文件拥有者的权限为rwx;
user:peter:rw-表示用户peter对该文件的权限为rw-;
group::r--表示用户所属用户组的权限为r--;
mask::rw-表示文件默认的有效权限(mask)为rw-;
other::r--表示其他用户对该文件的权限为r--。
getfacl命令显示的文件权限还是很容易理解的。

6.针对某个用户组设置文件权限

回到顶部
设定参数为: g:[用户群组列表]:[rwx]
例如系统中有一个vboxsf用户组,我们设置该用户组对acltest文件的权限为rw-:
            [root@study ~]# setfacl -m g:vboxsf:rw acltest
            
再次用getfacl命令观察acltest文件的权限:
            [root@study ~]# getfacl acltest 
# file: acltest
# owner: root
# group: root
user::rwx
user:peter:rw-
group::r--
group:vboxsf:rw-
mask::rw-
other::r--

            
可以看到多出来一行group:vboxsf:rw-,表示vboxsf用户组对acltest文件的权限为rw-。 群组与使用者的设置并没有什么太大的差异,也非常容易理解。

7.设置mask权限

回到顶部
设定参数为: m:[rwx]
mask有点类似有效权限的意思! mask规定使用者或群组所设定的权限必须要存在于mask的权限设定范围内才会生效,即有效权限(effective permission)
例如设置acltest文件规范为仅有r:
            [root@study ~]# setfacl -m m:r acltest
            
再次用getfacl命令观察acltest文件的权限:
[root@study ~]# getfacl acltest
# file: acltest
# owner: root
# group: root
user::rwx
user:peter:rw-			#effective:r--
group::r--
group:vboxsf:rw-		#effective:r--
mask::r--
other::r--

            
通过上面可以看出user:peter:rw-和group:vboxsf:rw-这两行后面都多了#effective:r--, mask行变为mask::r-- 表示用户peter的权限虽然为rw-,但是由于mask的限制,所以peter真正的有效权限实际上是r--; 用户组vboxsf也是同样的道理。 注意这里的mask和文件权限掩码umask的区别,这两个东西根本就不是一回事儿。 可以通过mask来规范最大允许权限,就能够避免不小心开放某些权限给其他使用者或群组了。 不过mask的出现也给权限设置增加了一定的复杂度,所以在实际的操作中,干脆将mask设置为rwx,对用户和用户组开放所有的权限, 然后在针对具体的用户和用户组设置权限就可以了。

8.acl针对目录的权限设置

回到顶部
如果希望目录下的文件或者子目录可以继承父目录的acl设置,可以在原来的设置基础上加上d选项:d:[u|g]:[userlist|grouplist]:[rwx]
上面的例子我们是针对文件进行的设置,也可以针对目录进行设置,方法当然是和文件一模一样的。 但是目录有一个权限继承的问题,也就是说目录下的文件和子目录是否会继承父目录acl的设置呢?
我们用root身份在/tmp目录下创建一个acltestdir目录进行测试:
            [root@study ~]$ cd /tmp
            [root@study /tmp]$ mkdir acltestdir
            [root@study /tmp]$ ls -ld acltestdir/
            drwxr-xr-x 2 root root 4096 Feb 23 20:05 acltestdir/
            
上面创建的目录权限为drwxr-xr-x,任何用户都可以进入该目录,我们用chmod将other的权限设置为只读:
            [root@study /tmp]$ chmod o-x acltestdir
            [root@study /tmp]$ ls -ld acltestdir/
drwxr-xr-- 2 root root 4096 Feb 23 20:05 acltestdir/
            
这样用户peter是没有权限进入/tmp/acltestdir目录的。我们将用户切换到peter试试:
            [root@study /tmp]$ su peter
            [peter@study /tmp]$ cd acltestdir/
            bash: cd: /tmp/acltestdir: Permission denied
            
peter确实没有权限进入/tmp/acltestdir目录。
现在回到root用户,设置peter对该目录的权限为rx:
            [peter@study /tmp]$ exit
            [root@study /tmp]# setfacl -m u:peter:rx /tmp/acltestdir
            [root@study /tmp]# getfacl /tmp/acltestdir/
getfacl: Removing leading '/' from absolute path names
# file: tmp/acltestdir/
# owner: root
# group: root
user::rwx
user:peter:r-x
group::r-x
mask::r-x
other::---

            
再次切换回peter试试:
            [root@study /tmp]$ su peter
            [peter@study /tmp]$ cd acltestdir/
            [peter@study /tmp]$ ls -al
total 204
drwxr-x---+  2 root root   4096 Feb 23 20:16 .
drwxrwxrwt  20 root root 200704 Feb 23 20:26 ..
            [peter@study /tmp]$ touch testing
            touch: cannot touch `testing': Permission denied
            [peter@study /tmp]$ exit
            
可以看到peter顺利进入/tmp/acltestdir目录了。因为peter对该目录是没有写权限的,所有在该目录下用touch命令是无法创建文件的。
上面我们对目录进行了简单的权限设置,现在回到本节的主题。
也就是我们用setfacl命令对目录设置的acl权限是否会影响到该目录中的文件和子目录呢?
也就是ACL的权限设定是否能够被次目录所继承。
我们回到root身份,在/tmp/acltestdir目录下创建一个文件和一个目录试试:

            [root@study /tmp]# cd /tmp/acltestdir
            [root@study /tmp]# touch test1
            [root@study /tmp]# mkdir test2
            [root@study /tmp]# ls -ld test*
            -rw-r--r-- 1 root root    0 Feb 23 20:43 test1
            drwxr-xr-x 2 root root 4096 Feb 23 20:43 test2
            
可以看到权限后面都没有+号,说明acl权限并没有被目录下的文件和子目录继承!
如果希望目录下的文件或者子目录可以继承父目录的acl设置,可以在原来的设置基础上加上d选项:d:[u|g]:[userlist|grouplist]:[rwx]
让peter在/tmp/acltestdir目录下一直具有rx的默认权限:
[root@study ~]# setfacl -m d:u:peter:rx /tmp/acltestdir
[root@study ~]# getfacl /tmp/acltestdir
getfacl: Removing leading '/' from absolute path names
# file: tmp/acltestdir
# owner: root
# group: root
user::rwx
user:peter:r-x
group::r-x
mask::r-x
other::---
default:user::rwx
default:user:peter:r-x
default:group::r-x
default:mask::r-x
default:other::---

            [root@study ~]# cd /tmp/acltestdir
            [root@study projecta]# touch acltest1
            [root@study projecta]# mkdir acltest2
            [root@study projecta]# ls -ld acltest*
            -rw-r-----+ 1 root root    0 Feb 23 20:52 acltest1
            drwxr-x---+ 2 root root 4096 Feb 23 20:52 acltest2
          
创建的新文件和子目录确实有acl权限了,我们用getfacl观察一下acltest2目录看看:
            [root@study projecta]# getfacl acltest2/
# file: acltest2/
# owner: root
# group: root
user::rwx
user:peter:r-x
group::r-x
mask::r-x
other::---
default:user::rwx
default:user:peter:r-x
default:group::r-x
default:mask::r-x
default:other::---


            
针对目录设置默认的ACL权限,就可以让这些属性继承到次目录!

9.取消acl设置

回到顶部
要取消文件的所有acl设置,只需要用-b选项就可以了,如果要取消某个用户的acl设置,需要用到-x选项 例如取消上面/root/acltest文件的所有acl设置:
              [root@study ~]# setfacl -b /root/acltest
            
如果只是想取消某个用户的acl设置,例如取消peter对/tmp/acltestdir目录的acl权限设置:
              [root@study ~]# setfacl -x u:peter /tmp/acltestdir
            
或者将peter对该目录下文件和子目录的acl权限也取消:
              [root@study ~]# setfacl -x d:u:peter /tmp/acltestdir
            
如果希望peter对/tmp/acltestdir目录没有任何权限:
            [root@study ~]# setfacl -m u:peter:- /tmp/acltestdir
            
设置某个用户或群组没有任何ACL权限的时候,权限字段不可留白,而是应该加上一个减号'-'才对!

initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读