在Linux系统中,如果有这样一个文件,或者说文件夹,对应的owner属于A,对应的group属于B,那么如何让一个既不是用户A,又不在group B的人访问、读写这个文件、文件夹呢?你可能会说,开放777权限,那我可以很确定的告诉你,那样很不好,会让所有不相干的用户获取所有的权限。为了灵活的配置权限,acl,即所谓的访问控制列表,可以灵活的运用起来。
Linux配置ACL主要涉及两条命令,getfacl和setfacl,从字面意思你也可以看出来,一个是查看acl权限的,一个是设置acl权限的,分工明确。
先看一下getfacl的使用:
getfacl -h
Usage: getfacl [-aceEsRLPtpndvh] file …
-a, –access display the file access control list only
-d, –default display the default access control list only
-c, –omit-header do not display the comment header
-e, –all-effective print all effective rights
-E, –no-effective print no effective rights
-s, –skip-base skip files that only have the base entries
-R, –recursive recurse into subdirectories
-L, –logical logical walk, follow symbolic links
-P, –physical physical walk, do not follow symbolic links
-t, –tabular use tabular output format
-n, –numeric print numeric user/group identifiers
-p, –absolute-names don’t strip leading ‘/’ in pathnames
-v, –version print version and exit
-h, –help this help text
通常的输入时这样的:
The output format of getfacl is as follows:
1: # file: somedir/
2: # owner: lisa
3: # group: staff
4: # flags: -s-
5: user::rwx
6: user:joe:rwx #effective:r-x
7: group::rwx #effective:r-x
8: group:cool:r-x
9: mask::r-x
10: other::r-x
11: default:user::rwx
12: default:user:joe:rwx #effective:r-x
13: default:group::r-x
14: default:mask::r-x
15: default:other::—
1,2,3显示的是文件名及所属用户,所属组。4显示的是特殊权限,如果此文件、目录没有设置过特殊权限,则不会显示这行。
5,7,10显示的是此文件本身的用户、组、和其他的权限,这三条称为基础acl条目(the base ACL entries)。6,8为额外的用户和组的相应的acl权限;9为有效权限,这条限制了所有组和额外用户的权限范围,也就是说所有组和额外用户的最大权限只能是mask的一个子集,例如mask最大权限是rx,则所有组和额外用户的权限只能是小于等于rx的,即使你设定了rwx,也是无效的;11-15显示的是目录的默认的acl权限,这个默认acl权限只针对目录,普通文件没有默认acl。
getfacl的最后如果是一个横杠dash“-”结尾,则表示getfacl从标准输入中读取一个文件列表来展示acl权限。
getfacl的头三行属于基础权限,很多时候是无用的,我们可以用getfacl –omit-header 把这三行忽略。
setfacl用法:
setfacl -h
Usage: setfacl [-bkndRLP] { -m|-M|-x|-X … } file …
-m, –modify=acl modify the current ACL(s) of file(s)
-M, –modify-file=file read ACL entries to modify from file
-x, –remove=acl remove entries from the ACL(s) of file(s)
-X, –remove-file=file read ACL entries to remove from file
-b, –remove-all remove all extended ACL entries
-k, –remove-default remove the default ACL
–set=acl set the ACL of file(s), replacing the current ACL
–set-file=file read ACL entries to set from file
–mask do recalculate the effective rights mask
-n, –no-mask don’t recalculate the effective rights mask
-d, –default operations apply to the default ACL
-R, –recursive recurse into subdirectories
-L, –logical logical walk, follow symbolic links
-P, –physical physical walk, do not follow symbolic links
–restore=file restore ACLs (inverse of `getfacl -R’)
–test test mode (ACLs are not modified)
-v, –version print version and exit
-h, –help this help text
setfacl [-bkndRLPvh] [{-m|-x} acl_spec] [{-M|-X} acl_file] file …
setfacl –restore=file
需要注意的是,getfacl后面可以跟一队的命令再接上一队的目录,不是一次只能执行单个目标的acl设置。
-m和-x后面接上acl规则,多个规则用逗号“,”隔开,-M和-X从文件或者标准输入中读取acl规则。
–set 和 –set-file会替换文件和目录之前的acl规则,-m (–modify) and -M (–modify-file)用户修改acl规则,-x (–remove) and -X (–remove-file)用于删除acl规则。
在现代的linux系统中,通常只有文件的所有者和root可以设置对应文件的acl。
一些示例:
Granting an additional user read access
setfacl -m u:lisa:r file
Revoking write access from all groups and all named users (using the effective rights mask)
setfacl -m m::rx file
Removing a named group entry from a file’s ACL
setfacl -x g:staff file
Copying the ACL of one file to another
getfacl file1 | setfacl –set-file=- file2
Copying the access ACL into the Default ACL
getfacl –access dir | setfacl -d -M- dir
acl权限递归设置
当我们需要对子目录设置相应的acl权限时,我们该怎么做呢,我的思路一开始是这样的:
find -type d -exec setfacl -m u:alice:rwx {} \;
find -type f -executable -exec setfacl -m u:alice:rwx {} \;
find -type f \! -executable -exec setfacl -m u:alice:rw {} \;
这种写法通常在一些脚本中使用,显得很复杂,其实我们有更好的解决方案。
setfacl -R -m u:colleague:rwX .
注意,此处的大写的X表示,只有当目标是目录,或者文件本身有执行权限是,才给予执行权限,普通文件一律没有x执行权限。
这里需要重点讲一下ACL_MASK,因为这是掌握ACL的另一个关键,在Linux file permission里面大家都知道比如对于rw-rw-r–来说, 当中的那个rw-是指文件组的permission. 但是在ACL里面这种情况只是在ACL_MASK不存在的情况下成立。如果文件有ACL_MASK值,那么当中那个rw-代表的就是mask值而不再是group permission了。
另外mask是指定额外用户和组的最大权限的,并不是说额外用户和组一定就是mask的权限!