使用文件访问控制列表

增强文件权限管理

与通过 chmod 命令设置一般标准权限相比,利用访问控制列表可以更精细地调整文件和目录的权限。

David Tansley, 系统管理员, Ace Europe

//ibm.com/developerworks/i/p-dtansley.jpgDavid Tansley 是一位自由作家。他有 15 年 UNIX 系统管理经验,最近 8 年使用 AIX。他喜欢打羽毛球和观赏一级方程式赛车,但是最喜欢与妻子一起开着 GSA 摩托车旅行。


developerWorks 投稿作者

2011 年 6 月 27 日

简介

在 AIX®、UNIX® 和 Linux® 系统上,每个文件(对象)都有三个主要的基本权限集,它们可以允许或限制用户、组或任何其他用户的访问。每个权限集中都有三个访问位:读、写和执行。除了这 9 个位之外,文件还可以设置 set-uidgroup-uidsticky 位。

可以使用 chmod 命令修改这些权限,一般来说它们足以保证系统上大多数文件的安全性。但是,在某些情况下,标准的文件权限有局限性;与应用程序访问或安全性相关的产品可能会出现这种情况。为了解决这个问题,大多数系统管理员会创建与应用程序相关的组(可能根据团队或支持的需要)。但是,经过一段时间之后,创建的这些组及其成员会变得相当复杂,成为管理负担。给文件或目录提供正确的安全设置很麻烦。一般情况下,您试图满足一个用户或组的需要,同时不危害文件的安全性,也就是说不允许其他用户访问这些文件。无疑,为了让应用程序所有者满意,一些成员被添加到不允许访问这些文件的组中。对文件访问进行访问授权的一种方法是实现访问控制列表 (ACL)。通过使用 ACL,可以更好地控制谁可以、谁不可以访问或执行文件或目录;这由按用户或组分配给文件的扩展权限决定。

本文并不描述 NFS ACL 或继承,因为这个主题应该在专门的文章中讨论。

有三个实用程序可以帮助管理 ACL:

  • aclput —— 把 ACL 信息写到文件上,但是通常用于把 ACL 定义复制到另一个文件上。
  • aclget —— 显示给定文件的 ACL。
  • acledit —— 可以在编辑器中创建或修改给定文件的 ACL。

访问控制条目属性

ACL 使用访问控制条目 (ACE) 控制用户和组的访问权。它们通常被称为规则,包括:

  • permit —— 授予对一个文件或目录的访问权。
  • deny —— 限制对一个文件或目录的访问。
  • specify —— 精确地定义用户或组的访问权。
  • 对于每个规则,您可以指定用户或组要满足某一条件,然后才会授予或拒绝访问权。

现在,使用 aclget 查看 mig_top 文件,这个文件还没有设置任何 ACE 属性。命令的基本格式是 aclget <filename>

# aclget  mig_top
*
* ACL_type   AIXC
*
attributes:
base permissions
    owner(alpha):  rwx
    group(apps):  r--
    others:  r--
extended permissions
    disabled

仔细看一下 aclget 输出的信息,可以看到 ACL_type 是 AIXC。AIXC 包含基本的和扩展的权限。属性显示文件是否设置了 set-uidgroup-idsticky 位。基本权限显示通过 chmodchown 命令设置的权限。扩展的权限显示用户和组的扩展权限(如果启用了)。如果禁用了,那么作为只包含基本权限的一般文件处理。

扩展权限的格式如下:

Extended Permissions: ( Enabled | Disabled )

   permit  mode   u:username,g:groupname
   deny    mode   u:username,g:groupname
   specify mode   u:username,g:groupname

其中:

  • Extended Permissions 表明启用或禁用。
  • permit、deny 和 specify 是规则。
  • 模式是读 (r)、写 (w) 或执行 (x)。
  • 用户名/组名是由逗号分隔的用户 (u:) 和/或组 (g:)。每个用户条目必须具有单独的规则行。不能把两个用户放在同一行。

