访问控制列表(ACL)
ACL(Access Control List)是标准 UNIX 文件属性(r.w.x)的附加扩展。ACL 给予用户和管理员更好控制文件读写和权限赋予的能力,Linux 从 2. 6 内核开始提供对 Ext2、Ext3、Ext4、XFS、JFS 等文件系统的 ACL 支持。
1.为什么要使用 ACL
在Linux 中,对一个文件可以进行操作的对象被分为三类:user、group、other。
例如:
#1s -l
-rw-rw----1 ztg adm 0 Jul 3 20:12 test.txt
若现在希望用户 zhang 也可以对 test.txt 文件进行读写操作,有以下几种办法(假设 zhang 不属于 adm 组)。
①给文件的 other 增加读写权限,由于 zhang 属于 other,因此 zhang 将拥有读写的权限。
②将 zhang 加入到 adm 组,则 zhang 将拥有读写的权限。
③设置 sudo,使 zhang 能够以 ztg 的身份对 test.txt 进行操作,从而获得读写权限。
第 1 种做法的问题:所有用户都将对 test.txt 拥有读写权限。
第 2 种做法的问题:zhang 被赋予了过多的权限,所有属于 adm 组的文件,zhang 都可以拥有其等同的权限。
第 3 种做法的问题:虽然可以达到只限定 zhang 用户一人拥有对 test. txt 文件的读写权限,但是需要对 sudoers 文件进行严格的格式控制,而且当文件数量和用户很多的时候,这种方法就很不灵活了。
看来好像没有一个好的解决方案,其实问题出在 Linux的文件权限方面,主要在于对other 的定义过于宽泛,以至于很难把“权限”限定于一个不属于 owner 和 group 的用户。而 ACL(Access Control List)就是用来帮助用户解决这个问题的。
ACL可以为某个文件单独设置该文件具体的某用户或组的权限。需要掌握的命令也只有三个:getfacl,setfacl,chacl。
•getfacl<文件名>
//获取文件的访问控制信息
• setfacl -m u:用户名:权限 <文件名>
//设置某用户名的访问权限
• setfacl -m g:组名:权限 <文件名>
//设置某个组的访问权限
• setfacl -x u:用户名 <文件名>
//取消某用户名访问权限
• setfacl -x g:组名 <文件名>
//取消某个组的访问权限
• chacl u:用户名:权限,g:组名:权限<文件名>
//修改文件的访向控制信息
2. Linux 是否支持 ACL
因为 Linux 系统并不是每一个版本的核心都支持 ACL的功能,因此先要检查系统核心是否支持 ACL。
#cat /boot/config-3.10.0-121.e17.x86_64 | grep -i xfs
//如果是 ext4 文件系统,则将 xfs 换为 ext4
CONFIG_XFS_FS=m
CONFIG_XFS_QUOTA=Y
CONFIG_XFS_POSIX_ACL=y
//表示支持 ACL
打开文件系统的 ACL 支持,修改/etc/fstab 的 mount 属性,例如,针对/opt 文件系统,LABEL=/opt /opt ext3 rw,acl 1 2。
#mount -v -o remount/opt.
#mount -1
/dev/hda10 on /opt type ext3 (rw,acl) [/Home]
3.ACL 的名词定义
ACL 是由一系列的 Access Entry 组成,每一条 Access Entry 定义了特定的类别,可
以对文件拥有的操作权限。Access Entry 有三个组成部分:Entry tag type、qualifier
(optional),permission。
先来看一下最重要的 Entry tag type,有以下几个类型。
ACL_USER_OBJ:相当于 Linux 里 file_owner 的权限。
ACL_USER:定义了额外的用户可以对此文件拥有的权限。
ACL_GROUP_OBJ:相当于 Linux 中 group 里的权限。
ACL_GROUP:定义了额外的组可以对此文件拥有的权限。
ACL_MASK:定义了 ACL_USER、ACL_GROUP _OBJ、ACL_GROUP 的最大权限。
ACL_OTHER:相当于 Linux 里其他的权限。
示例如下:
[ztg@localhost ~]$ getfacl ./test.txt
#file:test.txt
#owner:ztg
#group: adm
user::rw-
//定义了 ACL_USER_OBJ,说明 file owner 拥有读写权限
user:zhang:rw- //定义了 ACL_USER,这样用户 zhang 就拥有了对文件的读写权限
group::rw- //定义了 ACL_GROUP_OBJ,说明文件的 grqup 拥有读写权限
group:dev:r--//定义了 ACL_GROUP,使得 dev 组拥有了对文件的读权限
mask::rw-//定义了 ACL_MASK 的权限为读写权限
other::r--//定义了 ACL_OTHER 的权限为读权限
前面三个以#开头的行是注释,可以用-omit-header 省略。
4.如何设置 ACL 文件
首先还是要讲一下设置 ACL 文件的格式。从上面的例子可以看到,每一个 Access
Entry 都是由三个被分号(:)分隔开的字段所组成。
第1个是人口的标志类型:
user 对应着 ACL_USER_OBJ 和 ACL_USER。
group 对应着 ACL_GROUP_OBJ 和 ACL_GROUP。
mask 对应着 ACL_MASK。
other 对应着 ACL_OTHER。
第 2 个是限定,也就是上面例子中的 zhang 和 dev组,它定义了特定用户和组对于文件的权限,这里只有user 和 group 才有限定,其他的都为空。
第 3 个是权限,它和 Linux 的“权限”一样,这里就不赘述。
下面来看一下怎么设置 test.txt 这个文件的 ACL,让它来达到上面的要求。一开始文件没有 ACL 的额外属性。
[ztg@localhost ~]$ 1s -l
-rw-rw-r--1 ztg adm 0 Jul 3 22:06 test.txt
[ztg@localhost ~]$ getfacl --omit-header ./test.txt
user::rw-
group::rw-
other::r--
先让用户 zhang 拥有对 test.txt 文件的读写权限。
[ztg@localhost ~]$ setfacl -m user:zhang:rw-./test.txt
[ztgllocalhost ~J$ getfacl --omit-header ./test.txt
user::rw-
user:zhang:rw-
group::rw-
mask::rw-
other::r--
这时就可以看到 zhang 用户在 ACL 里面已经拥有了对文件的读写权限,此时如果查看一下 Linux 的“权限”,还会发现一个不一样的地方。
[ztg@ localhost ~]$ 1s -I ./test.txt
-rw-rw-r--+1 ztg adm 0 Jul 3 22:06 ./test.txt
在文件“权限”的最后多了一个十号,表示该文件使用 ACL 的属性设置,是一个 ACL文件。当任何一个文件拥有了 ACL_USER 或 ACL_GROUP 的值后,就可以称它为ACL 文件。
接下来设置 dev 组拥有读权限。
[ztg@ localhost ~]$ setfacl -m group:dev:r-- ./testitxt
[ztg@ localhost ~]$ getfacl --omit-header ./test.txt
user::rw-
user:zhang:rw-
group::rw-
group:dev:r--
mask::rw-
other::r--
至此,就实现了上面提到的要求。
5.ACL_MASK 和最大有效性权限
这里需要重点讲一下 ACL_MASK,因为这是掌握 ACL 的另一个关键。在 Linux 文件“权限”里面,比如 rw-rw-r-,中间的 rw-是指 group 的权限。但是在 ACL里,这种情况只是在 ACL_MASK 不存在的情况下成立。若文件有 ACL_MASK 值,则中间的 rw-代表的就是 mask 值而不再是 group 的权限了。
看下面这个例子。
[ztgelocalhost ~]$ is -l
_rwxrw-r--1 ztg adm 0 Jul 3 08:30 test.sh
这里说明 test. sh 文件只有 ztg 拥有可读、可写、可执行权限,adm 组只有读写权限。现在想让用户 zhang 也对 test. sh 具有和 ztg 一样的权限。
[ztgelocalhost ~]$ setfacl -m user:zhang:rwx ./test.sh
[ztgelocalhost ~]$ getfacl --omit-header./test.sh
user::rwx
user:zhang:rwx
group::rw-
mask::rwx
other::r--
可以看到 zhang 拥有了 rwx权限,mask 值也被设定为 rwx,它规定了 ACL_USER、ACL_GROUP、ACL_GROUP_OBJ 的最大值。
再来看 test. sh 的 Linux“权限”。
[ztg@localhost ~]$ 1s -l
_rwxrwxr--+1 ztg adm 0 Jul 3 08:30 test.sh
现在 adm 组用户想要执行 test. sh,会被权限否定。因为 adm 组用户只有读写权限,这中间的 rwx是 ACL_MASK 的值,而不是 group 的权限。
所以,如果是一个 ACL 文件,需要用 getfacl 确认它的权限。
看一个例子。假如现在设置 test. sh 的 mask 为只读,看 adm 组用户是否还会有写权限。
[ztg@localnost ~]$ setfacl -m mask::r-- ./test.sh
[ztg@localhost ~]$ getfacl --omit-header ./test.sh
user::rwx
user:zhang:rwx #effective:r--
group::rw- #effective:r--
mask::r--
other::r--
这时可以看到 ACL_USER 和 ACL_GROUP_OBJ 旁边多了个# effective:r--,表示最大权限是读。ACL_MASK 的定义:规定了 ACL_USER.ACL_GROUP_OBJ、ACL_GROUP 的最大权限。虽然这里给 ACL_USER、ACL_GROUP_OBJ 设置了其他权限,但是真正有效果的只有读权限。
这时再来看 test. sh 的权限,此时它的组权限会显示其 mask 值。
[ztg@localhost ~]$ ls -l
_rwxr--r--+1 ztg adm 0 Jul 3 08:30 test.sh
6. Default ACL
上面讲的都是 Access ACL,是对文件而言。而 Default ACL 是指对一个目录进行默
认 ACL 设置,然后在此目录下建立的文件都将继承此目录的 ACL。
比如现在 ztg 用户建立了一个 dir 目录。
[ztg@ localhost ~]$ mkdir dir
希望所有在此目录下建立的文件都可以被 zhang 用户访问,那么应该对 dir 目录设置 Default ACL。
[ztg@localhost ~]$ setfacl -d -m user:zhang:rwx ./dir
[ztg@localhost ~]$ getfacl --omit-header ./dir
user::rwx
group::rwx
other::r-x
default:user::rwx
default:user:zhang:rwx
default:group::rwx
default:mask::rwx
default:other::r-x
这里可以看到 ACL 定义了 default 选项,zhang 用户拥有了默认的 rwx权限,所有没
有定义的 default 都将从文件权限中复制而来。
现在 ztg 用户在 dir 下建立一个 test.txt 文件。
[ztgelocalhost ~]$ touch ./dir/test.txt
[ztg@localhost ~]$ ls -l ./dir/test.txt
-rw-rw-r--+1 ztg ztg 0 Jul 3 09:11 ./dir/test.txt
[ztg@localhost ~]$ getfacl--omit-header ./dir/test.txt
user::rw-
user:zhang:rw-
group::rwx #effective:rw-
mask::rw-
other::r--
可以看到,在 dir 下建立的文件,zhang 用户自动就有了读写权限。
7. ACL 相关命令
getfacl:用来读取文件的 ACL。
setfacl:用来设定文件的 ACL.
chacl:用来改变文件和目录的 ACL。chacl -B 可以彻底删除文件或目录的 ACL 属
性。如果使用 setfacl -x 删除了文件的所有 ACL 属性,那个十号还会出现,此时应该是用
chacl-B。
用 cp 命令复制文件时,加上-p 选项可以复制文件的 ACL 属性,对于不能复制的ACL 属性将给出警告。
mv 命令将会默认地移动文件的 ACL 属性,如果操作不允许,会给出警告。
8.需要注意的几点
如果某个文件系统不支持 ACL,需要执行下面命令重新挂载。
#mount -。 remount,acl [mount point]
如果用 chmod 命令改变 Linux的文件权限,相应的 ACL 值也会改变;改变 ACL的值,相应的文件权限也会改变。