This article will explain how to use SELinux to confine a Tomcat application on RHEL6 / CentOS6.

By default, Tomcat runs as tomcat_t, which is an unconfined type. This is difficult to find out, because the documentation is scarce on the different types of EL6’s targeted policy.

The important thing to understand is that not only the unconfined_t domain or the unconfined_u user are unconfined. In the targeted policy, there is a type attribute that is called unconfined_domain_type.

A type attribute is a handy way of applying multiple access controls to a group of domains.
To see type attributes, execute the command:

# yum install setools-console
# seinfo -a

The output shows the list of type attributes that exist in the targeted policy. To get a list of types assigned to the attribute:

# seinfo -asysctl_type -x
sysctl_type
sysctl_crypto_t
sysctl_fs_t
sysctl_vm_t
sysctl_net_unix_t
sysctl_irq_t
sysctl_rpc_t
sysctl_hotplug_t
sysctl_kernel_t
sysctl_modprobe_t
sysctl_t
sysctl_vm_overcommit_t
sysctl_dev_t
sysctl_net_t

In the EL6 targeted policy, there is a domain attribute called unconfined_domain_type which, when applied to a domain, renders that domain unconfined:

# seinfo -aunconfined_domain_type -x
unconfined_domain_type
sosreport_t
cfengine_execd_t
bootloader_t
devicekit_power_t
nova_api_t
virt_qemu_ga_unconfined_t
nova_compute_t
nova_console_t
zarafa_gateway_t
openvswitch_t
...
tomcat_t
...

This means that all those domains are actually unconfined.

In order to remove this type attribute, execute the commands:

# semodule -l | grep unconfined
unconfined 3.1.1
unconfineduser 1.0.0
# semodule -d unconfined
# seinfo -aunconfined_domain_type -x
unconfined_domain_type
unconfined_sendmail_t
rpm_t
unconfined_mount_t
preupgrade_t
anaconda_t
rpm_script_t
openshift_initrc_t
unconfined_notrans_t
unconfined_execmem_t
unconfined_java_t
unconfined_mono_t
kernel_t
livecd_t
unconfined_t

Once the unconfined module is deleted from the system, the tomcat_t domain is now confined.
Warning, this will confine many other domains too.
Restarting Tomcat should now fail, and the commands:

# service tomcat restart
# ausearch -m avc -ts recent

should show a number of AVC denied events.

It is now time to write a policy that will reallow the execution of Tomcat. The usual way of doing this is to iterate over the following loop:

  • Restart Tomcat
  • Execute ausearch -m avc -ts recent | audit2allow
  • Add rules to policy, recompile and install

until everything works fine. This is pretty tedious. There is another way of doing this:

  • Put SELinux in permissive
  • Restart Tomcat
  • Run ausearch -m avc -ts recent | audit2allow
  • Add rules to policy, compile and install
  • Restart Tomcat

But the former method is preferred, as the second might introduce unwanted rules in the policy.

The policy below is the result of the first method on a fresh Tomcat installation with admin applications (manager and host-manager) deployed:

  • Create a development directory that contains a link to /usr/share/selinux/devel/Makefile, as well as a file called myapp.te that contains the following policy (Replace myapp everywhere by the name of your application):
    policy_module(myapp, 0.1)gen_require(`
    type initrc_t;
    type tomcat_log_t;
    type tomcat_t;
    type initrc_var_run_t;
    type java_exec_t;
    type locale_t;
    ')

    ###
    allow initrc_t tomcat_log_t:file { write setattr create };
    allow initrc_t tomcat_log_t:dir { write add_name create };

    allow tomcat_t initrc_var_run_t:file { open write getattr };
    allow tomcat_t java_exec_t:file { read execute getattr open execute_no_trans };
    allow tomcat_t locale_t:dir search;
    allow tomcat_t locale_t:file { open read getattr };
  • Compile and install the policy:
    # make myapp.pp && semodule -i myapp.pp
  • Restart Tomcat

You now have to deploy your Web application to /var/lib/tomcat/webapps/ and complete myapp.te with the rules specific to your application.

The drawback of this method is that, since we’ve disabled the unconfined module and consequently confined a number of other domains, we need to check that everything else still works fine (cron jobs, other applications, etc.)
It’s better to do this on a virtual server dedicated to running our Tomcat application solely.

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

1 réponse

Laisser un commentaire

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

Laisser un commentaire

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

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.