文件的所有者可以设置自己的 ACL。一个用户或组可以有多个条目;这样就可以更精细地调整访问权。组条目可以是单一组名,也可以包含多个组名。

在使用 acledit 之前,一定要把 EDITOR 环境变量设置为您喜欢的编辑器。例如:

$ export EDITOR=/usr/bin/vi

现在,在 mig_top 文件上创建 ACL。当前,它具有以下权限和所有者:

 $ ls -l mig_top
-rwxr--r--    1 alpha    apps           3768 Sep 30 18:11 mig_top

可以看到,没有为组设置执行位,只允许用户 alpha 执行此文件。假设用户 bravo 试图执行此文件,就会发生以下情况:

$ id
uid=210(bravo) gid=1(staff) groups=214(sun)
$ /usr/local/bin/mig_top
bash: /usr/local/bin/mig_top: 
The file access permissions do not allow the specified action.

现在让用户 bravo 对此文件具有执行权限。使用 acledit 编辑文件:

# acledit mig_top

把扩展权限改为启用。然后添加以下条目以允许用户 alpha 执行文件:

permit   r-x    u: bravo

在保存文件时以及在 acledit 内退出文件之前,会提示您确认希望保存修改:

Should the modified ACL be applied? (yes) or (no) yes

现在使用 aclget 显示修改后的 ACE 属性:

# aclget mig_top
*
* ACL_type   AIXC
*
attributes:
base permissions
    owner(alpha):  rwx
    group(apps):  r--
    others:  r--
extended permissions
    enabled
    permit   r-x     u:bravo

已经向用户 bravo 授予了扩展访问权。现在,如果用户 bravo 试图执行文件 mig_top,操作会成功:

$ id
uid=210(bravo) gid=1(staff) groups=214(sun)
 $ /usr/local/bin/mig_top
now processing...wait
done

如果在 ACL 中有语法错误,那么在试图保存 ACL 定义时,acledit 会显示发现的错误和造成错误的行号。例如:

    deny     r-w     u:papa
* line number 16: bad access mode: r-w

探究规则

ACE 是控制授予或拒绝扩展权限的规则,它们可能不容易理解。在本节中,讨论这些规则并通过示例演示如何实现规则。如果对于一个用户有拒绝访问的 deny 或 specify 规则,那么即使基本权限通过用户或组给他授予了访问权,此用户也会被拒绝。一个规则可以包含多个组,用户必须属于所有的组才满足条件。换句话说,执行条件 “与” 操作。

如果规则如下:

permit  r  - -  u:xray

它显式地声明用户 xray 只能读。写操作和执行操作被拒绝,除非通过另一个规则指定。不需要为写和执行操作设置 deny 规则,系统假定有这个限制。

再考虑以下规则:

    deny     -w-     u:xray
    permit   r-x     u:xray

在这个示例中,拒绝用户 xray 写,但是 permit 规则允许读和执行。这个操作也可以用一个 permit 规则实现,如下所示:

   permit   r-x     u:xray

现在看看 deny 规则如何覆盖 permit 规则。考虑以下 ACL:

extended permissions
    enabled
    permit   r-x     g:sun
    deny     r-x     u:alpha

sun 组的成员是用户 alpha 和 bravo。permit 规则允许 sun 组的成员读和执行。但是,deny 规则拒绝用户 alpha 读和执行;这会覆盖 permit 规则。用户 alpha 的访问会被拒绝。

现在考虑以下 ACL:

extended permissions
    enabled
    permit   r-x     g:sun
    deny     r-x     u:alpha,g:mobgrp

现在,在针对 alpha 的 deny 规则中添加了组 mobgrp。它声明,如果用户 alpha 属于组 mobgrp,就拒绝用户 alpha。如果用户 alpha 不属于组 mobgrp,就允许用户 alpha 访问。

在下一个示例中,向组 sun 和 mobgrp 授予读和写权限。只有同时属于这两个组的用户才允许读和写此文件。

extended permissions
    enabled
    permit   rw-     g:sun,g:mobgrp

下面是一个比较复杂的 ACL,包括针对用户和组的不同规则:

