In the last couple of weeks I’ve started enabling selinux in enforcing mode on my webservers. Besides some expected problems, I encountered a problem with cronolog when I enabled selinux. There was no way that cronolog wanted to create the needed directories. Usually we run cronolog to create separate “Year” and “Month” directories and in every “Month” directory a separate directory and file for each day.

When I started apache with the cronolog log configuration, the following error appeared in the global apache error_log:

piped log program '/usr/sbin/cronolog /var/log/httpd/yyy.xxx.nl/%Y/%m/%d/access_log' failed unexpectedly
/var/log/httpd/wpdev.redbee.nl/2013: Permission denied
piped log program '/usr/sbin/cronolog /var/log/httpd/yyy.xxx.nl/%Y/%m/%d/access_log' failed unexpectedly

There was no year “2013” directory created in the top level log directory /var/log/httpd/yyy.xxx.nl/
As cronolog never gives any problems in that area and file rights were configured correctly, I suspected selinux. And indeed this was the problem.

In /var/log/audit/audit.log the following errors where logged:

type=AVC msg=audit(1361309216.029:25603): avc: denied { create } for pid=10047 comm="cronolog" name="2013" scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:httpd_log_t:s0 tclass=dir
type=SYSCALL msg=audit(1361309216.029:25603): arch=c000003e syscall=83 success=no exit=-13 a0=7fff5ebbf050 a1=1fd a2=ffffffffffffffa8 a3=322f6c6e2e656562 items=0 ppid=9699 pid=10047 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=175 comm="cronolog" exe="/usr/sbin/cronolog" subj=unconfined_u:system_r:httpd_t:s0 key=(null)
type=AVC msg=audit(1361309235.635:25604): avc: denied { create } for pid=10048 comm="cronolog" name="2013" scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:httpd_log_t:s0 tclass=dir
type=SYSCALL msg=audit(1361309235.635:25604): arch=c000003e syscall=83 success=no exit=-13 a0=7fff4cc1efa0 a1=1fd a2=ffffffffffffffa8 a3=322f6c6e2e656562 items=0 ppid=9699 pid=10048 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=175 comm="cronolog" exe="/usr/sbin/cronolog" subj=unconfined_u:system_r:httpd_t:s0 key=(null)

I copied these messages into a separate file (crono.se) and used the following command to create a selinux policy:


audit2allow -i /home/rogierm/crono.se -M crono

This creates a couple of files (crono.pp and crono.te) in the current working directory. The crono.te contains the plain text policy. The crono.pp file can be used to import the selinux policy:


semodule -i crono.pp

This activates the cronolog selinux policy that contains the configuration listed below. After this module is activated cronolog is allowed to create directories under the log directory.


module crono 1.0;

require {
type httpd_log_t;
type httpd_t;
class dir create;
}

#============= httpd_t ==============
allow httpd_t httpd_log_t:dir create;