SELinux – How to confine a Tomcat application on RHEL6 / CentOS6 – part 2

Part 1 is here.

Another method of confining Tomcat is to create a completely new domain in which your application, as well as Tomcat and Java, will be running.

Let’s create a new domain by inheriting it from the tomcat_t domain. In the same directory as before, create the following myapp.te file:

policy_module(myapp, 0.1)

tomcat_domain_template(myapp)

Compile and install the policy:

# make myapp.pp && semodule -i myapp.pp

If you now list the available types, you will see a number of new types related to your application:

# yum install setools-console -y
# seinfo -t | grep myapp
myapp_var_lib_t
myapp_var_run_t
myapp_log_t
myapp_cache_t
myapp_tmp_t
myapp_t
myapp_exec_t

The nice thing here is that if you ask the policy whether myapp_t is confined, you will see that it actually is, even if tomcat_t is not:

# seinfo -aunconfined_domain_type -x | grep tomcat
tomcat_t
# seinfo -aunconfined_domain_type -x | grep myapp

We now have a new type that we can use instead of tomcat_t and we don’t need to confine nearly all of the existing domains.
But how are we going to use this new type myapp_t ?

First, we need to relabel the tomcat executable so that it will transition into myapp_t instead of tomcat_t. Its label is tomcat_exec_t so we need to find it and replace it:

# find / -xdev -context "*tomcat_exec_t*"
/usr/sbin/tomcat
# l -Z /usr/sbin/tomcat
-rwxr-xr-x. root root system_u:object_r:tomcat_exec_t:s0 /usr/sbin/tomcat
# chcon -t myapp_exec_t /usr/sbin/tomcat
# l -Z /usr/sbin/tomcat
-rwxr-xr-x. root root system_u:object_r:myapp_exec_t:s0 /usr/sbin/tomcat

After restarting tomcat, we find more or less the same audit errors as when we confined tomcat_t in part 1 of this post.

# /etc/init.d/tomcat start
Starting tomcat: Error code 4 [FAILED]
# yum install policycoreutils-python -y
# ausearch -m avc -ts recent | audit2allow

#============= myapp_t ==============
allow myapp_t initrc_var_run_t:file write;
allow myapp_t java_exec_t:file getattr;
allow myapp_t locale_t:dir search;

We see that tomcat is now running as myapp_t, so the transition works fine.
We need to make the labeling changes permanent:

# semanage fcontext -a -t myapp_exec_t "/usr/sbin/tomcat(6)?"
# restorecon /usr/sbin/tomcat
# l -Z /usr/sbin/tomcat
-rwxr-xr-x. root root system_u:object_r:myapp_exec_t:s0 /usr/sbin/tomcat

The reason why we set /usr/sbin/tomcat(6)? instead of just /usr/sbin/tomcat is because this is how it’s defined in the policy. Let’s override the whole policy instead of just what we need. It’s cleaner and when we’ll want to use Tomcat6 instead of Tomcat7 it’ll just magically work (hopefully).

Now, let’s iterate over the process of starting Tomcat and adding rules to the policy, taking care not to add rules that allow myapp_t to access tomcat_* resources. We end up with:

policy_module(myapp, 0.1)

tomcat_domain_template(myapp)

