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?

Powered by WordPress