简介: 与通过 chmod 命令设置一般标准权限相比,利用访问控制列表可以更精细地调整文件和目录的权限。
简介
在 AIX®、UNIX® 和 Linux® 系统上,每个文件(对象)都有三个主要的基本权限集,它们可以允许或限制用户、组或任何其他用户的访问。每个权限集中都有三个访问位:读、写和执行。除了这 9 个位之外,文件还可以设置 set-uid、group-uid 或 sticky 位。
可以使用 chmod 命令修改这些权限,一般来说它们足以保证系统上大多数文件的安全性。但是,在某些情况下,标准的文件权限有局限性;与应用程序访问或安全性相关的产品可能 会出现这种情况。为了解决这个问题,大多数系统管理员会创建与应用程序相关的组(可能根据团队或支持的需要)。但是,经过一段时间之后,创建的这些组及其 成员会变得相当复杂,成为管理负担。给文件或目录提供正确的安全设置很麻烦。一般情况下,您试图满足一个用户或组的需要,同时不危害文件的安全性,也就是 说不允许其他用户访问这些文件。无疑,为了让应用程序所有者满意,一些成员被添加到不允许访问这些文件的组中。对文件访问进行访问授权的一种方法是实现访 问控制列表 (ACL)。通过使用 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-uid、group-id 或 sticky 位。基本权限显示通过 chmod 和 chown 命令设置的权限。扩展的权限显示用户和组的扩展权限(如果启用了)。如果禁用了,那么作为只包含基本权限的一般文件处理。
扩展权限的格式如下:
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。一个用户或组可以有多个条目;这样就可以更精细地调整访问权。组条目可以是单一组名,也可以包含多个组名。
现在,在 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
如果要处理大量文件,我建议创建一个脚本,通过它自动处理要修改的文件。
如何知道文件上是否有 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 的文件相关的问题时,请重新检查规则是否正确。一定要先检查 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,可以根据组成员关系、组合的组成员关系或只针对特定的用户精细地调整访问权限,帮助提高文件安全性。