Chinaunix首页 | 论坛 | 博客
  • 博客访问: 631009
  • 博文数量: 244
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-27 09:53
个人简介

记录学习,记录成长

文章分类

全部博文(244)

我的朋友

分类: LINUX

2015-06-10 23:12:18

一、 为什么要使用ACL

首先,在 linux下,对一个文件可以进行的操作的对象分别为user(文件的拥有者),group(组,注意不一定是文件拥有者所在的组), other (其他)而对于每一对象的操作又有了读  写  执行 (这里不讨论SUID, SGID以及Sticky bit的设置)

通过ls -l命令就我们就可以列出一个文件的权限(看一下就行了,不需要操作)

代码:
[leonard@localhost ~]$ ls -l
-rw-rw---- 1 leonard admin 0 Jul 3 20:12 test.txt


在这里说明了对于test.txt这个文件leonard用户(user)拥有read & write权限. 所有属于admin 组的用户(group)拥有read & write 权限. 其他任何用户(other)
对于文件没有任何的权限

如果我们现在希望john这个用户也可以对test.txt文件进行读写操作. 我自己大概会想到以下几种办法 (这里假设john不属于admin组)

1. 给文件的other类别增加读和写的权限. 这样由于john会被归为other类别,那么他也将拥有读写的权限。

2. 将john加入到admin group. 那么john会被归为group类别,那么他将拥有读写的权限。

第一种做法的问题在于所有用户都将对test.txt拥有读写操作,显然这种做法不可取

第二种做法的问题在于john被赋予了过多的权限.所有属于admin组的文件,john都可以拥有其等同的权限了。

 对于以上不安全的情况,我们可以用Linux的Access Control List (ACL)来帮助我们解决当然,要讨论ACL你必须要安装上ACL的RPM包,而且,在安装完成后,还要磁盘分区的支持。

以我为例,我的分区默认并没有支持ACL功能,如果要让分区支持ACL,有以下几种办法:

1.使用tune2fs命令让分区永久支持ACL功能             语法: tune2fs  -o  acl  分区
如:[root@localhost ~]# tune2fs -o acl /dev/sda2         #如果不知道目录所在的分区,可以看我的一篇相关文章
      tune2fs 1.41.12 (17-May-2010)                              http://blog.chinaunix.net/uid-30212356-id-5077530.html

配置完成后,可以通过tune2fs  -l  分区     查看,如我的:
[root@localhost ~]# tune2fs -l /dev/sda2
tune2fs 1.41.12 (17-May-2010)
Filesystem volume name:  
Last mounted on:          /
Filesystem UUID:          eafb2027-525e-4a4d-8df7-f7123a9fe637
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
#在“Default mount options:”的值中包括“acl”就说明该分区支持ACL功能
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux............

2.使用mount命令让分区临时支持ACL功能(重启开机后ACL失效)

mount   -o    remount    分区     或者        mount    -o    acl    分区    挂载点
注意:使用mount命令让一个分区临时支持ACL功能时,可以使用以上二种方式。第一种使用在分区已经被挂载的情况,也就是说这个分区已经在使用但还不支持ACL功能,在不影响分区使用的情况下重新挂载分区使其支持ACL功能;第二种使用在一开始挂载分区时就使其支持ACL功能。
[root@srv ~]# mount -o remount /dev/sda13
[root@srv ~]# mount -o acl  /dev/sda14  /media/sda14(此为引用,我没有再去试验)
[root@srv ~]# mount   #使用mount命令查看。
#如果分区支持ACL功能时,在挂载信息中会显示出来。
/dev/sda13 on /media/sda13 type ext3 (rw,acl)
/dev/sda14 on /media/sda14 type ext3 (rw,acl)
3.修改/etc/fstab文件,使分区永久支持ACL功能。在/etc/fstab文件中在需要支持ACL功能分区的挂载选项列中加上“,acl”即可使分区永久支持ACL功能。(这里是引用的,懒,没测试)
如:[root@srv ~]# cat /etc/fstab
LABEL=SWAP-sda9
swap                   
swap                   
defaults       
0 0
/dev/sda10
/media/sda10
ext3   
defaults,acl
0 0
在启用了acl参数之后重新加载/data分区
# mount -o remount   分区            即可!
提示:通过tune2fs命令使分区支持ACL功能后,通过mount命令是无法查看到的,通过修改/etc/fstab使分区支持ACL功能后,通过mount命令可以查看到分区支持ACL功能
二:ACL的名词定义
ACL 是由一系列的Access Entry所组成的. 每一条Access Entry定义了特定的类别可以对文件拥有的操作权限. Access Entry有三个组成部分: Entry tag type, qualifier ,(optional), 权限
我们先来看一下最重要的Entry tag type, 它有以下几个类型

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-server data]# getfacl test.txt              
# file: test.txt
# owner: root
# group: family
user::rw-
user:zyq:rw-
group::rw-
group:jackuser:rw-
mask::rw-
other::---
前面三个以#开头的定义了文件名,文件所有者和文件拥有组. 这些信息没有太大的作用,我们可以用 --omit-header参数(即getfacl -c tset.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的权限为read and write
other::--- 定义了ACL_OTHER的没有任何权限操作此文件
从这里我们就可以看出ACL提供了我们可以定义特定用户和用户组具有对文件的具体功能;

