Apache Tomcat mod_jk with selinux

I am using Selinux with targeted policy on Centos 5.2. Centos is repackaging the Redhat Enterprise sources. As a consequence, the following procedure should more or less apply to Fedora and Redhat as well. Please note, that I am a beginner finding my way through Selinux.

The problem

While configuring my system, I set Selinux to permissive to log denied messages but still to allow the application to proceed.

I got the following error message in /var/log/audit/audit.log

type=AVC msg=audit(1221345997.761:142513): avc:  denied  { unlink } for  pid=13703 comm="httpd" 
name="jk-runtime-status.13703.lock" dev=dm-1 ino=2284901 
scontext=user_u:system_r:httpd_t:s0 
tcontext=user_u:object_r:httpd_log_t:s0 tclass=file

type=SYSCALL msg=audit(1221345997.761:142513): arch=c000003e syscall=87 success=yes 
exit=0 a0=2b27f82a6190 a1=7080 a2=0 a3=12 items=0 ppid=1 pid=13703 auid=500 
uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=698 
comm="httpd" exe="/usr/sbin/httpd" subj=user_u:system_r:httpd_t:s0 key=(null)

The first message means that something running under the context user_u:system_r:httpd_t:s0 tries to access a file (tclass=file) which has the Selinux context user_u:object_r:httpd_log_t:s0. The filename is

jk-runtime-status.13703.lock. Selinux denied unlink on the file. What does this mean?

The only source to explain the permission was the website http://seedit.sourceforge.net/doc/access_vectors/

So unlink means deleting a file. The mod_jk module in Apache uses the jk-runtime-status file and tries to delete it.
Solving the problem

I used the following means to analyse the problem

grep http /var/log/audit/audit.log | audit2why

More precise is the search tool in Selinux

ausearch --comm httpd | audit2why 

Note that ausearch will search all audit.log files including the older ones as well. Have a look on its manpage it is well documented.

The only problem is that audit2why tells me nothing useful.

A different approach are the troubleshooting tools. They can run as visual application or just on the console. Well, I have a server so there is no visual environment.

If you can’t run sealert than just install it:

yum install setroubleshoot-server

First extract all httpd messages and write them to httpd.log


ausearch —comm httpd > httpd.log

To get the messages of today just use


ausearch —comm httpd —start today > httpd.log

Now run
sealert -a httpd.log 

I got the following message:


Summary:

SELinux prevented httpd reading and writing access to http files.

Detailed Description:

[SELinux is in permissive mode, the operation would have been denied but was
permitted due to permissive mode.]

SELinux prevented httpd reading and writing access to http files. Ordinarily
httpd is allowed full access to all files labeled with http file context. This
machine has a tightened security policy with the httpd_unified turned off, this
requires explicit labeling of all files. If a file is a cgi script it needs to
be labeled with httpd_TYPE_script_exec_t in order to be executed. If it is
read-only content, it needs to be labeled httpd_TYPE_content_t, it is writable
content. it needs to be labeled httpd_TYPE_script_rw_t or
httpd_TYPE_script_ra_t. You can use the chcon command to change these contexts.
Please refer to the man page “man httpd_selinux” or FAQ
(http://fedora.redhat.com/docs/selinux-apache-fc3) “TYPE” refers to one of
“sys”, “user” or “staff” or potentially other script types.


Allowing Access:

Changing the “httpd_unified” boolean to true will allow this access: “setsebool
-P httpd_unified=1”

The following command will allow this access:


setsebool -P httpd_unified=1

……….. snip ……….

I am confused. The trouble shooting tools thinks that this is a html file but at least it explains correctly, that httpd tries to write to this file.

If proposes two solution:

a)

Change the context of the file to


httpd_TYPE_script_rw_t

This allow writing of httpd to this file but hey, this would allow any php to write to this file as well. This is not what I want.

b)


setsebool -P httpd_unified=1

From my understanding this allows to write everything which is readable from httpd. This is not what I want as well.

Well this is a lock file and might change the context of the file to something that httpd_t can write and unlink.

Let’s have a look in the normal pid file directory

	ls -Z /var/run

I found probably something useful


rw-r-r— root root system_u:object_r:httpd_var_run_t httpd.pid

Pid files have the context httpd_var_run
Let us check which access httpd has. sesearch is a great help to do this.

sesearch —allow -s httpd_t | grep httpd_var_run

The result is

allow httpd_t httpd_var_run_t : file { ioctl read write create getattr setattr lock append unlink link rename };
allow httpd_t httpd_var_run_t : dir { ioctl read write getattr lock add_name remove_name search };
allow httpd_t httpd_var_run_t : sock_file { ioctl read write create getattr setattr lock append unlink link rename };

The first line tells us httpd_t can do everything in {..} to a file having the context httpd_var_run_t.

Let us try to create the jk_runtime file in a folder so that it gets the httpd_var_run_t context by default.

mkdir /var/run/mod_jk

semanage fcontext -a -t httpd_var_run_t "/var/run/mod_jk(/.*)?"

I changed the mod_jk configuration, which can be somewhere in your httpd.conf or close to it.

JkShmFile /var/run/mod_jk/jk-runtime-status

After a restart of httpd, I can see the lock files in /var/run/mod_jk and ta-ta-ta let’s see the file context of Selinux.


ls Z /var/run/mod_jk
-rw-r
-r— root root user_u:object_r:httpd_var_run_t jk-runtime-status.6940
rw-r-r— root root user_u:object_r:httpd_var_run_t jk-runtime-status.6940.lock

Perfect. Let us check the audit.log a last time, if anything unwanted rests in the log file.

tail /var/log/audit/audit.log

No, not this time. So we are done.
Best Regards

Sebastian Hennebrueder