首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

SELinux 中基于角色的访问控制(2)

SELinux 中基于角色的访问控制(2)

进一步了解类型增强使用同一个 /bin/register 程序的不同用户能够对不同文件执行读写操作,这些文件必须通过程序访问。这是类型增强的核心概念之一:应当结合授权的用户上下文与正被执行的代码确定结果进程对系统(或 TE 域)的 “影响范围”。
图 1 显示了系统中的域和类型:
图 1. 域和类型但是怎样阻止 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 显示了所有这些部分如何相互联系。
图 2. 各部分如何联系位于顶部的一行显示了 SELinux 用户,位于中间的一行列出了角色,而位于底部的一行列出了域。只要连接了三行,就可以使用任意一行中的条目构造一个有效的安全上下文。在策略中,用户定义:
1
user full_u roles { mgr_r cashier_r };




将定义一个用户及其与角色的连接,而角色定义:
1
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 策略将指定允许哪些角色转换。因此使用:
1
allow mgr_r cashier_r;




指定角色 mgr_r 中的进程可以切换到角色 cashier_r 中的有效上下文。但是没有下面的一行:
1
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 中靠近顶部的位置。
1
2
3
4
5
6
7
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 设置回强制模式。
1
2
echo 1 > /selinux/enforce
logout




以 bob 的身份登录,显式要求 SELinux 进行域转换,然后运行 register.py:
1
2
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。如果尝试:
1
2
echo "full_u:mgr_r:mgr_register_t" > /proc/self/attr/exec
/bin/register.py bob 25




您将注意到权限被拒绝。最后,您可以尝试:
1
2
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 后查看返回值,则将发现它已经失败。
1
2
3
echo "full_u:mgr_r:cashier_register_t" > /proc/self/attr/exec
echo $?
    1




因此当您下一次运行 register.py 时,register.py 不会尝试请求的域转换,而是简单地继续默认域转换并成功。
此时,您可能认为通过严格地使用 TE 而不使用角色或 SELinux 用户就可以实现我们的目标。但是,使用角色和用户可以使将来的系统管理更加简单。当您接下来了解如何在 Fedora Core 8 中实现此系统时,将更清楚地明白这一点。
返回列表