darkness

Wednesday, 26 September 2007

SELinux and EPEL’s mod_fcgid on CentOS 5

darkness @ 01:02:02

I rebuilt EPEL’s mod_fcgid package with the latest mod_fcgid (2.2 I believe) with no problems. Make sure to define a macro like rhel with value 5 to get the SELinux policy module built too (echo '%rhel 5' >> ~/.rpmmacros or maybe rpmbuild --define 'rhel 5' ...).

Now, I’m using FastCGI and Apache’s suEXEC to run the FastCGIs as particular (per-site) users. So for one site my configuration looks like:

<VirtualHost www.example.com:80>
        ServerName www.example.com
        DocumentRoot /srv/www/www.example.com/root

        SuexecUserGroup www_example_com www_example_com
        ScriptAlias /trac /var/www/suexec/www_example_com/trac.fcgi
</VirtualHost>

suEXEC (as distributed with CentOS 5) will only run things under /var/www, so I created /var/www/suexec. I want to run things as the example user, lets say, so I mkdir /var/www/suexec/www_example_com and chown that directory to example:example, because suEXEC requires that. Then I make a little .fcgi file that starts my FastCGI app (for Trac as you may have noticed).

So on and so forth; none of that is interesting. Now here comes SELinux: I did install the mod_fcgid-selinux package, which automatically installs an SELinux policy module for mod_fcgid (semodule --list | grep fastcgi). As far as I can tell, you must chcon -t httpd_fastcgi_script_exec_t your FastCGI scripts; without this, I believe your script won’t have access to various pipes or shared memory or something that it needs to communicate back to mod_fcgid living in Apache. Don’t label the whole directory httpd_fastcgi_script_exec_t, just the .fcgi file. See also the README.SELinux that comes in the mod_fcgid-selinux package.

At this point, especially since I had the SELinux httpd_unified boolean on (it’s on by default), I might have been in the clear. I go to run my trac.fcgi (via /trac)… and I get an internal error. /var/log/httpd/error_log spews HTML and other errors that sound generally like “I didn’t start as a FastCGI at all, here’s me as a regular CGI, whee!” The best part? No AVC messages.

Here’s where Dan Walsh’s post on disabling dontaudit rules comes in. As he says, the cool stuff is in Fedora 8 where all dontaudit rules can be disabled, even ones in policy modules (policy modules like the fastcgi module that is installed by mod_fcgid-selinux). However, in this case, and because I rebuilt fastcgi with no dontaudit rules, I can tell you the problem is in the base policy and not in a policy module; so using semodule -b /usr/share/selinux/targeted/enableaudit.pp works just fine to troubleshoot this.

So execute the above semodule command, restart Apache (for good measure?), reload /trac, and now we get:

type=AVC msg=audit(1190783371.758:8180): avc: denied { read write }
for pid=3 2127 comm="suexec" name="[180326]" dev=sockfs
ino=180326 scontext=user_u:system_ r:httpd_suexec_t:s0
tcontext=user_u:system_r:httpd_t:s0 tclass=unix_stream_socke t

type=AVC msg=audit(1190783371.758:8180): avc: denied { siginh }
for pid=32127 comm="suexec" scontext=user_u:system_r:httpd_t:s0
tcontext=user_u:system_r:http d_suexec_t:s0 tclass=process

type=AVC msg=audit(1190783371.758:8180): avc: denied { rlimitinh }
for pid=32 127 comm="suexec" scontext=user_u:system_r:httpd_t:s0
tcontext=user_u:system_r:h ttpd_suexec_t:s0 tclass=process

type=AVC msg=audit(1190783371.758:8180): avc: denied { noatsecure }
for pid=32127 comm="suexec" scontext=user_u:system_r:httpd_t:s0
tcontext=user_u:system_r: httpd_suexec_t:s0 tclass=process

Now, the last three messages are apparently no big deal. That first one, though, is the problem. So I run that through audit2allow, a little editing, and I come out with something like:

 policy_module(local_fastcgi, 1.0.0)

 require {
     type httpd_suexec_t;
     type httpd_t;
 };

 allow httpd_suexec_t httpd_t:unix_stream_socket { rw_stream_socket_perms };

(OK, sorry, that’s actually a significant bit of editing. I just learned about the macros that I guess you’re supposed to use, like policy_module. I found rw_stream_socket_perms in the fastcgi policy source.)

I slap that in a file like local_fastcgi.te then make -f /usr/share/selinux/devel/Makefile load (careful! I think that will build and install every policy in–and possibly every policy under–the current directory). Once loaded, I restart Apache, and now my FastCGI being run by suEXEC works.

I hope you didn’t just read this overly verbose post just to find “install the above policy module and FastCGIs running with suEXEC under CentOS 5 will work with SELinux on.” Er, sorry.

I would report this as a bug… maybe I should file it against EPEL, if they’ve got some bug tracking. Then they’ll probably end up pushing it upstream to the F7 maintainer? Which I assume is where the EPEL package was derived from. My question then is: does F7 have this problem too, or is it fixed in F7 by virtue of some other part of the policy?

The rule to dontaudit httpd_suexec_t getting at httpd_t:unix_stream_socket is actually in the core Apache policy, I think, and it seems to make a reference to how Apache should “close-on-exec.” So I’m really not even sure if this policy change should go into Apache’s policy (and have a bool?) or if it should go into mod_fcgid’s policy module (and have a bool there?).

So, does someone want to advise me as to where and against what package(s) I should file a bug? Or maybe I need to wade onto the Fedora SELinux mailing list?

1 Comment »

  1. I’m the author of the mod_fcgid-selinux policy module.

    The existing dontaudit rules in the apache policy are needed because httpd doesn’t set close-on-exec for various file descriptors it has open before it calls out to CGI scripts etc. So those scripts inherit those file descriptors and could potentially mess with the files httpd has open.
    As there is an SELinux domain transition here (e.g. httpd_t -> httpd_sys_script_t) and the httpd_sys_script_t domain isn’t allowed access to most of the files httpd has open, the kernel generates AVC denials at exec() time and closes the files in the child process. The dontaudit rules just prevent the logs getting cluttered with the resulting noise. It would of course be better to get httpd to set close-on-exec but upstream seems reluctant to do that.

    Now as for the question of where to report the need for your allow rule, it definitely belongs in the core apache policy rather than the fastcgi module because it references only types from the httpd module. I suggesting raising this on fedora-selinux-list, explaining under what circumstances you need this, and you’ll probably get a helpful answer from Dan Walsh, the selinux-policy maintainer in Fedora.

    Comment by Paul Howarth — Monday, 23 June 2008 @ 08:58:10

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress