|
更进一步研究类型增强
不同用户使用相同的/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,注意所有的上下文都由冒号分隔的3部分组成:
◆最后一部分是域,它最终决定用户在系统上的权限 ◆第二部分是角色,它限制了用户可以进入的域 ◆第一部分是SELinux用户,与角色和域相似,它限制了进程可以进入的角色
PAM模块通过将上下文写入文件/proc/$$/attr/exec来设置上下文,然后再对新域执行一个有效登记类型的shell脚本,查看策略的代码,你会看到mgr_r或许是与域mgr_t,mgr_register_t, and 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用户,中间的行列出了角色,下面的行列出了域,创建一个有效的安全上下文必须从连接在一起的条目中每一行使用一个项目,在策略里,用户的定义如下: 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里写入呢?有几个原因,其中一个就是类型增强(TE),查看图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用户上下文。
特别地,让我们尝试下面的内容,作为root用户登陆,并修改/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行下,然后按Ctrl-r读取文件,敲入/root/addme,再按Ctrl-O写这个文件,回车确认文件名,然后按Ctrl-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_t执行一个cashier_exec_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是一个有效的上下文,因此下次执行实际上试图进行域转换时失败了,但是,自从mgr_r与cashier_register_t建立联系以来,full_u:mgr_r:cashier_register_t就不再仅是一个有效的上下文了,在往/proc/self/attr/exec写入上下文后,我们检查了返回的数值,我们发现它失败了。 echo "full_u:mgr_r:cashier_register_t" > /proc/self/attr/exec echo $? 1 因此当你下次运行register.py时,它不会试图要求域转换了,但是要简单地执行默认的域转换,这会是成功的。
在这一点上,你可能会认为我们的目标通过严格使用TE而不利用角色或SELinux用户已经达到了,但是,使用角色和用户在未来将会使系统管理变得更容易,当你看了如何在Fedora Core 8上实施后将会有更清醒的认识。
上一页 [1] [2] [3] 下一页
|