SELinux and EPEL’s mod_fcgid on CentOS 5
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?
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