gen_require(`
type initrc_var_run_t;
type java_exec_t;
type locale_t;
type http_cache_port_t;
type port_t;
')

allow myapp_t initrc_var_run_t:file { open write getattr };
allow myapp_t java_exec_t:file { read execute getattr open execute_no_trans };
allow myapp_t self:process { execmem signull signal };
allow myapp_t locale_t:dir { open read search getattr };
allow myapp_t locale_t:file { open read getattr };
allow myapp_t port_t:tcp_socket { name_bind name_connect };
allow myapp_t http_cache_port_t:tcp_socket { name_bind name_connect };
allow myapp_t self:tcp_socket { listen accept };

# make myapp.pp && semodule -i myapp.pp
# /etc/init.d/tomcat restart
# ausearch -m avc -ts recent | audit2allow

#============= myapp_t ==============
allow myapp_t tomcat_cache_t:dir search;
#!!!! The source type 'myapp_t' can write to a 'dir' of the following types:
# myapp_cache_t, var_log_t, var_lib_t, var_run_t, myapp_var_lib_t, myapp_var_run_t, myapp_tmp_t, myapp_log_t, tmp_t, var_t, cluster_var_lib_t, cluster_var_run_t, root_t, cluster_conf_t

allow myapp_t tomcat_log_t:dir write;
allow myapp_t tomcat_var_lib_t:dir read;

So we’re left with myapp_t trying to access tomcat_log_t, tomcat_cache_t, tomcat_var_lib_t, which seems logical, considering that we haven’t relabeled any other files on the filesystem.
Instead of allowing myapp_t to access the tomcat domains, we need to relabel those files with the myapp types:

# find / -xdev -context "*tomcat_*" | xargs ls -ldaZ
drwxrwx---. root tomcat system_u:object_r:tomcat_cache_t:s0 /var/cache/tomcat
drwxrwx---. root tomcat system_u:object_r:tomcat_cache_t:s0 /var/cache/tomcat/temp
drwxrwx---. root tomcat system_u:object_r:tomcat_cache_t:s0 /var/cache/tomcat/work
drwxr-xr-x. root tomcat system_u:object_r:tomcat_var_lib_t:s0 /var/lib/tomcat
drwxrwxr-x. root tomcat system_u:object_r:tomcat_var_lib_t:s0 /var/lib/tomcat/webapps
drwxrwx---. root tomcat system_u:object_r:tomcat_log_t:s0 /var/log/tomcat
-rw-rw----. tomcat tomcat system_u:object_r:tomcat_log_t:s0 /var/log/tomcat/catalina.out
-rw-r--r--. tomcat tomcat unconfined_u:object_r:tomcat_log_t:s0 /var/log/tomcat/tomcat-initd.log

Just as we’ve done with /usr/sbin/tomcat(6)?, let’s relabel what’s already in the policy:

# semanage fcontext -l | grep tomcat
/usr/sbin/tomcat(6)? all files system_u:object_r:myapp_exec_t:s0
/usr/sbin/tomcat(6)? regular file system_u:object_r:tomcat_exec_t:s0
/usr/share/munin/plugins/tomcat_.* regular file system_u:object_r:munin_services_plugin_exec_t:s0
/var/cache/tomcat6?(/.*)? all files system_u:object_r:tomcat_cache_t:s0
/var/lib/tomcat6?(/.*)? all files system_u:object_r:tomcat_var_lib_t:s0
/var/log/tomcat6?(/.*)? all files system_u:object_r:tomcat_log_t:s0
/var/run/tomcat6?\.pid regular file system_u:object_r:tomcat_var_run_t:s0
# semanage fcontext -a -t myapp_cache_t '/var/cache/tomcat6?(/.*)?'
# semanage fcontext -a -t myapp_var_lib_t '/var/lib/tomcat6?(/.*)?'
# semanage fcontext -a -t myapp_log_t '/var/log/tomcat6?(/.*)?'
# semanage fcontext -a -t myapp_var_run_t '/var/run/tomcat6?\.pid'
# semanage fcontext -l | grep tomcat
# find / -xdev -context "*tomcat_*_t*" | xargs restorecon
# find / -xdev -context "*myapp_*_t*" | xargs ls -ldaZ
-rwxr-xr-x. root root system_u:object_r:myapp_exec_t:s0 /usr/sbin/tomcat
drwxrwx---. root tomcat system_u:object_r:myapp_cache_t:s0 /var/cache/tomcat
drwxrwx---. root tomcat system_u:object_r:myapp_cache_t:s0 /var/cache/tomcat/temp
drwxrwx---. root tomcat system_u:object_r:myapp_cache_t:s0 /var/cache/tomcat/work
drwxr-xr-x. root tomcat system_u:object_r:myapp_var_lib_t:s0 /var/lib/tomcat
drwxrwxr-x. root tomcat system_u:object_r:myapp_var_lib_t:s0 /var/lib/tomcat/webapps
drwxrwx---. root tomcat system_u:object_r:myapp_log_t:s0 /var/log/tomcat
-rw-rw----. tomcat tomcat system_u:object_r:myapp_log_t:s0 /var/log/tomcat/catalina.out
-rw-r--r--. tomcat tomcat unconfined_u:object_r:myapp_log_t:s0 /var/log/tomcat/tomcat-initd.log

Looks good. Restarting Tomcat now shouldn’t yield any errors.
We can now tailor the myapp policy module to the specific needs of the myapp application.

1 réponse

Trackbacks (rétroliens) & Pingbacks

  1. […] part 2, we’ll see how to achieve a better result by creating a new domain derived from the tomcat_t […]

Laisser un commentaire

Participez-vous à la discussion?
N'hésitez pas à contribuer!

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *