加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

SELinux 中基于角色的访问控制

(2009-04-23 13:24:56)
标签:

电脑

linux

unix

selinux

访问控制

acl

it

分类: Archives
基于角色的访问控制(Role-based access control,RBAC)是通用的安全模型,可以通过把角色分配给用户然后把权限分配给这些角色来简化管理。RBAC 在 Security-Enhanced Linux (SELinux) 中用作用户与底层类型增强(Type Enforcement,TE)模型之间的抽象层,用于提供细粒度的访问控制,但是并不是针对简化管理。了解如何将 SELinux 环境的三个部分(策略、内核和用户空间)结合使用以增强 RBAC 并把 Linux® 用户绑定到 TE 策略中。

在 Security-Enhanced Linux (SELinux) 中实现的安全策略是位于基于角色的访问控制 (RBAC) 层之下的类型增强 (TE)(SELinux 还将垂直实现多层安全性 (MLS),这超出了本文的讨论范围)。TE 最为常见,也因而最为人熟知,由于服务器实施细粒度权限:当由于意外的访问拒绝而引起中断时,TE 最有可能对此负责。在 TE 中,进程的安全域(对系统的影响域)是由任务的历史记录和当前执行的程序确定。

 

实现收银机系统

收银机结算系统的第一个实现是在前面介绍的从头创建的 SELinux 系统之上实现的(可以在 下载 中获得)。下面介绍了在完全从头创建的系统之上实现收银机结算系统的步骤。

挂载磁盘映像(关闭了 qemu 映像):

 

mount -oloop,offset=32256 -t ext2 gentoo.img /mnt

 

下载 部分获取 code_for_fromscratch.tgz 文件,并通过执行以下操作将其解压缩到磁盘映像下:

 

tar zxf selinuxregister.tgz -C /mnt
umount /mnt

 

现在启动 qemu 映像:

 

qemu -hda gentoo.img -m 512 -vnc :3 -kernel bzImage \
      -append "ro root=/dev/hda1 -p"

 

登录后,必须编译并安装新策略,同时安装新的 PAM 模块:

 

cd /usr/src
checkpolicy -c 19 -o policy.bin policy.conf
cp policy.bin /etc/
rc-update add selinuxenforce default
cp /etc/pam.d/system-auth /etc/pam.d/system-auth.orig
cp /etc/pam.d/system-auth.new /etc/pam.d/system-auth

 

SELinux 用户是在策略中创建的,但是必须创建与 SELinux 用户相对应的 Linux 用户:

 

adduser mary
passwd mary
  (passwd)
mkdir /home/mary
adduser boss
passwd boss
  (passwd)
mkdir /home/boss
adduser bob
passwd bob
  (passwd)
mkdir /home/bob

 

然后为数据存储创建目录结构:

 

