[Pacemaker] [RFC] working selinux policy module for pacemaker
Vladislav Bogdanov
bubble at hoster-ok.com
Wed Dec 19 08:33:59 UTC 2012
Hi all,
I'd like to share my successful attempt to confine pacemaker.
I took pacemaker module barebone found in latest fedora's selinux-policy (3.11.1-64.fc18) and
extended it a bit, so now I have pacemaker and some pacemaker-managed services
running confined.
Everything runs on EL6 with corosync-2.2 and latest master. Services include:
* dlm_controld (4.0.0)
* gfs_controld (I wrote before that I had success porting it to corosync-2 and dlm-4)
* clvmd
* drbd (8.3.14 with crm_fence_peer updated to work with 1.1.8 and above)
* clustered LVM VG on top of drbd device running active/active
* GFS filesystem on LVM LV
What differs from fedora policy module:
* lrmd runs in init_t domain. This includes:
** label lrmd as init_exec_t
** allow process domain transition from pacemaker_t to init_t for entry
files labeled with init_exec_t
** allow init_t processes communicate with pacemaker_t processes via UNIX
domain socket
** allow pacemaker_t to send signals to init_t to stop lrmd (this is probably
weak, but I do not see better solution right now)
** label SHM channel created by init_t process with pacemaker_tmpfs_t
* OCF scripts are labeled as initrc_exec_t (this actually has nothing to
pacemaker module, so I packaged this separately)
* pacemaker_t is allowed to do setattr on corosync_var_run_t:dir (this one is a
minor change to allow chown(/var/run/heartbeat) and could be replaced with
dontaudit)
* pacemaker_t is allowed to search, list, read and execute initrc_exec_t files
and dirs (this is needed by crmd)
* pacemaker_t is allowed to do transition to drbd domain (to run drbd OCF script
which has its own label, drbd_exec_t) (needed for crmd)
* allow pacemaker_t to read usr_t files (to load schemas)
As I run on EL6, I included two more changes to make it compile and work:
* comment everything about systemd
* allow pacemaker_t to load locale files
I also included some more "fixes" in a separate policy module.
* introduce corosync_rw_tmpfs interface (backport from fedora and extend a bit)
* allow dlm_controld to communicate with corosync via UNIX sockets and SHM (this
is probably included in fedora, I did not check)
* allow gfs_controld to communicate with corosync via UNIX sockets and SHM (this
one is EL6-specific and requires gfs_contold working with corosync-2)
* allow clvmd to communicate with corosync via SHM
* fixes for dlm_controld-4.0 (labels for config and pid files)
* labels for /usr/lib/ocf (I wrote above about it)
Here is a pacemaker module (diff to fedora's one):
===
diff -urNp selinux/pacemaker/3.11.1/pacemaker.fc selinux-pacemaker-1.0.9/pacemaker.fc
--- selinux/pacemaker/3.11.1/pacemaker.fc 2012-12-17 12:08:57.000000000 +0000
+++ selinux-pacemaker-1.0.9/pacemaker.fc 2012-12-18 06:54:16.875165943 +0000
@@ -1,9 +1,11 @@
/etc/rc\.d/init\.d/pacemaker -- gen_context(system_u:object_r:pacemaker_initrc_exec_t,s0)
-/usr/lib/systemd/system/pacemaker.* -- gen_context(system_u:object_r:pacemaker_unit_file_t,s0)
+#/usr/lib/systemd/system/pacemaker.* -- gen_context(system_u:object_r:pacemaker_unit_file_t,s0)
/usr/sbin/pacemakerd -- gen_context(system_u:object_r:pacemaker_exec_t,s0)
+/usr/libexec/pacemaker/lrmd -- gen_context(system_u:object_r:init_exec_t,s0)
+
/var/lib/heartbeat/crm(/.*)? gen_context(system_u:object_r:pacemaker_var_lib_t,s0)
/var/lib/pacemaker(/.*)? gen_context(system_u:object_r:pacemaker_var_lib_t,s0)
diff -urNp selinux/pacemaker/3.11.1/pacemaker.te selinux-pacemaker-1.0.9/pacemaker.te
--- selinux/pacemaker/3.11.1/pacemaker.te 2012-12-17 12:08:57.000000000 +0000
+++ selinux-pacemaker-1.0.9/pacemaker.te 2012-12-18 08:30:51.933102744 +0000
@@ -1,4 +1,4 @@
-policy_module(pacemaker, 1.0.0)
+policy_module(pacemaker, 1.0.9)
########################################
#
@@ -7,6 +7,7 @@ policy_module(pacemaker, 1.0.0)
type pacemaker_t;
type pacemaker_exec_t;
+
init_daemon_domain(pacemaker_t, pacemaker_exec_t)
type pacemaker_initrc_exec_t;
@@ -24,8 +25,13 @@ files_tmp_file(pacemaker_tmp_t)
type pacemaker_tmpfs_t;
files_tmpfs_file(pacemaker_tmpfs_t)
-type pacemaker_unit_file_t;
-systemd_unit_file(pacemaker_unit_file_t)
+#type pacemaker_unit_file_t;
+#systemd_unit_file(pacemaker_unit_file_t)
+
+gen_require(`
+ type initrc_exec_t;
+ type corosync_var_run_t;
+')
########################################
#
@@ -60,6 +66,30 @@ kernel_read_messages(pacemaker_t)
kernel_getattr_core_if(pacemaker_t)
kernel_read_software_raid_state(pacemaker_t)
+# For mcp_chown(HA_STATE_DIR "/heartbeat", pcmk_uid, pcmk_gid);
+allow pacemaker_t corosync_var_run_t:dir { setattr };
+
+# crmd gathers metadata from OCF scripts
+allow pacemaker_t initrc_exec_t:dir list_dir_perms;
+init_getattr_script_files(pacemaker_t)
+init_read_script_files(pacemaker_t)
+init_exec_script_files(pacemaker_t)
+# drbd OCF script has different label (drbd_exec_t)
+drbd_domtrans(pacemaker_t)
+
+# Start lrmd in init_t domain
+init_domtrans(pacemaker_t)
+# Allow communication with it
+init_stream_connect(pacemaker_t)
+# And allow to kill lrmd
+init_signal(pacemaker_t)
+# And label lrmd shm channels as pacemaker_tmpfs_t. I hope this should not interfere with real inits (sysv, upstart, systemd).
+fs_tmpfs_filetrans(init_t, pacemaker_tmpfs_t, { dir file })
+
+# Read schema files
+files_read_usr_files(pacemaker_t)
+
+# Execute pacemaker daemons, rhcs fence agents and various binaries called from OCF scripts run by crmd to get metadata
corecmd_exec_bin(pacemaker_t)
corecmd_exec_shell(pacemaker_t)
@@ -78,6 +108,8 @@ auth_use_nsswitch(pacemaker_t)
logging_send_syslog_msg(pacemaker_t)
+miscfiles_read_localization(pacemaker_t)
+
optional_policy(`
corosync_read_log(pacemaker_t)
corosync_stream_connect(pacemaker_t)
===
And addons to make everything work on EL6:
===
--- /dev/null 2012-08-22 02:58:15.078103358 +0000
+++ selinux-clusterng-addon-0.0.7/clusterng-addon.fc 2012-12-18 07:16:50.179150062 +0000
@@ -0,0 +1,4 @@
+/etc/dlm(/.*)? gen_context(system_u:object_r:dlm_controld_etc_t,s0)
+/var/run/dlm_controld(/.*)? gen_context(system_u:object_r:dlm_controld_var_run_t,s0)
+/var/run/cluster/gfs_controld\.pid gen_context(system_u:object_r:gfs_controld_var_run_t,s0)
+/usr/lib/ocf(/.*)? gen_context(system_u:object_r:initrc_exec_t,s0)
--- /dev/null 2012-08-22 02:58:15.078103358 +0000
+++ selinux-clusterng-addon-0.0.7/clusterng-addon.if 2012-12-18 08:13:51.447113151 +0000
@@ -0,0 +1,19 @@
+######################################
+## <summary>
+## Allow the specified domain to read/write corosync's tmpfs files.
+## </summary>
+## <param name="domain">
+## <summary>
+## Domain allowed access.
+## </summary>
+## </param>
+#
+interface(`corosync_rw_tmpfs',`
+ gen_require(`
+ type corosync_tmpfs_t;
+ ')
+
+ rw_files_pattern($1, corosync_tmpfs_t, corosync_tmpfs_t)
+ delete_files_pattern($1, corosync_tmpfs_t, corosync_tmpfs_t)
+')
+
--- /dev/null 2012-08-22 02:58:15.078103358 +0000
+++ selinux-clusterng-addon-0.0.7/clusterng-addon.te 2012-12-18 08:12:10.434097978 +0000
@@ -0,0 +1,31 @@
+policy_module(clusterng-addon,0.0.7)
+
+type dlm_controld_etc_t;
+files_type(dlm_controld_etc_t)
+
+gen_require(`
+ type corosync_t;
+ type dlm_controld_t;
+ type gfs_controld_t;
+ type clvmd_t;
+')
+
+allow corosync_t self:capability { fowner };
+#corecmd_exec_bin(dlm_controld_t)
+
+# Allow dlm_controld read its config
+read_files_pattern(dlm_controld_t, dlm_controld_etc_t, dlm_controld_etc_t)
+
+optional_policy(`
+ corosync_stream_connect(dlm_controld_t)
+ corosync_rw_tmpfs(dlm_controld_t)
+')
+
+optional_policy(`
+ corosync_stream_connect(gfs_controld_t)
+ corosync_rw_tmpfs(gfs_controld_t)
+')
+
+optional_policy(`
+ corosync_rw_tmpfs(clvmd_t)
+')
===
Related 'ps axfZ' output on an active node is:
unconfined_u:system_r:corosync_t:s0 1711 ? Ssl 0:19 corosync
unconfined_u:system_r:pacemaker_t:s0 1737 pts/1 S 0:00 pacemakerd
unconfined_u:system_r:pacemaker_t:s0 1739 ? Ss 0:01 \_ /usr/libexec/pacemaker/cib
unconfined_u:system_r:pacemaker_t:s0 1740 ? Ss 0:00 \_ /usr/libexec/pacemaker/stonithd
unconfined_u:system_r:init_t:s0 1741 ? Ss 0:00 \_ /usr/libexec/pacemaker/lrmd
unconfined_u:system_r:pacemaker_t:s0 1742 ? Ss 0:00 \_ /usr/libexec/pacemaker/attrd
unconfined_u:system_r:pacemaker_t:s0 1743 ? Ss 0:00 \_ /usr/libexec/pacemaker/pengine
unconfined_u:system_r:pacemaker_t:s0 1744 ? Ss 0:00 \_ /usr/libexec/pacemaker/crmd
unconfined_u:system_r:dlm_controld_t:s0 2648 ? Ssl 0:00 dlm_controld
unconfined_u:system_r:gfs_controld_t:s0 2687 ? Ssl 0:00 gfs_controld
unconfined_u:system_r:clvmd_t:s0 2698 ? SLsl 0:00 /usr/sbin/clvmd -T30 -I corosync
selinux runs in Enforcing mode.
# mount|grep gfs2
/dev/mapper/vg_gfs--test-gfs--test on /cluster/storage/gfs-test-fs type gfs2 (rw,seclabel,relatime,hostdata=jid=0)
So, comments are welcome,
Vladislav
More information about the Pacemaker
mailing list