[Pacemaker] [RFC] working selinux policy module for pacemaker
Andrew Beekhof
andrew at beekhof.net
Fri Jan 4 03:07:15 UTC 2013
On Wed, Dec 19, 2012 at 7:33 PM, Vladislav Bogdanov
<bubble at hoster-ok.com> wrote:
> 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.
Sweet. I've passed your amendments on to Milos who is looking after
https://bugzilla.redhat.com/show_bug.cgi?id=801493
>
> 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
>
> _______________________________________________
> Pacemaker mailing list: Pacemaker at oss.clusterlabs.org
> http://oss.clusterlabs.org/mailman/listinfo/pacemaker
>
> Project Home: http://www.clusterlabs.org
> Getting started: http://www.clusterlabs.org/doc/Cluster_from_Scratch.pdf
> Bugs: http://bugs.clusterlabs.org
More information about the Pacemaker
mailing list