Enabling user directory support

Let's look at an example of how to use SELinux Booleans applicable to web server installations. In this recipe, we'll enable Apache UserDir support (allowing the web server to serve local user account web pages at http://sitename/~username).

Getting ready

Configure the Apache web server to serve user content. An entire Apache configuration tutorial would be in place here, but this is not in the scope of this book. Basically, this is done by editing the httpd.conf file and setting the UserDir directive.

How to do it…

To enable user directory support, follow the next set of steps:

  1. Make sure that the user's home directory is accessible for the Apache runtime account with the following commands. If Linux DAC denies access, SELinux will not even handle the request.
    ~$ chmod 755 ${HOME}/
    ~$ chmod 755 ${HOME}/public_html
    
  2. Check that access isn't already allowed by surfing to a user page. If all permissions are okay but SELinux denies access, then the page should be served with a 403 (forbidden) error and a denial should be registered in the audit logs. The Apache error logs would yield a permission denied against the resource.
  3. The audit logs will probably tell that httpd_t isn't allowed to act on home_root_t or user_home_dir_t. From a look through the SELinux Booleans, we find at least two interesting Booleans (httpd_enable_homedirs and httpd_read_user_content):
    ~# sesearch -s httpd_t -t home_root_t -c dir -p open -AC
    Found 2 semantic av rules:
    DT allow httpd_t home_root_t : dir { getattr search open } ; [ httpd_enable_homedirs ]
    DT allow httpd_t home_root_t : dir { getattr search open } ; [ httpd_read_user_content ]
    
  4. Let's first toggle httpd_read_user_content. This allows the web server to access all user files, which is functionally okay, but this also immediately grants it access to all files:
    ~# setsebool httpd_read_user_content on
    
  5. Another approach (but this approach requires user intervention) is to have ~/public_html/ labeled as httpd_user_content_t. When this is done, httpd_read_user_content can be turned off and httpd_enable_homedirs can be enabled:
    ~$ chcon –R –t httpd_user_content_t public_html
    ~# setsebool httpd_read_user_content off
    ~# setsebool httpd_enable_homedirs on
    
  6. When the changes are working nicely, we can persist the changes so that they survive a reboot:
    ~# setsebool –P httpd_enable_homedirs on
    

How it works...

The default web server policy in SELinux does not allow the web server to access user home content. If a vulnerability in a web application or the Apache web server itself would allow an attacker to read user content, SELinux will prevent this from happening. But, sometimes, user content access is needed.

By enabling the httpd_read_user_content Boolean, the web server domain (and all related domains) will have full read access to all user files. If users are not able (or do not know how) to set the proper context on their files, then this is the only suitable option.

A better approach, however, is to enable the httpd_enable_homedirs Boolean. This allows the web server search access through the home directory (/home/user/, which is labeled user_home_dir_t) but does not provide read access to user content (which is labeled user_home_t). Instead, the resources needed for the web server are labeled httpd_user_content_t—a type that regular users can relabel resources to (or relabel resources from). Next to httpd_user_content_t, one can also define the following content types:

  • httpd_user_htaccess_t for the .htaccess files
  • httpd_user_script_exec_t for user-provided CGI scripts
  • httpd_user_ra_content_t for appendable resources (for the web server)
  • httpd_user_rw_content_t for read/write resources (for the web server)

These resources can be set by the end user and give a finer control over how each resource within the ~/public_html/ location can be handled by the web server (and the web applications).

There's more...

Some SELinux supporting distributions have a daemon called restorecond, which can be used to automatically set the context of files the moment they are created/detected, without needing file transitions in policy. This can be used to automatically have ~/public_html/ labeled as httpd_user_content_t.

See also