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

从头开始生成 SELinux(3)

从头开始生成 SELinux(3)

安装 SELinux 用户空间下一个步骤是安装将以文本形式编写的 SELinux 策略编译成内核所需要的二进制格式的代码,以及一个对根文件系统进行标记的程序。源代码可以使用清单 6 所示的代码通过 CVS 从 SourceForge 上获得:
清单 6. 得到 SELinux 用户空间源代码
1
2
3
4
5
su
mount -oloop,offset=32256 $ORIG/gentoo.img /mnt
cd /mnt/usr/src
cvs -z3 -d:pserver:anonymous@cvs.sf.net:/cvsroot/selinux co -P \
nsa/selinux-usr




将纯文本策略拷贝到磁盘映像文件上,方法如下:
cp -r $ORIG/mdp /mnt/usr/src
进入 nsa/selinux-usr 目录,并编译 libsepol、checkpolicy、libselinux 和 policycoreutils,方法如下:
清单 7. 编译 SELinux 用户空间代码
1
2
3
4
5
6
7
8
9
10
chroot /mnt
cd /usr/src/nsa/selinux-usr/
cd libsepol/
make && make install
cd ../libselinux/
make && make install
cd ../checkpolicy/
make && make install
cd ../policycoreutils/
make && make install




如果在上一个步骤中碰到了错误,请确保所需要的 setfiles 都已经安装了,方法如下:
清单 8. 安装 setfiles
1
2
3
cd setfiles
make
make install




现在,要编译策略,请使用 checkpolicy 程序,方法如下:
清单 9. 编译 SELinux 策略
1
2
3
4
5
cd /usr/src/mdp
checkpolicy -o policy.bin policy.conf
cp policy.bin /etc/
exit  # exit chroot
exit  # exit root shell




重新对文件系统进行标记需要引导进虚拟机中。记住现在要指定 -p 选项,这样 /sbin/init 就不会加载 SELinux 策略:
qemu -hda gentoo.img -kernel bzImage -append "ro root=/dev/hda1 -p"
SELinux 是通过自己的文件系统 selinuxfs 来与用户空间的程序进行交互的。用户空间程序期望它被挂载到 /selinux 上。创建 /selinux 目录,并对文件系统重新进行标记,方法如下:
清单 10. 重新标记文件系统
1
2
3
4
mkdir /selinux
cd /usr/src/mdp
setfiles file_contexts /
poweroff




最后,您可以在 SELinux 下重新启动机器了!
qemu -hda gentoo.img -kernel bzImage -append "ro root=/dev/hda1"
学习 SELinux 策略SELinux 是基于为进程、文件和其他对象所分配的安全上下文来制定访问决策的。SELinux 为查询这些上下文并对它们进行设置(假设有所需的访问权限)提供了接口。例如,SELinux 通过 procattr 接口来报告进程的上下文。如果输入:
cat /proc/$$/attr/current
就会看到当前进程($$)的上下文。通过使用脚本 pidctx.sh(请参见后文  一节中的 zip 文件),我们可以简单地查看系统中所有进程的上下文。这个脚本会简单地打印系统上每个进程的 /proc/<pid>/attr/current 文件的内容。
SELinux 使用扩展属性来保存文件的内容。Linux 中大部分永久文件系统(ext2、ext3、jfs、xfs 等)都可以支持扩展属性,而 reiserfs 是一个不幸的例外。这些是一些 (name, value) 的数据对,与 inode 关联在一起,其中名字被周期性地划分成名称空间。SELinux 扩展属性在安全性名称空间中,是由 “selinux” 来标识的,因此完整的 xattr 值应该是 “security.selinux”。新的系统调用集允许用户空间查询并设置扩展属性。用来对 xattr 进行查询的系统调用是 getxattr(2)。它接受一个文件名、一个属性名、一个缓冲区(xattr 的返回值就保存在这里)以及所提供的缓冲区的大小作为参数。
showctx.c 文件简单地运行作为命令行提供的所有文件名,并打印  security.selinux 扩展属性的值,这假设它是存在、可读的,并且具有合适的大小。
我们可以从后文  一节的 zip 文件中获得 showctx.tar.gz 文件,并从中解压出 showctx.c 文件。然后将其放入 QEMU 机器。一种方法是关闭 QEMU 映像,然后执行下面的命令:
清单 11. 安装 showctx
1
2
3
4
5
(su)
mount -oloop,offset=32256 $ORIG/gentoo.img /mnt
cp showctx.c /mnt/usr/src
umount /mnt
exit




