lfjjia 2015-07-05
一、为什么要使用ACL
首先,在linux下,对一个文件可以进行的操作的对象分别为user(文件的拥有者),group(组,注意不一定是文件拥有者所在的组),other(其他)而对于每一对象的操作又有了读写执行(这里不讨论SUID,SGID以及Stickybit的设置)
通过ls-l命令就我们就可以列出一个文件的权限(看一下就行了,不需要操作)
代码:
[leonard@localhost~]$ls-l
-rw-rw----1leonardadmin0Jul320:12test.txt
在这里说明了对于test.txt这个文件leonard用户(user)拥有read&write权限.所有属于admin组的用户(group)拥有read&write权限.其他任何用户(other)
对于文件没有任何的权限
如果我们现在希望john这个用户也可以对test.txt文件进行读写操作.我自己大概会想到以下几种办法(这里假设john不属于admin组)
1.给文件的other类别增加读和写的权限.这样由于john会被归为other类别,那么他也将拥有读写的权限。
2.将john加入到admingroup.那么john会被归为group类别,那么他将拥有读写的权限。
第一种做法的问题在于所有用户都将对test.txt拥有读写操作,显然这种做法不可取
第二种做法的问题在于john被赋予了过多的权限.所有属于admin组的文件,john都可以拥有其等同的权限了。
对于以上不安全的情况,我们可以用Linux的AccessControlList(ACL)来帮助我们解决当然,要讨论ACL你必须要安装上ACL的RPM包,而且,在安装完成后,还要磁盘分区的支持。
以我为例,我的分区默认并没有支持ACL功能,如果要让分区支持ACL,有以下几种办法:
1.使用tune2fs命令让分区永久支持ACL功能语法:tune2fs-oacl分区
如:[root@localhost~]#tune2fs-oacl/dev/sda2#如果不知道目录所在的分区,可以看我的一篇相关文章
tune2fs1.41.12(17-May-2010)http://blog.chinaunix.net/uid-30212356-id-5077530.html
配置完成后,可以通过tune2fs-l分区查看,如我的:
[root@localhost~]#tune2fs-l/dev/sda2
tune2fs1.41.12(17-May-2010)
Filesystemvolumename:
Lastmountedon:/
FilesystemUUID:eafb2027-525e-4a4d-8df7-f7123a9fe637
Filesystemmagicnumber:0xEF53
Filesystemrevision#:1(dynamic)
Filesystemfeatures:has_journalext_attrresize_inodedir_indexfiletypeneeds_recoveryextentflex_bgsparse_superlarge_filehuge_fileuninit_bgdir_nlinkextra_isize
Filesystemflags:signed_directory_hash
#在“Defaultmountoptions:”的值中包括“acl”就说明该分区支持ACL功能。
Defaultmountoptions:user_xattracl
Filesystemstate:clean
Errorsbehavior:Continue
FilesystemOStype:Linux............
2.使用mount命令让分区临时支持ACL功能(重启开机后ACL失效)
mount-oremount分区或者mount-oacl分区挂载点
注意:使用mount命令让一个分区临时支持ACL功能时,可以使用以上二种方式。第一种使用在分区已经被挂载的情况,也就是说这个分区已经在使用但还不支持ACL功能,在不影响分区使用的情况下重新挂载分区使其支持ACL功能;第二种使用在一开始挂载分区时就使其支持ACL功能。
[root@srv~]#mount-oremount/dev/sda13
[root@srv~]#mount-oacl/dev/sda14/media/sda14(此为引用,我没有再去试验)
[root@srv~]#mount#使用mount命令查看。
#如果分区支持ACL功能时,在挂载信息中会显示出来。
/dev/sda13on/media/sda13typeext3(rw,acl)
/dev/sda14on/media/sda14typeext3(rw,acl)
3.修改/etc/fstab文件,使分区永久支持ACL功能。在/etc/fstab文件中在需要支持ACL功能分区的挂载选项列中加上“,acl”即可使分区永久支持ACL功能。(这里是引用的,懒,没测试)
如:[root@srv~]#cat/etc/fstab
LABEL=SWAP-sda9
swap
swap
defaults
00
/dev/sda10
/media/sda10
ext3
defaults,acl
00
在启用了acl参数之后重新加载/data分区
#mount-oremount分区即可!
提示:通过tune2fs命令使分区支持ACL功能后,通过mount命令是无法查看到的,通过修改/etc/fstab使分区支持ACL功能后,通过mount命令可以查看到分区支持ACL功能
二:ACL的名词定义
ACL是由一系列的AccessEntry所组成的.每一条AccessEntry定义了特定的类别可以对文件拥有的操作权限.AccessEntry有三个组成部分:Entrytagtype,qualifier,(optional),权限
我们先来看一下最重要的Entrytagtype,它有以下几个类型
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里other的权限
举个例子说明一下吧.下面我们就用getfacl命令来查看一个已经定义好了的ACL文件
[root@zyq-serverdata]#getfacltest.txt
#file:test.txt
#owner:root
#group:family
user::rw-
user:zyq:rw-
group::rw-
group:jackuser:rw-
mask::rw-
other::---
前面三个以#开头的定义了文件名,文件所有者和文件拥有组.这些信息没有太大的作用,我们可以用--omit-header参数(即getfacl-ctset.txt命令)来省略掉
user::rw-定义了ACL_USER_OBJ,说明文件拥有者拥有读和写的权限
user:zyq:rw-定义了ACL_USER,这样用户zyq就拥有了对文件的读写权限
group::rw-定义了ACL_GROUP_OBJ,说明文件的group拥有read和write权限
group:jackuser:rw-定义了ACL_GROUP,使得jackuser组拥有了对文件的read和write权限
mask::rw-定义了ACL_MASK的权限为readandwrite
other::---定义了ACL_OTHER的没有任何权限操作此文件
从这里我们就可以看出ACL提供了我们可以定义特定用户和用户组具有对文件的具体功能;
三、如何设置ACL文件
首先我们讲一下设置ACL文件的格式.从上面的例子中我们可以看到每一个AccessEntry都是由三个:号分隔开的字段所组成.
第一个就是Entrytagtype
user对应了ACL_USER_OBJ和ACL_USER
group对应了ACL_GROUP_OBJ和ACL_GROUP
mask对应了ACL_MASK
other对应了ACL_OTHER
第二个字段称之为qualifier.也就是上面例子中的zyq和jackuser组.它定义了特定用户和用户组
对于文件的权限.这里我们也可以发现只有user和group才有qualifier,其他的都为空
第三个字段就是我们熟悉的权限了.它和Linux的权限一样定义,这里就不多讲了
一开始文件没有ACL的额外属性
[root@localhostmnt]#ll
总用量4
drwxr-xr-x.2rootroot40963月1407:00hgfs
-rw-r--r--1rootroot06月1005:50test.txt
[root@zyq-serverdata]#getfacltest.txt
#file:test.txt
#owner:root
#group:root
user::rw-
group::r--
other::r--
我们先让用户abc拥有对test.txt文件的读写权限
[root@localhostmnt]#setfacl-mu:abc:rwtest.txt
[root@localhostmnt]#getfacl-ctest.txt
user::rw-
user:abc:rw-
group::r--
mask::rw-
other::r--
这时我们就可以看到abc用户在ACL里面已经拥有了对文件的读写权限.这个时候如果我们查看一下linux的权限我们还会发现一个不一样的地方
[root@localhostmnt]#ll
总用量4
drwxr-xr-x.2rootroot40963月1407:00hgfs
-rw-rw-r--+1rootroot06月1005:50test.txt
在文件权限的最后多了一个+号.当任何一个文件拥有了ACL_USER或者ACL_GROUP的值以后,我们就可以称它为ACL文件.这个+号就是用来提示我们的.
我们还可以发现当一个文件拥有了ACL_USER或者ACL_GROUP的值时ACL_MASK同时也会被定义;
接下来我们来设置ABC组拥有read权限
[root@localhostmnt]#setfacl-mg:ABC:rtest.txt
[root@localhostmnt]#getfacl-ctest.txt
user::rw-
user:abc:rw-
group::r--
group:ABC:r--
mask::rw-
other::r--
[root@localhostmnt]#setfacl-mg:ABC:rtest.txt
[root@localhostmnt]#getfacl-ctest.txt
user::rw-
user:abc:rw-
group::r--
group:ABC:r--
mask::rw-
other::r--
[root@localhostmnt]#setfacl-mg:ABC:rtest.txt
[root@localhostmnt]#getfacl-ctest.txt
user::rw-
user:abc:rw-
group::r--
group:ABC:r--
mask::rw-
other::r--
[root@localhostmnt]#setfacl-mg:ABC:rtest.txt
[root@localhostmnt]#getfacl-ctest.txt
user::rw-
user:abc:rw-
group::r--
group:ABC:r--
mask::rw-
other::r--
[root@localhostmnt]#lltest.txt
-rw-rw-r--+1rootroot06月1005:50test.txt
四、ACL_MASK和Effective权限
这里需要重点讲一下ACL_MASK,因为这是掌握ACL的另一个关键
在Linux文件权限里面大家都知道比如对于rw-rw-r--来说,第二组中的那个rw-是指文件组的权限.但是在ACL里面这种情况只是在ACL_MASK不存在的情况下成立.如果文件有ACL_MASK值,那么当中那个rw-代表的就是mask值而不再是group权限了;
例如:[root@localhostmnt]#lltest.sh
-rwxrw-r--1rootfamily16月1006:28test.sh
这里说明test.sh文件只有文件拥有者root拥有read,write,execute权限.family
组只有读和写的权限。现在我们想让用户abc也对test.sh具有和root一样的权限。
[root@localhostmnt]#setfacl-mu:abc:rwxtest.sh
[root@localhostmnt]#getfacl-ctest.sh
user::rwx
user:abc:rwx
group::rw-
mask::rwx
other::r--
这里我们看到abc已经拥有了rwx的权限.mask值也被设定为rwx.那是因为它规定了ACL_USER,ACL_GROUP和ACL_GROUP_OBJ的最大值(也就是权限的最大值)
现在我们再来看test.sh的Linux权限,它已经变成了
[root@localhostmnt]#lltest.sh
-rwxrwxr--+1rootfamily16月1006:28test.sh
那么如果现在family组的用户想要执行test.sh的程序会发生什么情况呢?它会被权限deny.原因在于实际上family组的用户只有读和写的权限.这里当中显示的rwx是ACL_MASK的值而不是group的权限
所以从这里我们就可以知道,如果一个文件后面有+标记,我们都需要用getfacl来确认它的权限,以免发生混淆
下面我们再来继续看一个例子
假如现在我们设置test.sh的mask为readonly,那么family组的用户还会有write权限吗?
[root@localhostmnt]#setfacl-mmask::rtest.sh
[root@localhostmnt]#getfacl-ctest.sh
user::rwx
user:abc: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的最大权限.那么在我们这个例子中他们的最大权限也就是readonly.虽然我们这里给ACL_USER和ACL_GROUP_OBJ设置了其他权限,但是他们真正有效果的只有read权限也就是mask的权限.
这时我们再来查看test.sh的Linux文件权限时它的group权限也会显示其mask的值
[root@localhostmnt]#lltest.sh
-rwxr--r--+1rootfamily16月1006:28test.sh
五、DefaultACL
上面我们所有讲的都是AccessACL,也就是对文件而言.下面讲的是DefaultACL.,DefaultACL是指对于一个目录进行DefaultACL设置,并且在此目录下建立的文件都将继承此目录的ACL
我希望所有在此目录下建立的文件都可以被smbuser用户所访问.那么我们就应该对mydir目录设置DefaultACL
首先利用root用户在/mnt/创建一个dir的文件夹,然后将这个文件夹的defaultuser权限设置为smbuser可以rw-
以root身份在dir目录下创建一个test.txt的文件。其他的不做限制,然后切换到smbuser。发现smbuser用户可以修改test.txt文件中的内容但是无法在dir目录中创建和删除文件/文件夹
[root@localhostmnt]#mkdirdir
[root@localhostmnt]#id
uid=0(root)gid=0(root)groups=0(root)
[root@localhostmnt]#lldir/
total0
[root@localhostmnt]#getfacldir
#file:dir
#owner:root
#group:root
user::rwx
group::r-x
other::r-x
[root@localhostmnt]#setfacl-md:smbuser:rwdir/
[root@localhostmnt]#getfacldir/
#file:dir/
#owner:root
#group:root
user::rwx
group::r-x
other::r-x
default:user::rwx
default:user:smbuser:rw-
default:group::r-x
default:mask::rwx
default:other::r-x
此时我们可以看到ACL定义了default选项,smbuser用户拥有了default的read,write,excute/search权限.但是却无法删除和创建文件,这里还必须将mydir目录的ACL_USER修改为smbuser后,切换到smbuser用户才能够在mydir目录中创建和删除文件/文件夹
[root@localhostmnt]#setfacl-mu:smbuser:rwxdir/
[root@localhostmnt]#getfacl-cdir/
user::rwx
user:smbuser:rwx
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:smbuser:rw-
default:group::r-x
default:mask::rwx
default:other::r-x
此时测试
[root@localhostmnt]#cddir/
[root@localhostdir]#touchtest.txt
[root@localhostmnt]#cddir/
[root@localhostdir]#su-smbuser
[smbuser@localhost~]$cd/mnt/dir/
[smbuser@localhostdir]$toucha
[smbuser@localhostdir]$ll
total0
-rw-rw-r--+1smbusersmbuser0Jun1007:38a
-rw-rw-r--+1rootroot0Jun1007:34test.txt
[smbuser@localhostdir]$rm*-rf
[smbuser@localhostdir]$
下面的试验我们看到在dir下建立的文件或文件夹都自动的加上了default的权限
[smbuser@localhostdir]$touchtest.txt
[smbuser@localhostdir]$getfacltest.txt
#file:test.txt
#owner:smbuser
#group:smbuser
user::rw-
user:smbuser:rw-
group::r-x#effective:r--
mask::rw-
other::r--
[smbuser@localhostdir]$mkdirtestdir
[smbuser@localhostdir]$getfacltestdir/
#file:testdir/
#owner:smbuser
#group:smbuser
user::rwx
user:smbuser:rw-
group::r-x
mask::rwx
other::r-x
default:user::rwx
default:user:smbuser:rw-
default:group::r-x
default:mask::rwx
default:other::r-x
[smbuser@localhostdir]$ll
total4
drwxrwxr-x+2smbusersmbuser4096Jun1007:43testdir
-rw-rw-r--+1smbusersmbuser0Jun1007:41test.txt
六:总结
从上面的例子可以看到,getfacl命令是用来读取文件的ACL,setfacl是用来设定文件的AcessACL.这里还有一个chacl是用来改变文件和目录的AccessACLandDefaultACL.他的用法很多,这里只提及一下chacl-B.它可以彻底删除文件或者目录的ACL属性(包括DefaultACL).比如你即使用了setfacl-x删除了所有文件的ACL属性,那个+号还是会出现在文件的末尾.所以正确的删除方法应该是用chacl-B
用cp来复制文件的时候我们现在可以加上-p选项.这样在拷贝文件的时候也将拷贝文件的ACL属性.对于不能拷贝的ACL属性将给出警告
mv命令将会默认地移动文件的ACL属性.同样如果操作不允许的情况下会给出警告
如果用chmod命令改变Linux文件权限的时候相应的ACL值也会改变.反之改变ACL的值,相应的文件权限也会改变
这篇博客我先看了几篇相关内容,然后自己动手又做了完整的测试,已经实现了ACL的功能,希望看到的人也自己亲自测试一下,遇到跟着片博客不符的情况可以找资料解决,这样才能进步,才能提升自己的能力。