ACL详解
Linux权限非常的一重要,正常情况下一个文件或目录有三种角色,分别为:目录或文件拥有者(User)、所属群组(Group)、其他用户(Other),每个角色对应:读、写、可执行(rwx)。这也是我们最常见的权限,#ls -l 所看到第一列内容。第一位是文件类型,如 d 是目录、-是普通文件、l 是链接文件、c 是字符文件、b 是块文件等。 剩下9位即是文件对应三种角色的权限。如下图:
![\](http://img3.itokit.com/uploadfile/2011/1019/20111019112525609.jpg)
还会有其它一些特殊权限,如SUID、SGID、 Sticky bit,还有一些需要通过命令lsattr来查看和chattr来设置的隐藏权限。
然而这些权限并没有办法单纯的针对某一用户或群组来设定特定的权限需求。这时候ACL可以帮助我们解决这个问题。
1.什么是ACL?
ACL(Access Control List)即访问控制列表。主要是针对单一用户,单一文件或目录进行rwx权限的细部设定。可以针对用户(User)、群组(Group)、默认属性掩码(umask)进行设置。
2.设置ACL前的准备工作
ACL
是Linux系统权限额外支持的一项功能,需要文件系统的支持,例如:ReiserFS , EXT2 , EXT3 , EXT4 , JFS , XFS等都支持ACL功能。如果你的文件系统支持ACL,接下来查看你的ACL功能是否启用。在RHEL6中查看文件系统是否启用ACL。
(1)使用#mount命令查看ACL
![\](http://img3.itokit.com/uploadfile/2011/1019/20111019112525966.png)
可以看到sda7的ACL已经启用。
(2)启用ACL
如果你想永久在某个partition上启用ACL功能,可以修改 /etc/fstab 。 在rhel6的fstab文件中是用UUID来挂载,所以可以先来确定sda7的UUID号,如下图:
![\](http://img1.itokit.com/uploadfile/2011/1019/20111019112526820.png)
事实上由mount这条命令,你可以知道sda7是挂载在 /data目录。所以在fstab文件中找到挂载在该目录下partition就是一定是sda7了。当然也可以用更加可靠的做法,就是确定这个partition的UUID值。用blkid这条命令查到UUID,再和fstab中比对。
在sda7上启用ACL功能,只需在defaults后加上acl,如下图:
![\](http://img1.itokit.com/uploadfile/2011/1019/20111019112526443.png)
修改完成,保存退出后。重新用mount 命令挂载这个分区。命令如下:
#mount -o remount /dev/sda7
之后再用mount 查看所有已挂载设备,应该能够看 (rw,acl) 字样。
3.ACL
相关设置命令
有以下三条命令:
getfacl
:取得文件或目录的ACL设置信息。
setfac
:设置文件或目录的ACL设置信息。
chacl
:同setfacl,也是用来设定ACL设置信息。用法类似于chmod。不常用。
这里主要介绍getfacl和setfacl命令。
下图是三条命令的man page:
![\](http://img2.itokit.com/uploadfile/2011/1019/20111019112526501.png)
![\](http://img2.itokit.com/uploadfile/2011/1019/20111019112527233.png)
命令常用参数:
基中getfacl与setfacl的参数选项基本相同。
(1)getfacl [-aceEsRLPtpndvh] file...
-a , --access:显示文件或目录的访问控制列表。
-d , --default:显示文件或目录的默认(缺省)的访问控制列表。
-c , --omit-header:不显示默认的访问控制列表。
-R , --recursive:操作递归到子目录。
-t , --tabular:使用列表输格式出ACL设置信息。
-n , --numeric:显示ACL信息中的用户和组的UID和GID。
-p , --absolute-names:
-v , --version:显示命令的版信息
-h , --help:显示命令帮助信息。
(2)setfacl [-bkndRLP] { -m|-M|-x|-X ... } file ...
-m, --modify=acl:修改文件或目录的扩展ACL设置信息。
-M, --modify-file=file:从一个文件读入ACL设置信息并以此为模版修改当前文件或目录的扩展ACL设置信息。
-x, --remove=acl:从文件或目录删除一个扩展的ACL设置信息。
-X, --remove-file=file:从一个文件读入ACL设置信息并以此为模版删除当前文件或目录的ACL设置信息。
-b, --remove-all:删除所有的扩展的ACL设置信息。
-k, --remove-default:删除缺省的acl设置信息。
--set=acl
:设置当前文件的ACL设置信息信息。
--set-file=file
:从文件读入ACL设置信息来设置当前文件或目录的ACL设置信息。
--mask
:重新计算有效权限,即使ACL mask被明确指定。
-n, --no-mask:不要重新计算有效权限。setfacl默认会重新计算ACL mask,除非mask被明确的制定。
-d, --default:设置默认的ACL设置信息(只对目录有效)。
-R, --recursive:操作递归到所有子目录和文件。
-L, --logical:跟踪符号链接,默认情况下只跟踪符号链接文件,跳过符号链接目录。
-P, --physical:跳过所有符号链接,包括符号链接文件。
--restore=file
:从文件恢复备份的acl设置信息(这些文件可由getfacl -R产生<---针对目录)。通过这种机制可以恢复整个目录树的acl设置信息。此参数不能和除--test以外的任何参数一同执行。
--test
:测试模式,不会改变ACL设置信息。
-v, --version:显示程序的版信息。
-h, --help:显示帮助信息。
ACL
设置信息
setfacl
命令可以识别以下的设置信息格式。
setfacl [d[efault]:] [u[ser]:]uid [:perms]:指定用户的权限,文件所有者的权限(如果uid没有指定)。
setfacl [d[efault]:] g[roup]:gid [:perms]:指定群组的权限,文件所有群组的权限(如果gid未指定)
setfacl [d[efault]:] m[ask][:] [:perms]:有效权限掩码
setfacl [d[efault]:] o[ther] [:perms]:其他的权限
3.实例
由于我的sda7这个partition经过上面的动作,已经启用了ACL功能,挂载在 /data目录下。下面所有的动作都是在这个目录下完成。
(1)默认的ACL设置信息
用root在 /data 目录下创建一个acl_test目录。
![\](http://img0.itokit.com/uploadfile/2011/1019/20111019112527757.png)
有没有发现在缺省设置里没有mask这一项,这是因为这个目录还没有设置扩展有ACL设置信息。
注意:
使设置信息能正常执行,需要满足以下条件:
★ 三个基本设置不能被删除。
★ 任何一条包含指定的用户名或群组名的设置信息必须包含有效的权限组合(即rwx的权限组合)。
★ 缺省设置信息必须存在。
由基本设置信息,我们可以知道文件名为 acl_test/ 的拥有者是root用户,所属群组是root组。
由缺省设置信息可知这个目录的权限是755,即只有root用户可读可写,root组和其他用户只有读的权限。
如果我想让 scan这个用户也具有可读可写,怎么办?
(2)针对目录的ACL设置
让scan这个用户对acl_test/ 这个目录可读可写。
了解下设置规范:
setfacl u:[
用户列表]:[rwx] 针对用户的权限规范。
setfacl g:[
群组列表]:[rwx] 针对群组的权限规范。
至于其它人的设置没有意义。
针对scan用户的ACL设置如下图:
![\](http://img3.itokit.com/uploadfile/2011/1019/20111019112527954.png)
可以看到多了一条扩展的ACL设置信息。
注意:多了一个mask:rwx。这是一个权限掩码。用来控制你所设置的扩展ACL权限。你所设置的权限必须存于mask规定的范围内才会生效。也就是所谓的“有效权限(effective permission)”。你可以用getfacl -e命令查看,如下图:
![\](http://img0.itokit.com/uploadfile/2011/1019/20111019112527478.png)
注意:在这里说一下目录的x权限,这个权限必须要有,否则你即使有写的权限,也没有办法进入这个目录。这个权限决定了你是否可以进目录。非常重要!
注意:设置了ACL的目录或文件,在属性的最后一位会出现一个“+”号,如下图:
![\](http://img3.itokit.com/uploadfile/2011/1019/20111019112527722.png)
上面我们知道acl_test/ 这个目录只root用户可读可写,在设置了针对scan用户的ACL信息后,现在我们切换到scan用户看看可不可以进行写操作。如下图:
![\](http://img2.itokit.com/uploadfile/2011/1019/20111019112528683.png)
成功创建一个目录和一个文件。
(3)针对文件的ACL设置
如果是针对一个文件呢?下面我们用root用户在acl_test/目录下创建一个 acl_vim文件。这时候scan用户应该没有写入的权限。如下图:
![\](http://img1.itokit.com/uploadfile/2011/1019/20111019112528234.png)
切换到scan用户试试看。如下图:
![\](http://img0.itokit.com/uploadfile/2011/1019/20111019112528993.png)
没有写入权限。写入的动作被禁止。
下面我们要让scan用户对这个文件有写入的权限,所以我们来针对scan用户设置acl_vim文件的acl信息,如下图:
![\](http://img1.itokit.com/uploadfile/2011/1019/20111019112528905.png)
我们通过ACL设置信息,让scan这个用户具有对acl_vim文件读和写的权限。现在我们来切换到scan用户验证一下,如下图:
![\](http://img2.itokit.com/uploadfile/2011/1019/20111019112528834.png)
验证成功。也可以发现在文件属性的权限最后一位也有一个“+”号。
(4)针对有效权限mask的设定
设定规范:
setfacl m:[rwx]
或
setfacl m::[rwx]
设定acl_test/ 目录的有效权限为mask:r。如下图:
![\](http://img2.itokit.com/uploadfile/2011/1019/20111019112529181.png)
我们可以看到scan用户的有效权限变为r。包括group。
那么这时候scan用户对acl_test/ 这个目录还有没有写入权限。下面验证一下,如下图:
![\](http://img3.itokit.com/uploadfile/2011/1019/20111019112529768.png)
由于scan用户在这个目录上没有x权限,所以连这个目录都不能进入,尽管我们已经赋予scan用户rwx的ACL设置信息。最终权限由mask控制,你所设置的权限必须在mask内,否则相对mask多出来的权限也是无效的。
下面把mask改为原来的rwx。如下图:
![\](http://img2.itokit.com/uploadfile/2011/1019/20111019112529428.png)
这个时候scan用户就可以对这个目录写入了。上面的写入操作都可以实现了。
注意:如果setfacl命令不指定操作用户,那么就是对默认属主用户权限的操作(例如acl_test/目录,owner:root,group:root),这时候的setfacl命令功能上和传统的chmod相同。例如setfacl u::rwx,g::rwx,o::rwx acl_test/ 等价于chmod 777 acl_test/ 。就是把缺省设置信息全部设置为rwx的权限了。
(5)针对预设权限的设定
我在设置了acl_test/ 目录的ACL后,在这个目录下再创建目录和文件时,并没有继承上层目录acl_test/ 的ACL设置信息。如下图:
![\](http://img0.itokit.com/uploadfile/2011/1019/20111019112529296.png)
之前我们在acl_test/ 目录下创建了scan/ 目录和scan_test文件用于验证acl_test/ 这个目录scan用户的ACL设置信息。所以可以看到它们的用户和组都为scan。而acl_vim是在上面步骤中用于验证文件上的ACL设置信息的设定。
可以看到目录scan/ 和文件scan_test 并没有继承上层acl_test/ 目录的ACL设置信息。
设置规范:
setfacl -d -m [ug]:
列表:[rwx] 目录 (注意:-d参数必须放在最前面。)
setfacl -d --set [ug]:列表:[rwx] 目录 (注意:-d参数必须放在最前面。)
setfacl -m d:[ug]:列表:[rwx] 目录
让acl_test/ 这个目录下的所有文件和目录继承acl_test/ 目录的ACL设置信息。如下图:
![\](http://img0.itokit.com/uploadfile/2011/1019/20111019112530116.png)
下面我们切换到scan用户验证一下在acl_test/目录下创建目录和文件能不能继承acl_test/这个目录的ACL设置信息。如下图:
![\](http://img0.itokit.com/uploadfile/2011/1019/20111019112530509.png)
可以看到目录scan_1/和文件scan_test_1已经继承了上层acl_test/目录的ACL设置信息。在权限的最后一位都有个“+”号。
注意:当然文件和目录的继承又会有一些差异。因为文件不像目录,目录的下层可再创建文件和目录,所以目录在继承上层目录的ACL设置信息时,会保证在它下层的目录和文件仍可以继承它的ACL设置信息。所以它要完全继承上层目录的ACL设置信息。而文件不需要继承这些设置信息。所以对于文件来说仅会继承scan用户这条ACL设置信息即可,而LINUX系统中的文件默认是不允许有x权限的。所以尽管scan用户有rwx的权限,但是mask为rw,所以有scan用户对该文件的有效权限仅有rw的权限。
(6)setfacl其它一些操作
setfacl -x [ug]:用户或级列表 文件或目录:删除特定用户或组在相关文件或目录上的ACL设置。
setfacl -b
文件或目录 :删除文件或目录上所有的ACL设置。
注意:加上 -R 参数可以对目录递归处理。
注意:cp和mv命令对于ACL的支持,mv命令保持ACL设置信息,cp命令在使用-p,-a参数时保留ACL设置信息。但是如果从一个支持ACL的文件系统向一个不支持ACL的文件系统移动或带ACL属性的拷贝,则会得到类似下面这样的错误提示,cp: preserving permissions for `filename’: Operation not supported
删除acl_test目录下acl_vim文件的ACL设置信息,如下图:
![\](http://img2.itokit.com/uploadfile/2011/1019/20111019112530987.png)
删除acl_test/目录下scan_1/目录的ACL设置信息,如下图:
![\](http://img2.itokit.com/uploadfile/2011/1019/20111019112530703.png)
备份和恢复ACL设置信息
备份和恢复scan_test_1文件的ACL设置信息,如下图:
![\](http://img1.itokit.com/uploadfile/2011/1019/20111019112531522.png)