By default, all users are running as unconfined, meaning that things act pretty much as if SELinux was disabled. Included in the SELinux policy are 3 SELinux user profiles:
- staff_u: can sudo
- user_u: can do most things regular users can do
- xguest_u: can run X and some applications, but not get on the network
- guest_u: can't even run X, but can move files around
Let's start by writing a new user policy for our gitolite user. I call it mygitoliteuser_u, and the policy will be in the file mygitoliteuser.te:
A few things going on here:policy_module(mygitoliteuser, 1.0.0) require { type system_mail_t; type postfix_postdrop_t; } role mygitoliteuser_r; role mygitoliteuser_r types { system_mail_t postfix_postdrop_t }; userdom_restricted_user_template(mygitoliteuser) gitosis_run(mygitoliteuser_t, mygitoliteuser_r) gen_user(mygitoliteuser_u, user, mygitoliteuser_r, s0, s0)
- We base it off the userdom_restricted_user_template(), which is what guest_u uses.
- We allow it to run gitolite via the gitosis_run() interface.
- We additionally let it send email. Note, that theoretically this should be covered by the mta_role() interface, but it wasn't doing the right thing for me.
make -f /usr/share/selinux/devel/Makefile mygitoliteuser.pp
semodule -i mygitoliteuser.pp
Now set up the contexts for the new mygitoliteuser_u:
cd /etc/selinux/targeted/contexts/users
cat guest_u | sed 's/guest_/mygitoliteuser_/g' > mygitoliteuser_u
Now you need to assign this profile to the gitolite user:
usermod -Z mygitoliteuser_u gitolite
Now here is where things get annoying. Once you do this, don't try to run "restorecon /var/lib/gitolite", as this will screw up the labels on everything in that directory and label it as user_home_t. You see, all currently released versions of semanage assume that if a user has a real shell, its home directory needs to be labelled as user_home_t, which is sane reasoning, but doesn't work for things like gitolite user. There is a fix for this behaviour in libsemanage 2.1.5 -- you can set ignoredirs=/var/lib/gitolite in /etc/selinux/semanage.conf, but this is not helpful on RHEL6.Anyway, the only real solution currently is to set up a cronjob that would make sure that everything in /var/lib/gitolite is labelled as gitosis_var_lib_t. I used puppet for this purpose:
That's about it. I may as well share my tweaks to the default gitosis policy here:file { '/var/lib/gitolite': seltype => 'gitosis_var_lib_t', recurse => true, }
policy_module(mygitosis, 1.0.0) require { type gitosis_t; type gitosis_exec_t; type tmp_t; type ssh_home_t; type bin_t; type fs_t; } # required by fork allow gitosis_t gitosis_exec_t:file execute_no_trans; # used by hooks (usually here-docs) allow gitosis_t tmp_t:dir { write remove_name add_name }; allow gitosis_t tmp_t:file { write getattr read create unlink open }; # these appear bogus dontaudit gitosis_t bin_t:file setattr; dontaudit gitosis_t fs_t:filesystem getattr; optional_policy(` mta_send_mail(gitosis_t) ')

2 comments:
Thanks for this write-up. Do you plan on submitting this policy change upstream, perhaps as a boolean?
I have submitted a few patches to the upstream gitosis policy, but they haven't been applied yet, to my knowledge.
Post a Comment