attributes:
base permissions
    owner(root):  rwx
    group(system):  r--
    others:  ---
extended permissions
    enabled
    specify  rw-     u:xray,g:chatt
    permit   rw-     g:sun,g:mobgrp
    permit   rw-     u:alpha,g:sun,g:earth
    permit   rw-     u:juliet
    deny     rw-     u:bravo,g:mobgrp,g:apps,g:syb
    deny     -w-     u:xray,g:chatt,g:spyi

在这个输出中,没有用户或组具有允许读、写或执行的基本权限。

第一个规则指定,只要用户 xray 是组 chatt 的成员,就允许他读和写,这会覆盖基本权限。如果不满足此条件,就拒绝读和写访问。

第二个规则允许同时属于 sun 和 mobgrp 组的用户读和写。如果不满足此条件,就拒绝访问。

第三个规则指定,如果用户 alpha 是 sun 和 earth 的成员,就允许他读和写。如果不满足此条件,就拒绝访问。

第四个规则允许用户 juliet 读和写。对于用户 juliet 没有设置需要满足的条件。

第五个规则指定,如果用户 bravo 是所有三个组(mobgrp、apps 和 syb)的成员,就拒绝他读和写。如果不满足此条件,就允许访问。

第六个规则指定,如果用户 xray 是 chatt 和 spyi 组的成员,就拒绝他写。如果不满足此条件,就允许写。但是,如果他只是 chatt 组的成员,那么应用第一个规则,因此也允许读。

尽管我只演示了文件上的 ACL,但是它们也可以在目录上使用。应用相同的原则。


限制 su 的方法

论坛上常常出现的一个问题是,如何对某些用户禁用 su。通过使用 ACL,很容易控制允许哪些用户使用 su 命令。假设默认的策略规定某些用户账号不能使用 su 变成其他账号,即使知道密码也不行。一个解决方案是对 su 使用 sudo,但是首先必须限制他们使用 su。假设不希望允许使用 su 的用户是 golf、hotel 和 india。对于这些用户,首先创建一个组。我们把这个组命名为 nosu:

#  mkgroup -A users="golf,hotel,india" nosu
# lsgroup nosu
nosu id=219 admin=false users=golf,hotel,india adms=root registry=files

接下来,使用 acledit 启用扩展权限,在 su 二进制文件上添加拒绝组 nosu 读和执行的规则。编辑之后,使用 aclget 确认修改已经完成:

# aclget /usr/bin/su
*
* ACL_type   AIXC
*
attributes: SUID
base permissions
    owner(root):  r-x
    group(security):  r-x
    others:  r-x
extended permissions
    enabled
    deny     r-x     g:nosu

现在,如果组 nosu 的成员试图执行 su,会被拒绝:

$ id
uid=224(india) gid=1(staff) groups=207(fire),208(cloud),217(nossh),219(nosu)
$ su - alpha
ksh: su: 0403-006 Execute permission denied.

要想允许这些账号访问 su,可使用 sudo。下面的示例所示的 sudoers 条目让 nosu 组能够在本地主机 rs6000 上使用 su 变成用户 zulu:

%nosu     rs6000 = NOPASSWD:/usr/bin/su – zulu

现在,用户 india(nosu 组的成员)可以通过 sudo 使用 su 变成用户 zulu:

$ id
uid=224(india) gid=1(staff) groups=207(fire),208(cloud),217(nossh),219(nosu)
$ sudo -l
User india may run the following commands on this host:
    (root) NOPASSWD: /usr/bin/su - zulu
$ sudo -u root su - zulu
$ id
uid=228(zulu) gid=1(staff) groups=209(earth)

复制 ACL 定义

要想把 ACL 信息从一个文件复制到另一个文件,可使用 aclget 并通过管道连接 aclput。例如,为了把 ACL 信息从 mig_top 复制到 prop_krb_admin 文件,可以使用以下命令:

# aclget mig_top | aclput prop_krb_admin

