Hello,
I'm having some trouble with an SELinux policy to allow sending mail from a
PHP script run from our Web server with a local installation of qmail on a
CentOS 5 system. We send mail using php's mail() function, which calls
/usr/bin/sendmail, which in turn calls /var/qmail/bin/qmail-inject, then
/var/qmail/bin/qmail-queue, which actually puts the message in the queue.
SELinux comes with some default qmail policies, but out-of-the-box we had
AVC denials when qmail-queue would try to write the message into the queue,
since the Web script context was not permitted to do this.
I decided to take this opportunity to learn about writing SELinux policies.
I know qmail very well, so thought I would write a policy for qmail. The
policy would transition to a new type mail_qmail_queue_t when qmail-queue
was run, and then allow this type to write into the queue.
I think I have the basics working, but I'm running into some snags, and I
don't have enough experience to know what sorts of solutions are likely to
work out.
First, I am seeing some denials that seem to be related to file descriptors
passed by Apache to qmail-queue. When qmail-queue is run, stderr is
connected to the Web server log, and stdout is connected to the HTTP socket.
This is a pretty normal setup, which will cause any output to show up in
the user's browser and errors to show up in the Web server log. However I
get these AVC denials:
- Thu Dec 30 01:27:47 2010 type=AVC msg=audit(1293690467.534:90936): avc:
denied { read } for pid=9643 comm="qmail-queue" path="pipe:[4937510]"
dev=pipefs ino=4937510 scontext=system_u:system_r:mail_qmail_queue_t:s0
tcontext=system_u:system_r:httpd_t:s0 tclass=fifo_file
- Thu Dec 30 01:27:47 2010 type=AVC msg=audit(1293690467.534:90936): avc:
denied { append } for pid=9643 comm="qmail-queue"
path="/var/log/httpd/error_log" dev=md2 ino=24183170
scontext=system_u:system_r:mail_qmail_queue_t:s0
tcontext=user_u:object_r:httpd_log_t:s0 tclass=file
- Thu Dec 30 01:27:47 2010 type=AVC msg=audit(1293690467.534:90936): avc:
denied { read write } for pid=9643 comm="qmail-queue"
path="socket:[13964]" dev=sockfs ino=13964
scontext=system_u:system_r:mail_qmail_queue_t:s0
tcontext=system_u:system_r:httpd_t:s0 tclass=tcp_socket
I could write policy to allow mail_qmail_queue access to these httpd_t
resources, but in general it should not have that access; only when it is
run from Apache. I could create a special type for "qmail-queue run from
Apache", but that quickly gets out-of-hand if I create custom policies for
each program that sends mail. What is the normal way to deal with these
sorts of situations?
Second, I am having some trouble getting file contexts set up. I have
several qmail installations with different policies, so I wrote a rule in my
fc file like this:
/var/qmail(-.*)?/bin/qmail-queue --
gen_context(system_u:object_r:mail_qmail_queue_exec_t,s0)
When I use that rule, qmail-queue gets labeled bin_t, I think because of
another rule saying anything in a directory named "bin" is "bin_t". How can
I tell it my rule is more specific or higher priority than the default rule?
For that matter, how can I figure out what rule is overriding mine?
Third, is there a useful guide for troubleshooting SELinux policy execution?
When things don't work as I expect them to, it's hard to find the reason if
it's not obvious from the audit.log.
Finally, can anybody recommend a good book or other resource for learning
SELinux? I have *SELinux by Example*, but it seems that conventions for
policy files have changed a great deal since it was written.
Thanks!
-----Scott.