前些天我做了一个大胆的尝试,将非Debian的SELinux Policy,放到Debian 8上,试图激活它。结果失败了。但是在探索的过程中发现了一个有趣的东西。
1. 首先获取源码:
git clone https://github.com/sjvermeu/hardened-refpolicy.git
2. 编译
a)make conf
b)make policy
这时出现了错误:
/usr/bin/checkmodule -m tmp/kdeconnect.tmp -o tmp/kdeconnect.mod
/usr/bin/checkmodule: loading policy configuration from tmp/kdeconnect.tmp
policy/modules/contrib/kdeconnect.te:70:ERROR 'syntax error' at token 'corenet_s
endrecv_kdeconnect_client_packets' on line 3295:
corenet_sendrecv_kdeconnect_client_packets(kdeconnect_t)
/usr/bin/checkmodule: error(s) encountered while parsing configuration
Rules.modular:74: recipe for target 'tmp/kdeconnect.mod' failed
make: *** [tmp/kdeconnect.mod] Error 1
修改方法很简单,反正我也不用kde,不编译它就可以了:
修改 policy/modules.conf,将
kdeconnect = module
改为
kdeconnect = off
3. 安装和加载
make install
make load
在load过程中,又碰到了错误:
第一个错误:
libsepol.print_missing_requirements: bitcoin's global requirements were not met:
type/attribute init_script_readable (No such file or directory).
libsemanage.semanage_link_sandbox: Link packages failed (No such file or directo
ry).
/usr/sbin/semodule: Failed!
Rules.modular:56: recipe for target 'load' failed
make: *** [load] Error 1
修改方式和前面的kdeconnect类似,在policy/modules.conf中:
bitcoin = module
改为
bitcoin = off
第二个错误,比较普遍,这类错误反复出现:
libsepol.print_missing_requirements: salt's global requirements were not met: ty
pe/attribute rc_exec_t (No such file or directory).
libsemanage.semanage_link_sandbox: Link packages failed (No such file or directory).
/usr/sbin/semodule: Failed!
Rules.modular:56: recipe for target 'load' failed
make: *** [load] Error 1
type rc_exec_t;
domain_entry_file(initrc_t, rc_exec_t)
')
domain_entry_file(initrc_t, rc_exec_t)
4. 测试SELinux策略
a)修改配置文件
编辑 /etc/selinux/config, 选择刚刚被安装加载的SELinux策略:
SELINUXTYPE=refpolicy
b)重新启动,提供启动参数“security=selinux enforcing=0”
c) 查看log
dmesg | grep "permissive=1"
会出现大量的错误,举一个例子:
[ 117.398873] audit: type=1400 audit(1493972806.808:13): avc: denied { transition } for pid=703 comm="login" path="/bin/bash" dev="sda1" ino=130697 scontext=system_u:system_r:kernel_t tcontext=root:sysadm_r:sysadm_t tclass=process permissive=1
提取有用的信息:
{ transition } scontext=system_u:system_r:kernel_t tcontext=root:sysadm_r:sysadm_t tclass=proces
问题的原因是login进程不应该处在kernel_t这个域之中。深层的原因是整个文件系统中的文件都没有设置正确的安全上下文。执行:
restorecon -R
下一个错误:
[ 2.230993] audit: type=1400 audit(1493974525.676:3): avc: denied { dyntransition } for pid=1 comm="systemd" scontext=system_u:system_r:kernel_t tcontext=system_u:system_r:init_t tclass=process permissive=1
提取有用的信息:
{ dyntransition } scontext=system_u:system_r:kernel_t tcontext=system_u:system_r:init_t tclass=process
对应的策略是:
allow kernel_t init_t:process dyntransition ;
将这条策略加入相关的策略文件,重新编译/安装/加载。反复操作,去除了几十个错误之后,似乎在permissive模式下已经见不到错误了。下面进入下一步,在enforcing模式下测试SELinux策略。
5. 进入enforcing模式
重新启动,提供启动参数“security=selinux enforcing=1”
启动失败,得到下面这类错误:
[ 3.138072] audit: type=1107 audit(1494035792.640:5): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t msg='Unknown permission status for class system exe="/lib/systemd/systemd" sauid=0 hostname=? addr=? terminal=?'
这不是一条内核产生的消息,这是用户态进程systemd产生的消息。systemd在启动过程中需要名字为“system”的客体类别上的“status”操作。但是内核中的SELinux不支持在system上的status操作。所以错误消息是:Unknown permission status for class system 。
简而言之,Debian 8的systemd和内核在SELinux方面不匹配!!!
那么,为什么在permissive模式下没有这条错误呢?因为systemd的代码逻辑,systemd只会在SELinux处于enforcing模式下才会进行一些深入的工作。
more information: www.zhian-tech.com