2014年4月10日星期四

Linux_030:Access Control Lists (ACLs)

环境:RHEL 7

默认的文件权限只允许文件属主、属组、其他人访问。
ACL 允许更细的权限粒度来控制文件,比如允许一个特定的进程访问某些文件,比如允许一个特定的用户、组访问某些文件。
文件的属主可以为特定的文件和目录设置 ACL。
新的文件和子目录可以继承父目录默认的 ACL 设置(如果父目录设置了默认的 ACL 的话),和目录的普通权限一样,必须有可执行权限才可以访问目录。
XFS 文件系统已经内置了对 ACL 的支持。
RHEL 7 的 Ext4 文件系统创建时,默认 enable ACL,RHEL 7 之前的版本,在挂载文件系统时,需要加上 acl 选项才支持 ACL。

$ ls -l roster.txt
-rwxrw----+ 1 student controller 130 Mar 19 23:56 roster.txt
这个“+”号表明这个文件设置了 ACL。
注意,当一个文件设置了 ACL 后,user 和 other 显示的权限和原来的含义一样,但是 group 显示的不是属组的权限,而是 ACL_MASK 的权限
要修改一个设置了 ACL 的文件的属组权限不能使用 chmod,而应该使用 setfacl -m g::perms file 。
   
1. Access Entry 格式
Access Entry 由三个组成部分: Entry tag type、qualifier (optional)、权限,之间用冒号分隔。

Entry tag type 有以下几种类型:
(1)ACL_USER_OBJ: 相当于原来的属主权限。
(2)ACL_USER: 定义了额外的用户可以对此文件拥有的权限。
(3)ACL_GROUP_OBJ: 相当于原来的属组权限。
(4)ACL_GROUP: 定义了额外的组可以对此文件拥有的权限。
(5)ACL_MASK: 定义限制了 ACL_USER、ACL_GROUP_OBJ、ACL_GROUP 的最大权限,不限制 ACL_USER_OBJ 和 ACL_OTHER 的权限。它可以根据 ACL 的操作情况自动计算出最大的权限,也可以使用 setfacl 人为设置。
(6)ACL_OTHER: 相当于原来的 other 权限。

qualifier 定义了特定的用户和组,只有 user 和 group 才有qualifier,其它为空。

Access Entry 在输出的显示中:
(1)user 对应了 ACL_USER_OBJ 和 ACL_USER。
(2)group 对应了 ACL_GROUP_OBJ 和 ACL_GROUP。
(3)mask 对应了 ACL_MASK。
(4)other 对应了 ACL_OTHER。

2. 查看一个文件的 ACL 设置
 $ getfacl roster.txt
  # file: roster.txt
  # owner: student
  # group: controller
  user::rwx                // 定义了 ACL_USER_OBJ,说明 file owner 有读、写、执行的权限。
  user:james:---        // 定义了 ACL_USER,用户 james 对文件没有任何权限。
  user:1005:rwx       // 定义了 ACL_USER,用户 ID=1005 的用户 对文件有读、写、执行的权限。
  group::rwx             // 定义了 ACL_GROUP_OBJ,说明文件的 group 有读、写、执行的权限。
  group:sodor:r--      // 定义了 ACL_GROUP,使得 sodor 组对文件有读的权限。
  group:2210:rwx     // 定义了 ACL_GROUP,使得组 ID=2210 的组对文件有读、写、执行的权限。
  mask::rw-              // 定义了 ACL_MASK 的权限为读和写。
  other::---                // 定义了 ACL_OTHER 没有任何权限。
  #effective:rw-
  #effective:rw-
  #effective:rw-

3. 查看一个目录的 ACL 设置
$ getfacl .
  # file: .
  # owner: student
  # group: controller
  # flags: -s-
  user::rwx
  user:james:---
  user:1005:rwx
  group::rwx
  group:sodor:r-x
  group:2210:rwx
  mask::rwx
  other::---
  default:user::rwx           // 属主默认的 ACL 权限:读写新文件,可执行子目录。其它用户默认继承属主的 ACL 权限。
  default:user:james:---   // 用户 james 默认的 ACL 权限:没有任何权限。
  default:group::rwx        // 属组的默认 ACL 权限:读写新文件,可执行子目录。其它组默认继承属组的 ACL 权限。
  default:group:sodor:r-x   // 组 sodor 默认的 ACL 权限:只读新文件,可执行子目录。
  default:mask::rwx           // 默认的 ACL_MASK 权限:读写新文件,可执行子目录。
  default:other::---             // 默认的 ACL_OTHER 权限:没有任何权限。

3. 判断一个进程能否访问一个设置了 ACL 的文件顺序:
(1)如果执行进程的用户是文件的属主,应用 ACL_USER_OBJ 权限。
(2)如果执行进程的用户是 ACL 中定义的某个用户,应用 ACL_USER 权限(在 ACL_MASK 允许的范围之内)。
(3)如果执行进程的组是文件的属组,应用 ACL_GROUP_OBJ 权限(在 ACL_MASK 允许的范围之内)。
(4)如果执行进程的组是 ACL 中定义的某个组,应用 ACL_GROUP 权限(在 ACL_MASK 允许的范围之内)。

4. 设置文件的 ACLs
(1)增加或修改一个用户的 ACL 权限 
   $ setfacl -m u:name:rX file
如果 name 为空,相当于设置文件属主的 ACL 权限。
文件属主的普通权限和文件属主的 ACL 权限是一样的,使用 chmod 设置文件属主的权限和使用 setfacl 设置文件属主的 ACL 权限是一样的。
注意,chmod 对 named user ACL 没有作用。   
(2)增加或修改一个组的 ACL 权限
   $ setfacl -m g:name:rw file // 如果 name 为空,相当于设置文件属组的 ACL 权限
   注意,chmod 对 named group ACL 没有作用,但是会引起 ACL_MASK 变化。
(3)增加或修改 other 的 ACL 权限
   $ setfacl -m o::- file
   文件 other 的普通权限和文件属主的 ACL 权限是一样的,使用 chmod 设置文件 other 的权限和使用 setfacl 设置文件 other 的 ACL 权限是一样的。
(4)可以一行定义多个 ACL 权限
   $ setfacl -m u::rwx,g:sodor:rX,o::- file
(5)getfacl 的输出可以作为 setfacl 的输入
   $ getfacl file-A | setfacl --set-file=- file-A-B // --set-file 接受输入来自一个文件或标准输入,标准输入用“-”表示。
   这样设置后,file-B 和 file-A 拥有同样的 ACL 权限。
(6)增加或修改 other 的 ACL_MASK 权限
   $ setfacl -m m::r file
(7)递归设置目录的 ACL 权限
   $ setfacl -R -m u:name:rX directory // X 表示只对目录设置可执行权限,防止不小心给所有文件设置了可执行权限
(8)删除 ACL 权限
  $ setfacl -x u:name,g:name file  // 删除该文件的指定的用户、组的 ACL 权限
  $ setfacl -b file // 删除该文件的所有 ACL 权限
  $ setfacl -b directory // 删除该目录的所有 ACL 权限
增加或修改默认的 ACL 权限
  $ setfacl -m d:u:name:rx directory
(9)删除默认的 ACL 权限
  $ setfacl -x d:u:name directory
  $ setfacl -k directory  // 删除该目录的所有默认的 ACL 权限

$ newgrp controller // 切换到某个组,用户可能有一个属组和多个附加组

5. ACL_MASK
查看 test.sh 的权限
# ll test.sh
-rwxrw-r-- 1 root family 0 12-27 23:04 test.sh

让用户 zyq 对 test.sh 有读、写、执行权限。


# setfacl  -m u:zyq:rwx test.sh

# getfacl -c test.sh
 user::rwx
 user:zyq:rwx
 group::rw-
 mask::rwx
 other::r--

可以看到 zyq 已经拥有了 rwx 的权限,同时 mask 也被设定为 rwx,那是因为它规定了ACL_USER、ACL_GROUP、ACL_GROUP_OBJ 的最大值

再次查看 test.sh 的权限
# ll test.sh
-rwxrwxr--+ 1 root family 0 12-27 23:04 test.sh


那么如果现在 family 组的用户想要执行 test.sh 的程序会发生什么情况呢?
答案是无法执行,因为实际上 family 组的用户只有读和写的权限。
这里当中显示的 rwx 是ACL_MASK 的值而不是 group 的权限。
小结:如果一个文件后面有 + 标记,需要用 getfacl 来确认它的权限,以免发生混淆。

6. Effective

继续上面的例子,设置 test.sh 的 mask 为r--,那么 family 组的用户还会有 write 权限吗?

# setfacl -m mask::r test.sh
# getfacl -c test.sh
 user::rwx
 user:zyq:rwx                  #effective:r--
 group::rw-                      #effective:r--
 mask::r--
 other::r--

这时发现,ACL_USER 和 ACL_GROUP_OBJ 旁边多了个 #effective:r--,表明虽然 ACL_USER 和 ACL_GROUP_OBJ 被设置了 rwx 和 rw-,但是  ACL_MASK 已经限制了 ACL_USER、ACL_GROUP_OBJ、ACL_GROUP 的最大权限为 r--,因此 ACL_USER 和 ACL_GROUP_OBJ 真正有效的权限是 r--。


7. Default ACL 
继续上面的例子,设置 test.sh 的 mask 为r--,那么 family 组的用户还会有 write 权限吗?

# setfacl -m mask::r test.sh
# getfacl -c test.sh
 user::rwx
 user:zyq:rwx                  #effective:r--
 group::rw-                      #effective:r--
 mask::r--
 other::r--

这 时发现,ACL_USER 和 ACL_GROUP_OBJ 旁边多了个 #effective:r--,表明虽然 ACL_USER 和 ACL_GROUP_OBJ 被设置了 rwx 和 rw-,但是  ACL_MASK 已经限制了 ACL_USER、ACL_GROUP_OBJ、ACL_GROUP 的最大权限为 r--,因此 ACL_USER 和 ACL_GROUP_OBJ 真正有效的权限是 r--。


 


参考文献:
1. http://www.cnblogs.com/ZhangShuo/articles/1836971.html

没有评论: