2009-10-27 12:45:10

by Craig.Grube

[permalink] [raw]
Subject: [refpolicy] new service_puppet.patch

I'm not sure if the previous patch I submitted got lost in the noise,
so I thought I would submit it one more time.

Attached is a patch introducing a new module for the Puppet
configuration management system client and server services.

--
Craig Grube
craig.grube at cobham.com

-------------- next part --------------
A non-text attachment was scrubbed...
Name: puppet.patch
Type: application/octet-stream
Size: 13608 bytes
Desc: not available
Url : http://oss.tresys.com/pipermail/refpolicy/attachments/20091027/4f9e6bab/attachment.obj
-------------- next part --------------


2009-10-27 13:18:56

by cpebenito

[permalink] [raw]
Subject: [refpolicy] new service_puppet.patch

On Tue, 2009-10-27 at 08:45 -0400, Craig Grube wrote:
> From dc34f726bc7f5ce430fb9253547a543c427c6602 Mon Sep 17 00:00:00 2001
> From: Craig Grube <[email protected]>
> Date: Wed, 23 Sep 2009 19:25:04 -0400
> Subject: [PATCH 1/1] introduction of policy for Puppet configuration management system

Comments inline. I was working on my own puppet policy, so I have
additional insight into this. Also, it is preferred that you send the
patch you get from "git format-patch" via "git send-email" so that the
patch can be easily applied via git am.

>
> Signed-off-by: Craig Grube <[email protected]>
> ---
> policy/modules/admin/usermanage.te | 8 +
> policy/modules/kernel/corenetwork.te.in | 1 +
> policy/modules/services/puppet.fc | 13 ++
> policy/modules/services/puppet.if | 51 +++++++
> policy/modules/services/puppet.te | 225 +++++++++++++++++++++++++++++++
> policy/modules/system/init.if | 20 +++
> policy/modules/system/init.te | 4 +
> policy/modules/system/libraries.te | 5 +
> 8 files changed, 327 insertions(+), 0 deletions(-)
> create mode 100644 policy/modules/services/puppet.fc
> create mode 100644 policy/modules/services/puppet.if
> create mode 100644 policy/modules/services/puppet.te
>
> diff --git a/policy/modules/admin/usermanage.te b/policy/modules/admin/usermanage.te
> index 1865872..e8c66c1 100644
> --- a/policy/modules/admin/usermanage.te
> +++ b/policy/modules/admin/usermanage.te
> @@ -247,6 +247,10 @@ optional_policy(`
> rpm_rw_pipes(groupadd_t)
> ')
>
> +optional_policy(`
> + puppet_write_puppet_tmp(groupadd_t)
> +')
> +
> ########################################
> #
> # Passwd local policy
> @@ -524,3 +528,7 @@ optional_policy(`
> rpm_use_fds(useradd_t)
> rpm_rw_pipes(useradd_t)
> ')
> +
> +optional_policy(`
> + puppet_write_puppet_tmp(useradd_t)
> +')
> diff --git a/policy/modules/kernel/corenetwork.te.in b/policy/modules/kernel/corenetwork.te.in
> index 9d100fe..3fa5007 100644
> --- a/policy/modules/kernel/corenetwork.te.in
> +++ b/policy/modules/kernel/corenetwork.te.in
> @@ -155,6 +155,7 @@ network_port(prelude, tcp,4690,s0, udp,4690,s0)
> network_port(printer, tcp,515,s0)
> network_port(ptal, tcp,5703,s0)
> network_port(pulseaudio, tcp,4713,s0)
> +network_port(puppet, tcp, 8140, s0)
> network_port(pxe, udp,4011,s0)
> network_port(pyzor, udp,24441,s0)
> network_port(radacct, udp,1646,s0, udp,1813,s0)
> diff --git a/policy/modules/services/puppet.fc b/policy/modules/services/puppet.fc
> new file mode 100644
> index 0000000..8cc04c3
> --- /dev/null
> +++ b/policy/modules/services/puppet.fc
> @@ -0,0 +1,13 @@
> +/etc/puppet(/.*)? gen_context(system_u:object_r:puppet_etc_t, s0)
> +
> +/etc/rc\.d/init\.d/puppet -- gen_context(system_u:object_r:puppet_initrc_exec_t, s0)
> +/etc/rc\.d/init\.d/puppetmaster -- gen_context(system_u:object_r:puppetmasterd_initrc_exec_t, s0)
> +
> +/usr/sbin/puppetd -- gen_context(system_u:object_r:puppet_exec_t, s0)
> +/usr/sbin/puppetmasterd -- gen_context(system_u:object_r:puppetmaster_exec_t, s0)
> +
> +/var/lib/puppet(/.*)? gen_context(system_u:object_r:puppet_var_lib_t, s0)
> +/var/log/puppet(/.*)? gen_context(system_u:object_r:puppet_log_t, s0)
> +/var/run/puppet(/.*)? gen_context(system_u:object_r:puppet_var_run_t, s0)
> +
> +
> diff --git a/policy/modules/services/puppet.if b/policy/modules/services/puppet.if
> new file mode 100644
> index 0000000..9c19661
> --- /dev/null
> +++ b/policy/modules/services/puppet.if
> @@ -0,0 +1,51 @@
> +## <summary>Puppet client daemon</summary>
> +## <desc>
> +## <p>
> +## Puppet is a configuration management system written in Ruby.
> +## The client daemon is responsible for periodically requesting the
> +## desired system state from the server and ensuring the state of
> +## the client system matches.
> +## </p>
> +## </desc>
> +
> +################################################
> +## <summary>
> +## Read / Write to Puppet temp files. Puppet uses
> +## some system binaries (groupadd, etc) that run in
> +## a non-puppet domain and redirects output into temp
> +## files.
> +## </summary>
> +## <param name="domain">
> +## <summary>
> +## Domain allowed access
> +## </summary>
> +## </param>
> +##
> +interface(`puppet_write_puppet_tmp', `
> + gen_require(`
> + type puppet_tmp_t;
> + ')
> +
> + allow $1 puppet_tmp_t:file rw_file_perms;
> + files_search_tmp($1)
> +')
> +
> +
> +##################################################
> +## <summary>
> +## Allow attempts to use puppet file descriptors
> +## Occurs when puppet redirects program output to
> +## /dev/null
> +## </summary>
> +## <param name="domain">
> +## <summary>
> +## Domain allowed access
> +## </summary>
> +## </param>
> +##
> +interface(`puppet_fd_use', `
> + gen_require(`
> + type puppet_t;
> + ')
> + allow $1 puppet_t:fd use;
> +')
> diff --git a/policy/modules/services/puppet.te b/policy/modules/services/puppet.te
> new file mode 100644
> index 0000000..60c68a6
> --- /dev/null
> +++ b/policy/modules/services/puppet.te
> @@ -0,0 +1,225 @@
> +
> +policy_module(puppet, 0.0.1)
> +
> +########################################
> +#
> +# Puppet personal declarations
> +#
> +
> +type puppet_t;
> +type puppet_exec_t;
> +init_daemon_domain(puppet_t, puppet_exec_t)
> +
> +type puppet_initrc_exec_t;
> +init_script_file(puppet_initrc_exec_t);
> +
> +type puppet_log_t;
> +logging_log_file(puppet_log_t)
> +
> +type puppet_var_lib_t;
> +files_type(puppet_var_lib_t)
> +
> +type puppet_var_run_t;
> +files_pid_file(puppet_var_run_t)
> +
> +type puppet_etc_t;
> +files_config_file(puppet_etc_t)
> +
> +type puppet_tmp_t;
> +files_tmp_file(puppet_tmp_t)
> +
> +########################################
> +#
> +# Pupper master personal declarations
> +#
> +
> +type puppetmaster_t;
> +type puppetmaster_exec_t;
> +init_daemon_domain(puppetmaster_t, puppetmaster_exec_t)
> +
> +type puppetmasterd_initrc_exec_t;
> +init_script_file(puppetmasterd_initrc_exec_t)
> +
> +type puppetmaster_tmp_t;
> +files_tmp_file(puppetmaster_tmp_t)
> +
> +########################################
> +#
> +# Puppet personal policy
> +#
> +
> +allow puppet_t self:capability { sys_admin fowner fsetid setuid setgid sys_rawio dac_override sys_nice sys_ptrace sys_tty_config };

I didn't have all these capabilities, and I'm concerned that its far too
much, as if some tools were just exec'ed instead of transitioned --
especially sys_rawio and sys_admin.

> +allow puppet_t self:fifo_file rw_fifo_file_perms;
> +allow puppet_t self:netlink_route_socket create_netlink_socket_perms;
> +allow puppet_t self:process { signal signull getsched setsched };
> +allow puppet_t self:tcp_socket create_stream_socket_perms;
> +allow puppet_t self:udp_socket create_socket_perms;
> +
> +search_dirs_pattern(puppet_t, puppet_etc_t, puppet_etc_t)
> +read_files_pattern(puppet_t, puppet_etc_t, puppet_etc_t)
> +
> +manage_dirs_pattern(puppet_t ,puppet_var_lib_t, puppet_var_lib_t)
> +manage_files_pattern(puppet_t, puppet_var_lib_t, puppet_var_lib_t)
> +
> +rw_dirs_pattern(puppet_t, puppet_var_run_t, puppet_var_run_t)

Redundant

> +setattr_dirs_pattern(puppet_t, puppet_var_run_t, puppet_var_run_t)
> +manage_files_pattern(puppet_t, puppet_var_run_t, puppet_var_run_t)
> +files_pid_filetrans(puppet_t, puppet_var_run_t, { file dir })
> +
> +manage_dirs_pattern(puppet_t, puppet_tmp_t, puppet_tmp_t)
> +manage_files_pattern(puppet_t, puppet_tmp_t, puppet_tmp_t)
> +files_tmp_filetrans(puppet_t, puppet_tmp_t, { file dir })
> +
> +auth_manage_all_files_except_shadow(puppet_t)
> +auth_relabel_all_files_except_shadow(puppet_t)

I think this is extremely excessive; it should be conditional. Instead,
I think the best default would be to start using a config file in the
files module, and have puppet manage all config files as the default
access.

> +corenet_sendrecv_puppet_client_packets(puppet_t)
> +corenet_tcp_connect_puppet_port(puppet_t)
> +
> +corenet_all_recvfrom_netlabel(puppet_t)
> +corenet_all_recvfrom_unlabeled(puppet_t)
> +
> +corenet_tcp_sendrecv_all_if(puppet_t)
> +corenet_tcp_sendrecv_all_nodes(puppet_t)
> +corenet_tcp_bind_all_nodes(puppet_t)

replace "all" with "generic"

> +corecmd_exec_bin(puppet_t)
> +corecmd_exec_shell(puppet_t)
> +
> +dev_read_rand(puppet_t)
> +dev_read_sysfs(puppet_t)
> +dev_read_urand(puppet_t)
> +
> +domain_read_all_domains_state(puppet_t)
> +domain_interactive_fd(puppet_t)
> +
> +files_read_etc_files(puppet_t)
> +
> +init_all_labeled_script_domtrans(puppet_t)
> +init_domtrans_script(puppet_t)
> +init_read_utmp(puppet_t)
> +init_signull_script(puppet_t)
> +
> +kernel_dontaudit_search_sysctl(puppet_t)
> +kernel_dontaudit_search_kernel_sysctl(puppet_t)
> +kernel_read_system_state(puppet_t)
> +kernel_read_crypto_sysctls(puppet_t)
> +
> +logging_send_syslog_msg(puppet_t)
> +
> +miscfiles_read_hwdata(puppet_t)
> +miscfiles_read_localization(puppet_t)
> +
> +selinux_search_fs(puppet_t)
> +selinux_set_all_booleans(puppet_t)
> +selinux_set_generic_booleans(puppet_t)
> +selinux_validate_context(puppet_t)
> +
> +seutil_domtrans_setfiles(puppet_t)
> +seutil_domtrans_semanage(puppet_t)
> +seutil_manage_default_contexts(puppet_t)

> +seutil_manage_file_contexts(puppet_t)

Why would this be necessary? The file contexts should be semanage.
Local changes to the file contexts should also be made through semanage.

> +
> +sysnet_dns_name_resolve(puppet_t)
> +sysnet_run_ifconfig(puppet_t, system_r)
> +
> +term_dontaudit_getattr_unallocated_ttys(puppet_t)
> +term_dontaudit_getattr_all_user_ttys(puppet_t)
> +
> +optional_policy(`
> + consoletype_domtrans(puppet_t)
> +')
> +
> +optional_policy(`
> + hostname_exec(puppet_t)
> +')
> +
> +optional_policy(`
> + rpm_domtrans(puppet_t)
> +')
> +
> +optional_policy(`
> + unconfined_domain(puppet_t)
> +')
> +
> +optional_policy(`
> + usermanage_domtrans_groupadd(puppet_t)
> + usermanage_domtrans_useradd(puppet_t)
> +')
> +########################################
> +#
> +# Pupper master personal policy
> +#
> +
> +allow puppetmaster_t self:capability { dac_read_search dac_override setuid setgid fowner chown fsetid sys_tty_config };
> +allow puppetmaster_t self:fifo_file rw_fifo_file_perms;;
> +allow puppetmaster_t self:netlink_route_socket create_netlink_socket_perms;
> +allow puppetmaster_t self:process signal_perms;
> +allow puppetmaster_t self:socket create;
> +allow puppetmaster_t self:tcp_socket create_stream_socket_perms;
> +allow puppetmaster_t self:udp_socket create_socket_perms;
> +
> +list_dirs_pattern(puppetmaster_t, puppet_etc_t, puppet_etc_t)
> +read_files_pattern(puppetmaster_t, puppet_etc_t, puppet_etc_t)
> +
> +manage_dirs_pattern(puppetmaster_t ,puppet_var_lib_t, puppet_var_lib_t)
> +manage_files_pattern(puppetmaster_t, puppet_var_lib_t, puppet_var_lib_t)
> +
> +rw_dirs_pattern(puppetmaster_t, puppet_var_run_t, puppet_var_run_t)

Redundant

> +setattr_dirs_pattern(puppetmaster_t, puppet_var_run_t, puppet_var_run_t)
> +manage_files_pattern(puppetmaster_t, puppet_var_run_t, puppet_var_run_t)
> +files_pid_filetrans(puppetmaster_t, puppet_var_run_t, { file dir })
> +
> +rw_dirs_pattern(puppetmaster_t, puppet_log_t, puppet_log_t)
> +setattr_dirs_pattern(puppetmaster_t, puppet_log_t, puppet_log_t)
> +setattr_files_pattern(puppetmaster_t, puppet_log_t, puppet_log_t)
> +create_files_pattern(puppetmaster_t, puppet_log_t, puppet_log_t)
> +append_files_pattern(puppetmaster_t, puppet_log_t, puppet_log_t)
> +rw_files_pattern(puppetmaster_t, puppet_log_t, puppet_log_t)
> +logging_log_filetrans(puppetmaster_t, puppet_log_t, { file dir })
> +
> +manage_dirs_pattern(puppetmaster_t, puppetmaster_tmp_t, puppet_tmp_t)
> +manage_files_pattern(puppetmaster_t, puppetmaster_tmp_t, puppet_tmp_t)
> +files_tmp_filetrans(puppetmaster_t, puppetmaster_tmp_t, { file dir })
> +
> +corenet_sendrecv_puppet_server_packets(puppetmaster_t)
> +corenet_tcp_bind_puppet_port(puppetmaster_t)
> +
> +corenet_all_recvfrom_netlabel(puppetmaster_t)
> +corenet_all_recvfrom_unlabeled(puppetmaster_t)
> +
> +corenet_tcp_sendrecv_all_if(puppetmaster_t)
> +corenet_tcp_sendrecv_all_nodes(puppetmaster_t)
> +corenet_tcp_bind_all_nodes(puppetmaster_t)

replace "all" with "generic".

> +
> +corecmd_exec_bin(puppetmaster_t)
> +corecmd_exec_shell(puppetmaster_t)
> +
> +files_read_etc_files(puppetmaster_t)
> +
> +dev_read_rand(puppetmaster_t)
> +dev_read_urand(puppetmaster_t)
> +
> +domain_read_all_domains_state(puppetmaster_t)
> +
> +kernel_dontaudit_search_kernel_sysctl(puppetmaster_t)
> +kernel_read_system_state(puppetmaster_t)
> +kernel_read_crypto_sysctls(puppetmaster_t)
> +
> +logging_send_syslog_msg(puppetmaster_t)
> +
> +miscfiles_read_localization(puppetmaster_t)
> +
> +sysnet_dns_name_resolve(puppetmaster_t)
> +sysnet_run_ifconfig(puppetmaster_t, system_r)
> +
> +optional_policy(`
> + hostname_exec(puppetmaster_t)
> +')
> +
> +optional_policy(`
> + rpm_domtrans(puppetmaster_t)
> + rpm_read_db(puppetmaster_t)
> +')

What is the puppetmaster doing with rpm?

> diff --git a/policy/modules/system/init.if b/policy/modules/system/init.if
> index 7637333..aa9f136 100644
> --- a/policy/modules/system/init.if
> +++ b/policy/modules/system/init.if
> @@ -720,6 +720,26 @@ interface(`init_labeled_script_domtrans',`
> files_search_etc($1)
> ')
>
> +#########################################
> +## <summary>
> +## Transition to the init script domain
> +## for all labeled init script types
> +## </summary>
> +## <param name="domain">
> +## <summary>
> +## Domain allowed access
> +## </summary>
> +## </param>
> +#########################################
> +interface(`init_all_labeled_script_domtrans',`
> + gen_require(`
> + attribute init_script_file_type;
> + ')
> +
> + init_labeled_script_domtrans($1, init_script_file_type)
> +')
> +
> +
> ########################################
> ## <summary>
> ## Start and stop daemon programs directly.
> diff --git a/policy/modules/system/init.te b/policy/modules/system/init.te
> index efe5277..6770b40 100644
> --- a/policy/modules/system/init.te
> +++ b/policy/modules/system/init.te
> @@ -688,6 +688,10 @@ optional_policy(`
> ')
>
> optional_policy(`
> + puppet_write_puppet_tmp(initrc_t)
> +')
> +
> +optional_policy(`
> quota_manage_flags(initrc_t)
> ')
>
> diff --git a/policy/modules/system/libraries.te b/policy/modules/system/libraries.te
> index 0c4f4ba..8989eb3 100644
> --- a/policy/modules/system/libraries.te
> +++ b/policy/modules/system/libraries.te
> @@ -123,3 +123,8 @@ optional_policy(`
> # blow up.
> rpm_manage_script_tmp_files(ldconfig_t)
> ')
> +
> +
> +optional_policy(`
> + puppet_write_puppet_tmp(ldconfig_t)
> +')
> --
> 1.6.2.5


--
Chris PeBenito
Tresys Technology, LLC
(410) 290-1411 x150

2009-10-30 12:31:20

by Craig.Grube

[permalink] [raw]
Subject: [refpolicy] new service_puppet.patch

I'll send a patch out later today using git send-email as requested.

On Oct 27, 2009, at 9:18 AM, Christopher J. PeBenito wrote:
> On Tue, 2009-10-27 at 08:45 -0400, Craig Grube wrote:
>>
>> +auth_manage_all_files_except_shadow(puppet_t)
>> +auth_relabel_all_files_except_shadow(puppet_t)
>
> I think this is extremely excessive; it should be conditional.
> Instead,
> I think the best default would be to start using a config file in the
> files module, and have puppet manage all config files as the default
> access.

Added a new boolean that is off by default as suggested. I was getting
a syntax error when using auth_relabel_all_files_except_shadow inside
of a tunable_policy block so I dropped it.

>> +seutil_domtrans_setfiles(puppet_t)
>> +seutil_domtrans_semanage(puppet_t)
>> +seutil_manage_default_contexts(puppet_t)
>
>> +seutil_manage_file_contexts(puppet_t)
>
> Why would this be necessary? The file contexts should be semanage.
> Local changes to the file contexts should also be made through
> semanage.

Probably put it in before I added the domain transition for semanage.
I didn't have
issues pulling it out.

>>
>> +optional_policy(`
>> + rpm_domtrans(puppetmaster_t)
>> + rpm_read_db(puppetmaster_t)
>> +')
>
> What is the puppetmaster doing with rpm?

This doesn't appear to be necessary for newer versions of puppet. The
version
I was using when I first started working on the policy used rpm to
list installed
packages.

--
Craig Grube
craig.grube at cobham.com

2009-10-30 14:40:55

by Craig.Grube

[permalink] [raw]
Subject: [refpolicy] new service_puppet.patch


On Oct 30, 2009, at 8:31 AM, Craig Grube wrote:
> On Oct 27, 2009, at 9:18 AM, Christopher J. PeBenito wrote:
>> On Tue, 2009-10-27 at 08:45 -0400, Craig Grube wrote:
>>> +optional_policy(`
>>> + rpm_domtrans(puppetmaster_t)
>>> + rpm_read_db(puppetmaster_t)
>>> +')
>>
>> What is the puppetmaster doing with rpm?
>
> This doesn't appear to be necessary for newer versions of puppet.
> The version
> I was using when I first started working on the policy used rpm to
> list installed
> packages.


This was a little premature. After letting puppetmaster run a bit
longer I was able
to get rpm related AVCs to pop up. I don't know why it didn't appear
sooner as I removed
the optional_policy block from my policy a couple of days ago. I
think using rpm_exec
and rpm_read_db should give puppetmaster what wants without letting it
transition
into the rpm domain.

--
Craig Grube
craig.grube at cobham.com