[colug-432] Puppet + Subversion + SELinux

Scott Merrill skippy at skippy.net
Thu Feb 24 11:42:38 EST 2011


We're looking at revamping our Puppet configuration:

* we'd like to move to a new server running RHEL6.
* we'd like to use a post-commit hook to have all SVN check-ins
automatically update the live configuration.
* we'd like to use SELinux in enforcing mode.

The first part is easy, and done. The second part is a little tricky
because of the third part.

The default location for the puppetmaster files is /etc/puppet. The
Subversion repository we're using is stored on the same server, so I
made a check-out of our files into /etc/puppet:
$ cd /etc/puppet
$ sudo svn co file:///usr/local/svn/puppet .

I checked out the Puppet repository onto my local workstation, so I
can work on the files there, and then commit them back. That works
fine.

So I set up the following post-commit hook for the Puppet repository:

#!/bin/sh
# update the local checkout of Puppet manifests
export HOME=/tmp
REPOS="$1"
REV="$2"
/usr/bin/svn up /etc/puppet

I access the repository from my workstation over https using Apache's
mod_dav_svn, so the post-commit hook runs as the Apache user. This
means the Apache user needs write access to /etc/puppet. That's an
easy chmod. But even after that, the post-commit hook failed with a
permission denied problem. So I chown'ed the files to Apache, but
still no luck writing there.

The SELinux context on /etc/puppet is system_u:object_r:puppet_etc_t,
and SELinux's audit log confirms that Apache, via httpd_sys_script_t,
does not have permission to do the necessary operations inside
/etc/puppet.

Through a series of iterations with "ausearch -m avc -ts recent |
audit2allow -r", I worked up the following SELinux policy module:

module local 1.0;

require {
	type httpd_sys_script_t;
	type puppet_etc_t;
	class file { rename setattr unlink write };
	class dir remove_name;
}

#============= httpd_sys_script_t ==============
allow httpd_sys_script_t puppet_etc_t:file rename;
allow httpd_sys_script_t puppet_etc_t:file setattr;
allow httpd_sys_script_t puppet_etc_t:file unlink;
allow httpd_sys_script_t puppet_etc_t:file write;
allow httpd_sys_script_t puppet_etc_t:dir remove_name;

As root, I built and installed the module using these commands:
# checkmodule -M -m -o local.mod local.te
# semodule_package -o local.pp -m local.mod
# semodule -i local.pp

Now my post-commit hook works as expected: /etc/puppet is updated
whenever I commit something to the repository from my workstation.

My questions are:
* is my policy too permissive?
* what alternatives might exist to this solution?
* are there any subtle gotchas that might cause trouble?

This is my first time writing an SELinux policy, so I'd like some
feedback on it.

Thanks,
Scott


More information about the colug-432 mailing list