[Pacemaker] [RFC] working selinux policy module for pacemaker

Vladislav Bogdanov bubble at hoster-ok.com
Wed Dec 19 03:33:59 EST 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