facl,全称为file access control list,用于提供除rwx权限之外的权限管理。facl可以针对单一用户,单一文件或者目录来设置指定的rwx权限,对于有需求设置特殊权限的情况下的环境非常有用。
facl的查看:getfacl
查看文件的facl设定状态可以通过getfacl命令来实现。getfacl命令可以打印出文件名、属主、属组及facl等信息。对于一个目录来说,如果其具有默认的facl,getfacl也能将其打印显示,注意仅有目录可拥有default acl。
命令格式:
getfacl [options] [FILE]
常用选项:
-a:显示ACL规则列表;
-d:显示默认的规则列表;
-e:显示所有有效的ACL规则;
-E:显示所有失效的ACL规则;
-R:递归显示目录下的文件或目录的ACL规则;
-n:以数字化的UID和GID替换显示的属主和属组名;
-p:不去除路径前的/符号,报错显示路径的完成,常用于将文件的facl信息输出重定向到文件;
-L:跟踪符号链接文件,并显示对应链接文件的ACL规则;
-P:不跟踪符号链接文件;
--omit-header:不显示前三行默认的文件名,属主和属组信息;
使用案例:
查看文件所有的acl信息:
root@localhost ~]# getfacl /etc/passwd
getfacl: Removing leading '/' from absolute path names
# file: etc/passwd
# owner: root
# group: root
user::rw-
group::r--
other::r--
facl的设置:setfacl
设置文件和目录的facl列表
命令格式:
setfacl [options] [FILE]
setfacl --restore=FILE
常用选项:
-b,--remove-all:移除所有扩展ACL条目。
-k,--remove-default:移除所有的默认路由,如果没有默认路由存在,则不会有任何警告;
-d:设置default acl;
--restore=FILE:从文件中恢复facl规则,文件中的内容可由getfacl -R产生;此选项不能够与其他选项一起使用,--test除外;
--test:测试模式,显示修改的结果,不修改文件的ACL规则;
-R,--recursive:递归作用于目录及目录下的文件和目录;
-L,--logical:跟踪符号链接文件到源文件;
-P,--physical:不跟踪符号链接文件到源文件;
--:标记着命令行选项的结束,其后的所有参数都会被当作是文件名;
-:如果文件名是单个-,setfacl会从标准输入中读取文件名;
--mask:设置重新计算有效权限的mask值;
-n,--no-mask:不使用重新计算有效权限的mask值;
-m:修改或设置文件的ACL规则,多个ACL条目通过,隔开;
-x:移除ACL条目,多个ACL条目通过,隔开;
--set,--set-file=FILE:用来设置文件或目录的acl规则,先前的ACL规则将被覆盖;
ACL条目
ACL条目可以使用以下几个格式:
- 1 . [d[efault]:] [u[ser]:]uid [:perms] ,针对用户的权限格式;如果uid为空,则是针对文件属主的权限格式;
- 2 . [d[efault]:] g[roup]:gid [:perms],针对用户组的权限格式;如果gid为空,则是针对文件属组的权限格式;
- 3 . [d[efault]:] m[ask][:] [:perms],有效权限掩码的格式;
- 4 . [d[efault]:] o[ther][:] [:perms],其他组的权限格式;
在分隔符和非分隔符之间的空格会被忽略;格式正确的ACL条目通常用于修改或设置文件目录的ACL规则,而不带有权限的ACL规则通常用于删除ACL条目;
perms是文件权限的组合,包括read(r),write(w),execute(x),也可以使用八进制的方式表示。
user,group,mask,other用于区分ACL条目的类型;对于uid和gid来说,你可以指定名词或者使用id 数字来表示。
自动创建的ACL条目
每个初始文件和目录只包含三个分别对应属主、属组,其他组的基本ACL条目。而一个合法的facl需要满足以下条件:
- 1.三个基本ACL规则不能被移除。每个身份类型至少得有一个ACL条目;
- 2 . 当一个facl包含的ACL条目指定了uid或gid的时候,必须存在一个用于计算有效权限的mask条目;
- 3 . 当一个facl包含任意default ACL条目时,必须包含三个基本default ACL(对应属主,属组,其他组)。
- 4 .当一个default ACL指定了uid或者gid的时候,必须存在一个用于计算有效权限的default mask条目;
下面描述可以帮助你更好理解上述的规则:
- 1 . 如果一个acl指定了uid或者gid,但是没有mask条目存在,一个跟该acl条目有着相同权限的mask条目会被自动创建。除非指定了-n选项,否则该mask条目会作用于所有的属主、用户和用户组条目。
- 2 .一个facl如果创建了针对任意用户或用户组的default ACL条目,但是不包含对应属主、属组和其他组的基本default ACL的话,系统会自动生成与三个基本ACL规则有着相同权限的,对应三个身份的default ACL。
- 3 .如果一个default ACL指定了uid或gid,并且没有mask条目存在,那么一个有着与default 用户组条目相同权限的default mask条目会被自动创建。
Default ACL
Default ACl 只能对目录进行设置,设置了default acl的目录,其目录下的所有新建的文件都会继承该目录的acl规则。
如,我们设置了/tmp/acldir 目录的default acl为用户charlie 只有rw权限:
[root@localhost tmp]# setfacl -d -m u:charlie:rw- /tmp/acldir
[root@localhost tmp]# getfacl /tmp/acldir/
getfacl: Removing leading '/' from absolute path names
# file: tmp/acldir/
# owner: root
# group: root
user::rwx
group::rwx
other::rwx
default:user::rwx
default:user:charlie:rw-
default:group::rwx
default:mask::rwx
default:other::rwx
随后在/tmp/acldir目录下分别创建文件defaultacl和目录defaultacldir,然后查看他们的facl信息:
[root@localhost tmp]# mkdir /tmp/acldir/defaultacldir
[root@localhost tmp]# touch /tmp/acldir/defaultacl
[root@localhost tmp]# getfacl /tmp/acldir/defaultacldir
getfacl: Removing leading '/' from absolute path names
# file: tmp/acldir/defaultacldir
# owner: root
# group: root
user::rwx
user:charlie:rw-
group::rwx
mask::rwx
other::rwx
default:user::rwx
default:user:charlie:rw-
default:group::rwx
default:mask::rwx
default:other::rwx
[root@localhost tmp]# getfacl /tmp/acldir/defaultacl
getfacl: Removing leading '/' from absolute path names
# file: tmp/acldir/defaultacl
# owner: root
# group: root
user::rw-
user:charlie:rw-
group::rwx #effective:rw-
mask::rw-
other::rw-
查看发现创建的文件将/tmp/acldir的default acl 转化为普通的acl条目继承了下来,而创建的目录则两者都继承了下来。
Mask条目
Mask条目是facl访问控制列表的一个关键点,Mask条目规定了ACL用户,用户组及属组所拥有的权限的最大值。如果没有使用--mask 指定mask条目权限,mask条目会自动匹配用户所定义的ACL权限的最大值。
mask条目遵循以下规则:
- 1 . mask条目作用范围为facl列表中的属组、任意用户及用户组条目;
- 2 . mask条目的权限通常与使用者在facl列表中指定的acl条目的最高权限相一致,除非用户指定了mask值。
举个例子:
假如新创建了一个目录/tmp/charlie
[root@localhost tmp]# ll -d /tmp/charlie
drwxr-xr-x. 2 root charlie 6 2月 28 16:57 /tmp/charlie
[root@localhost tmp]# getfacl /tmp/charlie/
getfacl: Removing leading '/' from absolute path names
# file: tmp/charlie/
# owner: root
# group: charlie
user::rwx
group::r-x
other::r-x
其属组为charlie,对应权限为r-x,此时对该目录添加对hadoop用户的facl:
[root@localhost tmp]# setfacl -m u:hadoop:rwx /tmp/charlie/
[root@localhost tmp]# getfacl /tmp/charlie/
getfacl: Removing leading '/' from absolute path names
# file: tmp/charlie/
# owner: root
# group: charlie
user::rwx
user:hadoop:rwx
group::r-x
mask::rwx
other::r-x
添加完成后,/tmp/charlie的facl会自动生成一个mask条目,mask条目自动获取到rwx权限。此时再查看/tmp/charlie的目录信息:
[root@localhost tmp]# ll -d /tmp/charlie
drwxrwxr-x+ 2 root charlie 6 2月 28 16:57 /tmp/charlie
发现/tmp/charlie的属组权限发生变化,属组居然有了w权限了,我们切换到charlie来看看能否在/tmp/charlie目录下创建文件:
[root@localhost tmp]# su - charlie
上一次登录:三 2月 28 16:59:24 CST 2018pts/1 上
您已成功登陆,当前版本Centos 7.2
当前时间: 2018年 02月 28日 星期三 17:30:44 CST
[charlie@localhost ~]$ touch /tmp/charlie/123
touch: 无法创建"/tmp/charlie/123": 权限不够
结果是无法创建,为什么会这样呢?原因是该目录的文件访问控制列表facl具有了mask条目后,文件的属组权限位会被替换成mask条目的权限,并且在权限的最后会增加一个+号,以表明该目录的facl列表包含mask条目,因此上述显示的是mask权限,而不是属组的权限。上述例子中属组的权限依旧是r-w,所以结果是无法在该目录下创建文件或目录咯。我们来修改mask条目的权限验证下结论 :
[root@localhost tmp]# setfacl -m m::r-- /tmp/charlie/
[root@localhost tmp]# getfacl /tmp/charlie/
getfacl: Removing leading '/' from absolute path names
# file: tmp/charlie/
# owner: root
# group: charlie
user::rwx
user:hadoop:rwx #effective:r--
group::r-x #effective:r--
mask::r--
other::r-x
[root@localhost tmp]# ll -d /tmp/charlie/
drwxr--r-x+ 2 root charlie 6 2月 28 16:57 /tmp/charlie/
在修改了mask条目的权限后,ls显示该目录的属组权限也一并变更为r--,验证了我们的结论。
那么mask条目是如何影响用户的权限的呢?我们可以看到上述的例子中,添加了mask条目后,facl列表中的某些ACL条目会多出了#effective:r--的信息,这个就是对应的ACL条目实际的有效权限,是mask权限与acl权限做与运算得出的结果。
(花了几天研究facl列表,整理的有点长,不知道有没有遗漏,如有错误,欢迎指出~)