runsisi's

technical notes

SELinux 宏与接口

2019-01-19 runsisi#selinux

在定义 SELinux 访问规则时,可以手写 allow 规则,也可以使用 SELinux 预定义的宏(policy/support)或 SELinux 模块(policy/modules 或第三方模块)暴露出来的接口,通过 interface 暴露出来的接口作用类似于宏,其实接口定义中也大量用到了预定义宏。

github 上的 SELinux Reference Policy 项目定义了大量的宏和接口,它是 CentOS selinux-policy-targeted 安装包的上游项目 。

通过下面的实例应该能够大致理解 SELinux 的宏定义:

# policy/support/obj_perm_sets.spt
define(`rw_dir_perms', `{ open read getattr lock search ioctl add_name remove_name write }')
define(`manage_sock_file_perms',`{ create open getattr setattr read write rename link unlink ioctl lock append }')

# policy/support/file_patterns.spt
define(`manage_sock_files_pattern',`
    allow $1 $2:dir rw_dir_perms;
    allow $1 $3:sock_file manage_sock_file_perms;
')

# policy/modules/services/virt.te
manage_sock_files_pattern(virtd_t, virt_var_run_t, virt_var_run_t)

通过下面的实例应该能够大致理解 SELinux 的接口定义:

# ceph/ceph/selinux/ceph.if
interface(`ceph_read_log',`
    gen_require(`
        type ceph_log_t;
    ')

    logging_search_logs($1)
    read_files_pattern($1, ceph_log_t, ceph_log_t)
')

# policy/modules/system/logging.if
interface(`logging_search_logs',`
    gen_require(`
        type var_log_t;
    ')

    files_search_var($1)
    allow $1 var_log_t:dir search_dir_perms;
    allow $1 var_log_t:lnk_file read_lnk_file_perms;
')

# policy/modules/kernel/files.if
interface(`files_search_var',`
    gen_require(`
        type var_t;
    ')

    allow $1 var_t:dir search_dir_perms;
')

# policy/support/obj_perm_sets.spt
define(`search_dir_perms',`{ getattr search open }')

# policy/support/file_patterns.spt
define(`read_files_pattern',`
    allow $1 $2:dir search_dir_perms;
    allow $1 $3:file read_file_perms;
')

要注意到 SELinux Reference Policy 同时也存在大量的 fc(file context)、te(type enforcement)定义,如:

# policy/modules/kernel/files.fc
/var/run/.* gen_context(system_u:object_r:var_run_t,s0)

# policy/modules/kernel/files.te
type var_lock_t;
files_lock_file(var_lock_t)
files_mountpoint(var_lock_t)

为了让 OpenStack 的 Glance、Cinder、Libvirt 等创建 Ceph 的客户端 admin client,可以添加如下的规则:

diff --git a/selinux/ceph.te b/selinux/ceph.te
index a56eb6a55abc9ace03e5ede6d97f3513a2e8f326..cadec918bc94e6550237d5e99f9e9ff24c666765 100644
--- a/selinux/ceph.te
+++ b/selinux/ceph.te
@@ -7,6 +7,10 @@ require {
    type urandom_device_t;
    type setfiles_t;
    type nvme_device_t;
+   type virtd_t;
+   type glance_api_t;
+   type cinder_api_t;
+   type cinder_volume_t;
    class sock_file unlink;
    class lnk_file read;
    class dir read;
@@ -121,3 +125,12 @@ fsadm_manage_pid(ceph_t)

 #============= setfiles_t ==============
 allow setfiles_t ceph_var_lib_t:file write;
+
+########################################
+#
+# for OpenStack components
+#
+manage_sock_files_pattern(virtd_t, ceph_var_run_t, ceph_var_run_t)
+manage_sock_files_pattern(glance_api_t, ceph_var_run_t, ceph_var_run_t)
+manage_sock_files_pattern(cinder_api_t, ceph_var_run_t, ceph_var_run_t)
+manage_sock_files_pattern(cinder_volume_t, ceph_var_run_t, ceph_var_run_t)

参考资料

[1] SELinux Reference Policy

https://github.com/SELinuxProject/refpolicy/tree/master/policy

[2] ObjectClassesPerms

http://selinuxproject.org/page/ObjectClassesPerms

[3] PolicyLanguage

http://selinuxproject.org/page/PolicyLanguage