Troubleshooting SELinux

To host many of my things I use CentOS with SELinux enabled. SELinux is nice because of the security advantages it brings, but it can be a pain to work with when setting up new things. This example is based on when I configured cron to take backups of mymongodb instance and mail them to me every night. But the process is pretty much the same no matter what it is that SELinux is blocking.

To mail I used mailx that is a part of most Linux systems, and this is where SELinux stopped me. First it didn’t allow cron to send mail and secondly it didn’t allow mailx to read the file I wanted to attach. So this is how i tracked down what was happening and how i told SELinux to allow these things.

This is how it can look, just a non working example:

$ mailx …. 
Permission denied on the attachment file

To see if SELinux is the culprit we look in the audit.log, the log belonging to SELinux. And we only check for things related to mailx:

$ cat /var/log/audit/audit.log | grep mailx
type=AVC msg=audit(1353724381.477:92977): avc: denied { read } for pid=5257 comm=”mailx” …
type=AVC msg=audit(1353809346.126:96169): avc: denied { open } for pid=8465 comm=”mailx” …
type=AVC msg=audit(1353895922.113:104567): avc: denied { getattr } for pid=12760 comm=”mailx” …

So it is SELinux that is preventing us from sending the mail. To fix this we first make sure we have the “policycoreutils-python” package installed. This contains the tool “audit2allow” that we will be using to create policy files from the entries in the audit log.

$ yum install policycoreutils-python

Then we generate a policy that we can check:

$ cat /var/log/audit/audit.log | grep mailx | grep denied | audit2allow -m cronmailx > cronmailx.te

We check it and, in this example, it allows us to open and read the attachment file:

$ cat cronmailx.te
module cronmailx 1.0;
require {
type var_t;
type system_mail_t;
class file { read getattr open };
}
#============= system_mail_t ==============
allow system_mail_t var_t:file getattr;
allow system_mail_t var_t:file { read open };

And at last we generate a policy we can load and load it:

$ cat /var/log/audit/audit.log | grep mailx | grep denied | audit2allow -M cronmailx
$ semodule -i cronmailx.pp

Now either everything works or there are more SELinux rules that stops us (that we didn’t reach earlier). If there are more then just repeat the process until it works.