Linux的ACL配置

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的功能,希望看到的人也自己亲自测试一下,遇到跟着片博客不符的情况可以找资料解决,这样才能进步,才能提升自己的能力。

相关推荐