现在如果 QEMU 没在运行,就启动它。要编译 showctx,请输入:
gcc -o showctx showctx.ccp showctx /bin/
现在可以输入:
showctx / /tmp /home /root /usr/src
当然,对每个文件我们都会看到相同的内容。下一节会通过增强策略来让这变得更加有趣。
使用 SELinux 策略秘密类型现在可以创建一个秘密目录 /secret,SELinux 应该不允许其他进程在这个目录下面读取数据。实际上我们可以先在这个目录中创建一个目录和几个文件:
mkdir /secretecho "hello, world" > /secret/helloworldecho "You can't see me" > /secret/dontlook
在 SELinux 策略中,现在创建一个新类型 secret_t,其他类型 base_t 无权访问它。首先,我们可以将下面的内容:
type secret_t;
添加到 policy.conf 中的 base_t 声明之后来定义这个类型。另外,由于 secret_t 类型的文件都是角色 base_r 的,而角色 base_r 必须要允许与 secret_t 关联在一起。因此刚才添加的这行代码要读取:
role base_r types { base_t };
对其进行编辑,使其读取:
role base_r types { base_t secret_t };
现在,要重新编译这个策略,请输入:
checkpolicy -o policy.bin policy.conf
cp policy.bin /etc/
接下来将下面的行添加到 file_contexts 文件中:
清单 12. /secret 中的文件内容
1
2
3
/secret user_u:base_r:secret_t
/secret/helloworld user_u:base_r:base_t
/secret/.* user_u:base_r:secret_t




这告诉系统 /secret 目录及其中的任何文件都是 secret_t类型的,只有 /secret/helloworld 文件例外,它应该是 base_t 类型的。要分配磁盘上的上下文,请使用 setfiles:
setfiles file_contexts /
噢不,有错!SELinux 不认识 secret_t 类型。实际上,我们可以动态重新加载 SELinux 策略。不过现在为了简单起见,我们还是重新启动 QEMU 映像好了。当然,由于我们没有安装引导程序,因此简单地重新启动并不能正常工作。因此,我们需要输入 poweroff 关闭 QEMU 映像。如果窗口在打印 “Power down” 之后就没有显示了,请使用 Ctrl-c 来中断 qemu 命令。重新运行 qemu 命令来重新启动它。然后尝试再次运行上面的 setfiles 命令。
验证策略的重新加载正确工作了:
showctx / /secret /secret/helloworld /secret/dontlookcat /secret/dontlook
不过等一会儿!您可以看到秘密类型了。
这是一个编译时内核选项 CONFIG_SECURITY_SELINUX_DEVELOP 的结果。这个选项默认将 SELinux 设置为非强制状态。要验证这个设置,请输入:
cat /selinux/enforce
这应该会返回 0。要将 SELinux 设置成强制模式,请输入:
echo 1 > /selinux/enforce
如果希望,您可以在系统引导时通过 init 脚本来自动实现这种功能,如清单 13 所示;或者简单地编译一个没有  SELINUX_DEVELOP 支持的内核。
清单 13. 在引导时将 SELinux 设置成强制模式
1
2
3
4
5
6
cat >> /etc/rc.d/selinux-enforce << EOF
#!/bin/sh
echo 1 > /selinux/enforce
EOF
chmod ugo+x /etc/rc.d/selinux-enforce
rc-update add default selinux-enforce




现在 SELinux 已经处于强制模式了,请再试图浏览 /secret 下面的内容。注意,尽管进程上下文有权读取 /secret/helloworld,但实际上您并不能真正读取它,因为无法通过 /secret。当然,创建一个到这个文件的硬链接可以跳过这个问题。
返回列表