要想把 ACL 信息复制到许多文件,我建议先把 ACL 信息复制到一个临时文件,然后可以用 vi 编辑这个文件,根据自己的安全策略调整文件安全权限。完成之后,使用 aclput 把 ACL 定义复制到希望复制 ACL 属性的文件。

例如,使用以下命令把 mig_top 文件的 ACL 定义复制到临时文件 default_acl:

# aclget -o default_acl mig_top

然后,使用 aclput 把 default_acl 文件包含的定义复制到现有的文件 prop_krb_admin:

# aclput -i default_acl prop_krb_admin

确认 ACL 的复制已经完成:

# aclget prop_krb_admin
* ACL_type AIXC
*
attributes:
base permissions
 owner(root): rwx
 group(system): r--
 others: r--
extended permissions
 enabled
permit r-x  g:admin,g:sysmaint

如果要处理大量文件,我建议创建一个脚本,通过它自动处理要修改的文件。

在使用 tarcpio 等 AIX 存档实用程序时,一定要通过使用 'U' 标志保留 ACL 的扩展权限。如果目标文件系统或主机不支持 AIX ACL,那么文件上不保留扩展权限。

存档:

tar -cUvf myfile myfile.tar

打开存档:

tar -xUvf myfile.tar


如何知道文件上是否有 ACL

如果在文件上启用了 ACL,第 11 位会是 '+' 符号。使用带 'U' 标志的 ls 命令列出有 ACL 的文件:

$ ls -Ul probe_sys*
-r-xr-xr--+  1 root operator 25 Aug 17 11:24 probe_sys
-rwxr-x----  1 operator operator 24 Jul 1 17:24 probe_sys.sh

在这个示例中,可以看出 probe_sys 文件上启用了 ACL,但是 probe_sys.sh 没有。

还可以使用带 'ea' 选项的 find 命令寻找启用了 ACL 的文件,如下所示:

# find. -ea
./probe_sys
./admin_list.sh
./cont_del.sh

如果对启用了 ACL 的文件执行使用八进制值的 chmod 命令,就会禁用 ACL,但是文件上保留扩展设置。ACL 不会生效,直到使用带 enabledacledit 命令手工地重新启用它。


排除故障

当遇到与启用了 ACL 的文件相关的问题时,请重新检查规则是否正确。一定要先检查 deny 规则,因为它们会覆盖为用户/组指定的其他规则。我建议使用 truss 进一步判断问题。

作为用户执行 truss 命令。在下面的示例中,对遇到访问权限问题的 mig_top 文件执行 truss

$ truss /usr/local/bin/mig_top

如果生成了大量输出,只需把输出重定向到一个文件供进一步分析。在输出中,查找包含 "Err" 的模式。查看输出有可能会发现什么地方出了问题。

430292: execve("/usr/local/bin/mig_top", 0x2001ECB8, 0x2001EA48) Err#13 EACCES
430292: statx("/usr/local/bin/mig_top", 0x2FF228C0, 128, 010)= 0
430292: statx("/usr/local/bin/mig_top", 0x2FF22770, 128, 010) = 0
430292: open("/usr/local/bin/mig_top", O_RDONLY|O_LARGEFILE)  Err#13 EACCES

如果由于某种原因非 root 用户不能执行 truss,那么 root 用户可以通过 truss 会话监视用户的活动。 root 用户要获得遇到问题的用户的 PID。用户可以通过执行以下命令查明 PID:

$ echo $$
212996

然后,作为 root 用户执行 truss 命令并提供用户进程的 PID。接下来,让用户访问出问题的文件。

# truss -aef -p 212996

在 root 终端会话中,查看输出以帮助诊断问题。


结束语

通过使用 ACL,可以根据组成员关系、组合的组成员关系或只针对特定的用户精细地调整访问权限,帮助提高文件安全性。

参考资料

学习

  • 查看 access control list 以了解更多信息。
  • AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
  • AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。
  • AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
  • AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。
  • IBM Systems Magazine for AIX 中文版:本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM 的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=AIX and UNIX
ArticleID=682589
ArticleTitle=使用文件访问控制列表
publish-date=06272011