Wednesday, April 7, 2010

Getting Started With SELinux

One topic that I have tried to stay away from is SELinux.  Why?  It is a large, time consuming, and complex topic that you really need to work with to gain a good understanding of how it works and how to effectively create policies.  Many people that work with it usually turn it off as a first step when building a server.  Another way to use SELinux more effectively would be to enable it, but set it to "permissive".  This way while everything will still be allowed it will be logged.  While it isn't imperative to have it running it does add another layer of security when used properly.  I finally decided that it was time to start taking a look into this topic.  I am currently using SELinux for my Apache servers, which allow me to add security and flexibility with controls.

First lets check to see if SELinux is running and what the status is set too.  You will need to be the root user and then you can run the following:

# sestatus
SELinux status:               enabled
SELinuxfs mount:              /selinux
Current mode:                 permissive
Mode from config file:        permissive
Policy version:               21
Policy from config file:      targeted 
 
Here we see that SELinux is enabled and the current mode is set to permissive.  If you do not have SELinux enabled or you want to change the settings of it, you will need to edit the /etc/selinux/config file and reboot your machine.  It will relabel the drive and its files to match the new policy and remain persistent across all further reboots.  Next I want to look at what the Apache process is running under for SELinux.  This can be done by:

# ps -ZC httpd
LABEL                            PID TTY       TIME CMD
system_u:system_r:httpd_t        2180 ?        00:00:00 httpd
system_u:system_r:httpd_t        2184 ?        00:00:00 httpd
system_u:system_r:httpd_t        2190 ?        00:00:00 httpd
system_u:system_r:httpd_t        2191 ?        00:00:00 httpd
system_u:system_r:httpd_t        2192 ?        00:00:00 httpd
system_u:system_r:httpd_t        2193 ?        00:00:00 httpd
system_u:system_r:httpd_t        2194 ?        00:00:00 httpd
system_u:system_r:httpd_t        2195 ?        00:00:00 httpd
system_u:system_r:httpd_t        2196 ?        00:00:00 httpd 
 
There are few things to notice here.  First you can see normal information about each process (9 in total), including the process ID and its label.  The labels are what we need to focus on to better understand how SELinux is handling the Apache process.  This should be fairly easy to understand from looking at it; the system_u means that the process is a system user and the system_r means that it is a process and not a file.  The third column represents the type however we will hold off on talking about that for the moment.  Everything looks good here so far for setting up Apache so lets go ahead and start adding files to the web server.

# cd /var/www/html
# touch selinux_web_ref
# touch index.html

Here we are going into the web directory and creating two files (assuming they don't exist already).  The selinux_web_ref leave alone for the moment, but the index.html should contain some test code that you can use to test that the web server works (you can leave the default index.html if you prefer).  Now lets look at how SELinux defines access control.  There are five fields which you need to know:

user:role:type:sensativity:category

User -> system_u for system users, user_u for normal users
Role -> object_r for files, system_r for system or user processes
Type -> used for access control
Sensitivity -> used by government agencies
Category -> used to allow/deny access even for root user

To understand how these work we look at our index.html file that we just created:

# ls -Z
-rwxr--r--  apache apache system_u:object_r:httpd_sys_content_t index.html
-rwxr--r--  apache apache system_u:object_r:httpd_sys_content_t selinux_web_ref

Looking at the reference above we can see that both of these files are owned by the apache user and apache group, they are labeled as files belonging to a system user, and their type is httpd_sys_content_t.  So far so good, next we will need to check which boolean values are set in SELinux either enabling or disabling certain things from running on our web server.  We can check with the following command:

# getsebool -a | grep httpd
allow_httpd_anon_write --> off
allow_httpd_bugzilla_script_anon_write --> off
allow_httpd_cvs_script_anon_write --> off
allow_httpd_mod_auth_pam --> off
allow_httpd_nagios_script_anon_write --> off
allow_httpd_prewikka_script_anon_write --> off
allow_httpd_squid_script_anon_write --> off
allow_httpd_sys_script_anon_write --> off
httpd_builtin_scripting --> on
httpd_can_network_connect --> off
httpd_can_network_connect_db --> off
httpd_can_network_relay --> off
httpd_can_sendmail --> on
httpd_disable_trans --> off
httpd_enable_cgi --> on
httpd_enable_ftp_server --> off
httpd_enable_homedirs --> on
httpd_rotatelogs_disable_trans --> off
httpd_ssi_exec --> off
httpd_suexec_disable_trans --> off
httpd_tty_comm --> on
httpd_unified --> on
httpd_use_cifs --> off
httpd_use_nfs --> off

As you can see there are many different options which can be modified.  Some research will be required to gain a better understanding of each option and allow you to set your policies correctly.  The defaults should work for most that are just starting out with SELinux.  You can also modify these settings using the setsebool command.  The final thing I wanted to touch on was why we made the selinux_web_ref file.  Most admins won't just allow users to create web content in their /var/www/html directory, they expect users to develop files on their own machines and then they will send the files to the admin to be uploaded.  This will make the security context of each file/folder different however when they are uploaded to the correct directories.  With SELinux you will want to keep all your web files/folders the same context so that the same policies apply to them.  SELinux has a nice feature where you can copy or "reference" another file for its settings and apply them.  Using the chcon command we can change the SELinux settings of the selinux_web_ref file until we are satisfied with it then apply it as the reference file for our /var/www/html directory.  I changed the context of the index.html file just as an example here:

# ls -Z
-rw-r--r--  apache apache user_u:object_r:httpd_sys_content_t index.html
-rwxr--r--  apache apache system_u:object_r:httpd_sys_content_t selinux_web_ref

# chcon --reference selinux_web_ref index.html
# ls -Z
-rw-r--r--  apache apache system_u:object_r:httpd_sys_content_t index.html
-rwxr--r--  apache apache system_u:object_r:httpd_sys_content_t selinux_web_ref

You can see above that the index.html file was set as a user file, but was changed to a system file after referencing the context of selinux_web_ref.  This can obviously be scripted to make life easier for the system admin.  As a final note it is worth mentioning that SELinux by default shouldn't have any trouble with .html pages, but will deny or disallow most scripts.  You will need to adjust the policy and settings to fit your needs.

Additional Reference:
http://wiki.centos.org/TipsAndTricks/SelinuxBooleans
http://wiki.centos.org/HowTos/SELinux

0 comments:

Post a Comment