三、 如何设置ACL文件
首先我们讲一下设置ACL文件的格式. 从上面的例子中我们可以看到每一个Access Entry都是由三个:号分隔开的字段所组成. 
第一个就是Entry tag type
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@localhost mnt]# ll
总用量 4
drwxr-xr-x. 2 root root 4096 3月  14 07:00 hgfs
-rw-r--r--  1 root root    0 6月  10 05:50 test.txt
[root@zyq-server data]# getfacl test.txt                   
# file: test.txt
# owner: root
# group: root
user::rw-
group::r--
other::r--
我们先让用户abc拥有对test.txt文件的读写权限
[root@localhost mnt]# setfacl -m u:abc:rw test.txt 
[root@localhost mnt]# getfacl -c test.txt 
user::rw-
user:abc:rw-
group::r--
mask::rw-
other::r--
这时我们就可以看到abc用户在ACL里面已经拥有了对文件的读写权限. 这个时候如果我们查看一下linux的权限我们还会发现一个不一样的地方
[root@localhost mnt]# ll
总用量 4
drwxr-xr-x. 2 root root 4096 3月  14 07:00 hgfs
-rw-rw-r--+ 1 root root    0 6月  10 05:50 test.txt
在文件权限的最后多了一个+号. 当任何一个文件拥有了ACL_USER或者ACL_GROUP的值以后,我们就可以称它为ACL文件.这个+号就是用来提示我们的.
我们还可以发现当一个文件拥有了ACL_USER或者ACL_GROUP的值时ACL_MASK同时也会被定义;
接下来我们来设置ABC组拥有read 权限
[root@localhost mnt]# setfacl -m g:ABC:r test.txt 
[root@localhost mnt]# getfacl -c test.txt 
user::rw-
user:abc:rw-
group::r--
group:ABC:r--
mask::rw-
other::r--

[root@localhost mnt]# setfacl -m g:ABC:r test.txt 
[root@localhost mnt]# getfacl -c test.txt 
user::rw-
user:abc:rw-
group::r--
group:ABC:r--
mask::rw-
other::r--

[root@localhost mnt]# setfacl -m g:ABC:r test.txt 
[root@localhost mnt]# getfacl -c test.txt 
user::rw-
user:abc:rw-
group::r--
group:ABC:r--
mask::rw-
other::r--

[root@localhost mnt]# setfacl -m g:ABC:r test.txt 
[root@localhost mnt]# getfacl -c test.txt 
user::rw-
user:abc:rw-
group::r--
group:ABC:r--
mask::rw-
other::r--

[root@localhost mnt]# ll test.txt 
-rw-rw-r--+ 1 root root 0 6月  10 05:50 test.txt


四、ACL_MASK 和 Effective 权限
这里需要重点讲一下ACL_MASK, 因为这是掌握ACL的另一个关键
在Linux 文件权限里面大家都知道比如对于rw-rw-r--来说, 第二组中的那个rw-是指文件组的权限. 但是在ACL里面这种情况只是在ACL_MASK不存在的情况下成立. 如果文件有ACL_MASK值,那么当中那个rw-代表的就是mask值而不再是group 权限了;
例如:[root@localhost mnt]# ll test.sh 
         -rwxrw-r-- 1 root family 1 6月  10 06:28 test.sh

这里说明test.sh文件只有文件拥有者 root拥有read, write, execute 权限. family
组只有读和写的权限。现在我们想让用户abc也对test.sh具有和root一样的权限。
[root@localhost mnt]# setfacl -m u:abc:rwx test.sh 
[root@localhost mnt]# getfacl -c test.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@localhost mnt]# ll test.sh 
-rwxrwxr--+ 1 root family 1 6月  10 06:28 test.sh