mkdir /data
mkdir /data/cashier_r
mkdir /data/mgr_r
mkdir /data/final
chmod 777 /data/*

 

最后,重新设置文件系统的标签:

 

setfiles /usr/src/filecontexts /
poweroff

 

现在准备好了映像。在不使用 -p 标志的情况下重新启动映像,以便装载 SELinux 策略:

 

qemu -hda gentoo.img -m 512 -vnc :3 -kernel bzImage \
      -append "ro root=/dev/hda1"

 

然后以根用户身份登录,尝试执行以下命令:

 

ls /data

 

权限被拒绝。登出,然后以收银员 bob 的身份登录。记录一个值,例如:

 

register bob 25.22

 

然后尝试执行以下操作欺骗系统:

 

register bob commit

 

不起作用。登出,然后重新以经理 Mary 的身份登录:

 

register bob commit

 

Mary 首先需要输入她自己的值:

 

register bob 27
register bob commit

 

值不匹配。想知道 Bob 提交了什么值?

 

cat /data/cashier_r/bob/(day)

 

系统不允许查看该值。您必须去与 Bob 讨论该值。您可能重新计算收银机中的总额并发现 Bob 输入的值无误。因此:

 

register bob 25.22
register bob commit

 

这次可以了。现在可以以根用户身份登录并且:

 

cat /data/final/bob/(day)

 

这将显示已经输入的所有值。

进一步了解类型增强

使用同一个 /bin/register 程序的不同用户能够对不同文件执行读写操作,这些文件必须通过程序访问。这是类型增强的核心概念之一:应当结合授权的用户上下文与正被执行的代码确定结果进程对系统(或 TE 域)的 “影响范围”。

图 1 显示了系统中的域和类型:


http://www.ibm.com/developerworks/cn/linux/l-rbac-selinux/domaintrans_dec19.gif中基于角色的访问控制" TITLE="SELinux 中基于角色的访问控制" />

但是怎样阻止 Bob 以经理身份登录或者 Mary 以收银员身份登录?更有趣的是,老板如何以两种身份登录?

第一部分是由一个新的 PAM 模块完成的。简言之,PAM(可插入认证模块)允许在各个认证步骤中执行小段代码,还允许灵活地指定哪些模块何时执行。我已经介绍了一个新模块 pam_ctx.so,该模块的代码位于 /usr/src/pam_ctx 下。它将搜索 /usermap.conf 文件查找正被验证的用户名并查找此用户的默认上下文。对于 Bob,此默认上下文是 cashier_u:cashier_r:cashier_t。对于 Mary,它是 mgr_u:mgr_r:mgr_t。而对于老板,它是 full_u:mgr_r:mgr_t。注意,所有环境都是由用冒号分隔的三个部分组成的:

  • 最后一部分是域,它将最终决定用户在系统中的权限。
  • 第二部分是角色,它将限制用户可以进入的域。
  • 第一部分是 “SELinux 用户”。类似于角色和域,这部分将限制进程可以进入的角色。

PAM 模块设置上下文的方式为:把上下文写入 /proc/$$/attr/exec 文件,然后执行对于新域具有有效登录类型的 shell。查看策略源代码,您将看到 mgr_r 只能与 mgr_t、mgr_register_t 和 rolechange_t 域关联在一起。cashier_r 角色只能与 cashier_t 和 cashier_register_t 域关联在一起。类似地,SELinux 用户 mgr_u 只能与 mgr_r 角色关联在一起,cashier_u 只能与 cashier_r 关联在一起。用户 full_u 可以与 mgr_r 或 cashier_r 关联在一起。

图 2 显示了所有这些部分如何相互联系。

http://www.ibm.com/developerworks/cn/linux/l-rbac-selinux/rbac.gif中基于角色的访问控制" TITLE="SELinux 中基于角色的访问控制" />

位于顶部的一行显示了 SELinux 用户,位于中间的一行列出了角色,而位于底部的一行列出了域。只要连接了三行,就可以使用任意一行中的条目构造一个有效的安全上下文。在策略中,用户定义:

 

user full_u roles { mgr_r cashier_r };

 

将定义一个用户及其与角色的连接,而角色定义:

 

role cashier_r types { cashier_t cashier_register_t };

 

将定义中间行条目及其与底部行的连接。

但是如何阻止 Bob 将 “full_u:mgr_r:mgr_t” 写入 /proc/$$/attr/exec?有很多方法。其中之一就是类型增强。回头查看图 1,当您在 cashier_t 类型中后,就只能进入 cashier_write_t。另外,SELinux 策略将指定允许哪些角色转换。因此使用:

 

allow mgr_r cashier_r;

 

指定角色 mgr_r 中的进程可以切换到角色 cashier_r 中的有效上下文。但是没有下面的一行:

 

allow cashier_r mgr_r;

 

因此 Bob 不能转换到 cashier_r 中的任何上下文。

我们还拒绝让 Mary 进入 cashier_t 域。查看 图 1,域转换本身实际上是被允许的。并且策略行:

 

allow mgr_r cashier_r;

 

还允许角色转换。但是,要实现角色转换,策略指定必须通过 /bin/role_change 入口点首先进入 rolechange_t。此程序将不会覆盖其上下文的 SELinux 用户部分。因此,登录到 mgr_u:mgr_r:mgr_t 中后,除了作为由 /usermap.conf 文件授权并由 pam_ctx.so 模块执行的有效 full_u 用户身份重新登录之外,没有其他方法可以转换到 cashier_r 角色。

有一点没有在策略中禁止。注意,对 SELinux 用户转换没有任何固有控制。所有这类控制都必须通过把 SELinux 用户与角色和域绑定在一起实现,这样,角色和域转换不允许转换到其他 SELinux 用户的任何有效上下文 —— 如果这是我们的需求。

具体来讲,让我们尝试以下操作。以根用户身份登录并修改 /bin/register.py,获悉它的上下文。我们将把一些行添加到新文件 addme 中,然后把该文件插入到 /bin/register.py 中靠近顶部的位置。

 

echo 0 > /selinux/enforce
cat > /root/addme << EOF
f=open("/proc/self/attr/current", "r")
print f.readlines()
f.close()
EOF
nano /bin/register.py
      

 

现在使用向下箭头键把光标移到 import 行下,然后为 Read File 键入 Control-r,然后键入 /root/addme。现在键入 Control-O 把数据写入文件,返回确认文件名,然后键入 Control-X 退出。最后,把 SELinux 设置回强制模式。

 

echo 1 > /selinux/enforce
logout

 

以 bob 的身份登录,显式要求 SELinux 进行域转换,然后运行 register.py:

 

echo "full_u:cashier_r:cashier_register_t" > /proc/self/attr/exec
/bin/register.py bob 25

 

现在 register.py 将作为 full_u:cashier_r:cashier_register_t 运行!把上下文回传到 /proc/pid/attr/exec 文件中,这将导致 SELinux 在下一次执行时尝试转换到该上下文中。当然,只有在转换有效时才会成功。在本例中,转换是有效的,因为没有更改角色,并且允许执行 cashier_exec_t 类型文件的 cashier_t 转换到 cashier_register_t。如果尝试:

 

echo "full_u:mgr_r:mgr_register_t" > /proc/self/attr/exec
/bin/register.py bob 25

 

您将注意到权限被拒绝。最后,您可以尝试:

 

echo "full_u:mgr_r:cashier_register_t" > /proc/self/attr/exec
/bin/register.py bob 25

 

这一次,权限没有被拒绝,但是上下文被报告为 cashier_u:cashier_r:cashier_register_t。为什么行为不同?由于 full_u:mgr_r:mgr_register_t 是一个有效的上下文,因此下一次执行将实际尝试域转换并失败。但是,full_u:mgr_r:cashier_register_t 甚至不是一个有效的上下文,因为 mgr_r 可能未与 cashier_register_t 关联在一起。如果在把上下文回传到 /proc/self/attr/exec 后查看返回值,则将发现它已经失败。

 

echo "full_u:mgr_r:cashier_register_t" > /proc/self/attr/exec
echo $?
    1

 

使用 Fedora Core 8

Fedora 8 默认启用了 SELinux。它集成了全新的 SELinux 技术,使用可装载策略模块简化策略定制并使用 semanage 简化用户和 RBAC 管理(Semanage 用于配置 SELinux 策略的某些元素,而无需对策略源代码进行修改或重新编译)。

让我们首先执行一次默认安装。首先下载 Fedora-8-i386-DVD.iso(请查阅下面的 参考资料 中的链接)。为了方便起见,您可以将其重命名为 f8.img。您将使用它作为 cdrom 映像以将 Fedora 8 安装到 qemu 下:

 

dd if=/dev/zero of=f8.img bs=1G seek=10 count=1
qemu -hda f8.img -cdrom f8.iso -boot d -m 1024 -vnc 3
      

 

然后,启动 VNCviewer:

 

vncviewer :3

 

在 VNC 窗口中,遵循几乎全部的默认安装设置,惟一的例外是:当询问要安装的包时,请取消选中 “Office and Productivity”,然后选中 “Software Development”。

安装完成后,在重新启动后继续遵循设置说明并选择要创建的非根用户帐户。最后,当映像就绪后,以该用户身份登录。

打开本文的浏览器窗口并下载 Fedora 8 的源 tarball(请查阅 参考资料 中的链接)。把它保存到主目录中的 ~myuser/cash_register_f8.tgz。

在左上角的 “Applications” 菜单中,选择 System Tools > Terminal。然后键入 su - 并输入根用户密码以打开根用户 shell。现在您已经准备好安装安全的收银机结算系统。

(注:如果无法忍受系统过慢的显示速度,您可以通过输入 runlevel 3 来退出 X 窗口。您可以通过键入 /sbin/init 3 来完成这项操作。您始终可以通过使用 /sbin/init 5 重新输入 runlevel 5 来重新启动 X 窗口。在 runlevel 3,只需在终端以根用户身份登录)。

首先,强制退出后台守护进程,以便您可以手动运行 yum:

 

killall -9 yum-updatesd

 

接下来安装 SELinux 策略模块开发包:

 

yum install selinux-policy-devel.noarch

 

现在复制示例策略模块目录,把收银机策略文件复制到示例目录中,然后编译这些文件:

 

cd /usr/share/selinux/
cp -r devel cash_register
cd cash_register
rm example.*
tar zxf ~myuser/cash_register_f8.tgz
mv register.py /bin
make

 

策略被编译成 cash_register.pp 文件中的二进制策略模块。要装载它,请执行以下代码:

 

semodule -i cash_register.pp

 

接下来,创建用户 mary 和 bob:

 

adduser bob
adduser mary
passwd bob
passwd mary

 

现在用户已经存在,请设置 RBAC 以将这些用户登录到相应的角色中:

 

semanage user -a -R cashier_r -P cashier bob_u
semanage login -a -s bob_u bob

semanage user -a -R mgr_r -P mgr mary_u
semanage login -a -s mary_u mary

 

semanage user 命令将创建一个新 SELinux 用户。SELinux 用户不是 Linux 用户名,而是附加到进程和文件的 SELinux 上下文(由 id -Z 返回)的一部分。如果在终端中键入 id -Z,您可能会看到 system_uunconfined_u。虽然 Linux 用户名和 SELinux 用户名可能相同,但是它们本身并没有联系。但是,登录进程将使用 Linux 用户名来为安全上下文选择 SELinux 用户。如上一节所述,SELinux 用户被限定到可以关联的角色中,同样,SELinux 角色被限定到关联的 SELinux 域(类型)中。

您将使用 semanage user 创建两个 SELinux 用户 mary_u 和 bob_u。同时,您将指定这两个用户可以关联的角色。用户 bob_u 只能使用 cashier_r 角色,而 mary_u 只能使用 mgr_r。您还必须为用户的主目录类型指定一个前缀。对于 Mary,请指定 mgr,并且将主目录扩展为 mgr_home_dir_t,并将 mgr_home_t 用于该目录中的文件。

semanage login 命令将把 Linux 用户名与 SELinux 用户绑定在一起。指定 mary 将以 mary_u 的身份登录,bob 将以 bob_u 的身份登录。

我们仍然需要为收银机值创建基本目录结构:

 

mkdir /data
mkdir /data/final
mkdir /data/cashier_r
mkdir /data/mgr_r
chmod 777 /data/cashier_r
chmod 777 /data/mgr_r
chmod 777 /data/final

 

最后,为新用户重新标记已创建和已安装的所有文件以及主目录:

 

fixfiles -f relabel /data /bin/register.py /home

 

注意这一次我们并未在策略中定义 SELinux 用户。而是用 semanage 命令创建了用户并把这些用户与相应的角色关联起来。

如果只希望允许 bob 以 cashier_r 的身份登录而 mary 以 mgr_r 的身份登录,那么不需要进行什么修改。但是,您可能需要让用户 charlie 能够以 mgr_r 或 cashier_r 的身份登录。这样做将要求进行更多更改。首先,创建用户:

 

adduser charlie
passwd charlie
semanage user -a -R mgr_r -R cashier_r -P mgr charlie_u
semanage login -a -s charlie_u charlie

 

现在告诉 PAM 应当询问 charlie 想要以哪个角色的身份登录。首先,打开 /etc/pam.d/login 并把下列行:

 

session required pam_selinux.so open

 

替换为:

 

session required pam_selinux.so open select_context

 

这样做将告诉 pam_selinux.so 模块用户应当能够在登录时选择默认上下文。接下来,告诉系统要为角色 charlie_r 使用的默认类型。在登录时,系统将允许 Charlie 指定角色而不使用默认值(mgr_r,因为我们把它列在 semanage user 命令中的第一位)。可供选择的选项是您在创建用户时用 -R 标志指定的所有角色。SElinux 随后将使用与被请求角色相关的默认类型,因此您必须为 cashier_r 指定一个默认类型:

 

echo "cashier_r:cashier_t" >> \
      /etc/selinux/targeted/contexts/default_type

 

现在当 Charlie 登录到控制台(或者按 Ctrl-Alt-F2 组合键登录到控制台,或者如前述输入 runlevel 3)时,系统将询问他要以哪个角色的身份登录。默认值将是 mgr_r,但是他也可以选择进入 cashier_r。如果他选择 cashier_r,他将能够以收银员的身份存储值,但是根据已经定义的策略,他不能够读取 Charlie 主目录中的任何文件。

注意,register.py 不对 Charlie 以经理和收银员的身份为自己的收银机存储的值进行保护。当然,这样的更改将十分容易实现

因此当您下一次运行 register.py 时,register.py 不会尝试请求的域转换,而是简单地继续默认域转换并成功。

此时,您可能认为通过严格地使用 TE 而不使用角色或 SELinux 用户就可以实现我们的目标。但是,使用角色和用户可以使将来的系统管理更加简单。当您接下来了解如何在 Fedora Core 8 中实现此系统时,将更清楚地明白这一点

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有