那么如果现在family组的用户想要执行test.sh的程序会发生什么情况呢? 它会被权限 deny.原因在于实际上family组的用户只有读和写的权限.这里当中显示的rwx是ACL_MASK的值而不是group的权限
所以从这里我们就可以知道,如果一个文件后面有+标记,我们都需要用getfacl来确认它的权限,以免发生混淆
下面我们再来继续看一个例子
假如现在我们设置test.sh的mask为read only,那么family组的用户还会有write 权限吗?
[root@localhost mnt]# setfacl -m mask::r test.sh 
[root@localhost mnt]# getfacl -c test.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的最大权限.那么在我们这个例子中他们的最大权限也就是read only.虽然我们这里给ACL_USER和ACL_GROUP_OBJ设置了其他权限,但是他们真正有效果的只有read权限也就是mask的权限.

这时我们再来查看test.sh的Linux 文件权限时它的group 权限也会显示其mask的值
[root@localhost mnt]# ll test.sh 
-rwxr--r--+ 1 root family 1 6月  10 06:28 test.sh


五、 Default ACL
上面我们所有讲的都是Access ACL, 也就是对文件而言. 下面讲的是Default ACL.,Default ACL是指对于一个目录进行Default ACL设置,并且在此目录下建立的文件都将继承此目录的ACL

我希望所有在此目录下建立的文件都可以被smbuser用户所访问. 那么我们就应该对mydir目录设置Default ACL

首先利用root用户在/mnt/创建一个dir的文件夹,然后将这个文件夹的default user权限设置为smbuser可以rw-
以root身份在dir目录下创建一个test.txt的文件。其他的不做限制,然后切换到smbuser。发现smbuser用户可以修改 test.txt文件中的内容但是无法在dir目录中创建和删除文件/文件夹
[root@localhost mnt]# mkdir dir

[root@localhost mnt]# id 
uid=0(root) gid=0(root) groups=0(root)

[root@localhost mnt]# ll dir/
total 0

[root@localhost mnt]# getfacl dir
# file: dir
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

[root@localhost mnt]# setfacl -m d:smbuser:rw dir/

[root@localhost mnt]# getfacl dir/
# 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@localhost mnt]# setfacl -m u:smbuser:rwx dir/

[root@localhost mnt]# getfacl -c dir/
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@localhost mnt]# cd dir/

[root@localhost dir]# touch test.txt

[root@localhost mnt]# cd dir/

[root@localhost dir]# su - smbuser

[smbuser@localhost ~]$ cd /mnt/dir/

[smbuser@localhost dir]$ touch a

[smbuser@localhost dir]$ ll
total 0
-rw-rw-r--+ 1 smbuser smbuser 0 Jun 10 07:38 a
-rw-rw-r--+ 1 root    root    0 Jun 10 07:34 test.txt

[smbuser@localhost dir]$ rm * -rf
[smbuser@localhost dir]$

下面的试验我们看到在dir下建立的文件或文件夹都自动的加上了default的权限
[smbuser@localhost dir]$ touch test.txt
[smbuser@localhost dir]$ getfacl test.txt 
# file: test.txt
# owner: smbuser
# group: smbuser
user::rw-
user:smbuser:rw-
group::r-x #effective:r--
mask::rw-
other::r--

[smbuser@localhost dir]$ mkdir testdir
[smbuser@localhost dir]$ getfacl testdir/
# 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@localhost dir]$ ll
total 4
drwxrwxr-x+ 2 smbuser smbuser 4096 Jun 10 07:43 testdir
-rw-rw-r--+ 1 smbuser smbuser    0 Jun 10 07:41 test.txt


六:总结
从上面的例子可以看到,getfacl命令是用来读取文件的ACL, setfacl是用来设定文件的Acess ACL. 这里还有一个chacl是用来改变文件和目录的Access ACL and Default ACL. 他的用法很多, 这里只提及一下chacl  -B. 它可以彻底删除文件或者目录的ACL属性(包括Default ACL). 比如你即使用了setfacl -x 删除了所有文件的ACL属性,那个+号还是会出现在文件的末尾.所以正确的删除方法应该是用chacl -B

用cp来复制文件的时候我们现在可以加上-p选项.这样在拷贝文件的时候也将拷贝文件的ACL属性.对于不能拷贝的ACL属性将给出警告

mv命令将会默认地移动文件的ACL属性. 同样如果操作不允许的情况下会给出警告

如果用chmod命令改变Linux 文件权限的时候相应的ACL值也会改变.反之改变ACL的值,相应的文件权限也会改变




这篇博客我先看了几篇相关内容,然后自己动手又做了完整的测试,已经实现了ACL的功能,希望看到的人也自己亲自测试一下,遇到跟着片博客不符的情况可以找资料解决,这样才能进步,才能提升自己的能力。
阅读(712) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~