What is Security-Enhanced Linux
This article covers the basic concepts of Security-Enhanced Linux (SELinux), with specific reference to the information needed for the RHCSA EX200 certification exam. Extra information is required for the RHCE EX300 certification exam, which will be supplied by another article.
Remember, the exams are hands-on, so it doesn't matter which method you use to achieve the result, so long as the end product is correct.
SELinux Modes (getenforce, setenforce)
The current SELinux mode is displayed using the
getenforce
or sestatus
commands.# getenforce Enforcing # # sestatus SELinux status: enabled SELinuxfs mount: /selinux Current mode: enforcing Mode from config file: enforcing Policy version: 26 Policy from config file: targeted #
It can be dynamically reset using the
setenforce
command.# setenforce Permissive # getenforce Permissive #
Allowable values include the following:
- Enforcing : SELinux is in enforcing mode.
- 1 : Equivalent to "Enforcing".
- Permissive : SELinux is in permissive mode.
- 0 : Equivalent to "Permissive".
The changes can be made persistent by amending the
SELINUX
parameter in the "/etc/selinux/config" file. The file contains an explanation of the allowable values.# cat /etc/selinux/config # This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=targeted #
When amending this file, rather than using the
setenforce
command, a reboot is required for the changes to take effect.SELinux File and Process Context
The SELinux file context is displayed using the "-Z" flag with the
ls
command.# touch test.txt # ls -lZ test.txt -rw-r--r--. root root unconfined_u:object_r:admin_home_t:s0 test.txt #
Displaying the SELinux process context is possible by using the "-Z" flag with the
ps
command.# ps -efZ | grep httpd system_u:system_r:httpd_t:s0 root 1781 1 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1805 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1806 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1807 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1810 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1811 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1812 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1815 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1816 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd system_u:system_r:httpd_t:s0 apache 1817 1781 0 19:12 ? 00:00:00 /usr/sbin/httpd unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 root 2684 2476 0 20:02 pts/0 00:00:00 grep httpd #
Restore Default File Contexts (semanage, restorecon)
Rather than trying to remember specific SELinux commands, we can just check the
man
pages for the service of interest.# man -k _selinux abrt_selinux (8) - Security-Enhanced Linux Policy for the ABRT daemon ftpd_selinux (8) - Security-Enhanced Linux policy for ftp daemons git_selinux (8) - Security Enhanced Linux Policy for the Git daemon httpd_selinux (8) - Security Enhanced Linux Policy for the httpd daemon kerberos_selinux (8) - Security Enhanced Linux Policy for Kerberos mysql_selinux (8) - Security-Enhanced Linux Policy for the MySQL daemon named_selinux (8) - Security Enhanced Linux Policy for the Internet Name server (named) daemon nfs_selinux (8) - Security Enhanced Linux Policy for NFS pam_selinux (8) - PAM module to set the default security context rsync_selinux (8) - Security Enhanced Linux Policy for the rsync daemon samba_selinux (8) - Security Enhanced Linux Policy for Samba squid_selinux (8) - Security-Enhanced Linux Policy for the squid daemon ypbind_selinux (8) - Security Enhanced Linux Policy for NIS #
From this we can see the
man
entry for "ftpd_selinux" gives us information on SELinux for FTP daemons.# man ftpd_selinux
At the top of the man page we are presented with the commands to allow the FTP daemon to read and write to the "/var/ftp" directory.
# semanage fcontext -a -t public_content_t "/var/ftp(/.*)?" # restorecon -F -R -v /var/ftp
For Apache, we would use something like the following.
# semanage fcontext -a -t httpd_sys_content_t "/var/www/htdocs(/.*)?" # restorecon -F -R -v /var/www/htdocs
The
semanage
command was not present on my default installation. To find out how to install it run the following command.# yum provides /usr/sbin/semanage Loaded plugins: refresh-packagekit, security policycoreutils-python-2.0.83-19.18.el6.x86_64 : SELinux policy core python : utilities Repo : localrepo Matched from: Filename : /usr/sbin/semanage #
Install the required package along with its dependencies.
# yum install policycoreutils-python
Now run the suggested SELinux commands described above.
# semanage fcontext -a -t public_content_t "/var/ftp(/.*)?" # restorecon -F -R -v /var/ftp
SELinux Boolean Settings (getsebool, setsebool)
SELinux policies are customized using boolean flags. The available boolean flags are listed using the
getsebool
command. On my installation this gives a list of 179 settings.# getsebool -a abrt_anon_write --> off abrt_handle_event --> off allow_console_login --> on ... xguest_mount_media --> on xguest_use_bluetooth --> on xserver_object_manager --> off #
The easiest way to identify the relevant settings is to filter them using a specific term.
# getsebool -a | grep ftp allow_ftpd_anon_write --> off allow_ftpd_full_access --> off allow_ftpd_use_cifs --> off allow_ftpd_use_nfs --> off ftp_home_dir --> off ftpd_connect_db --> off httpd_enable_ftp_server --> off tftp_anon_write --> off #
If you know the specific name of the flag, you can query the setting directly.
# getsebool allow_ftpd_anon_write allow_ftpd_anon_write --> off #
The
semanage
command can also be used to provide information about the settings. It reports the setting currently being used, along with the persistent setting, which will be used after reboot.# semanage boolean -l | grep ftp ftp_home_dir (off , off) Allow ftp to read and write files in the user home directories tftp_anon_write (off , off) Allow tftp to modify public files used for public file transfer services. allow_ftpd_full_access (off , off) Allow ftp servers to login to local users and read/write all files on the system, governed by DAC. allow_ftpd_use_nfs (off , off) Allow ftp servers to use nfs used for public file transfer services. allow_ftpd_anon_write (off , off) Allow ftp servers to upload files, used for public file transfer services. Directories must be labeled public_content_rw_t. allow_ftpd_use_cifs (off , off) Allow ftp servers to use cifs used for public file transfer services. ftpd_connect_db (off , off) Allow ftp servers to use connect to mysql database httpd_enable_ftp_server (off , off) Allow httpd to act as a FTP server by listening on the ftp port. #
The boolean settings are changed using the
setsebool
command. Without the "-P" flag, the current setting is changed, but this will not persist beyond a reboot.# setsebool allow_ftpd_anon_write on # semanage boolean -l | grep allow_ftpd_anon_write allow_ftpd_anon_write (on , off) Allow ftp servers to upload files, used for public file transfer services. Directories must be labeled public_content_rw_t. #
Using the "-P" flag makes the change persistent. It also makes it very slow, so don't panic thinking it has hung.
# setsebool -P allow_ftpd_anon_write on # semanage boolean -l | grep allow_ftpd_anon_write allow_ftpd_anon_write (on , on) Allow ftp servers to upload files, used for public file transfer services. Directories must be labeled public_content_rw_t. # # setsebool -P allow_ftpd_anon_write off # semanage boolean -l | grep allow_ftpd_anon_write allow_ftpd_anon_write (off , off) Allow ftp servers to upload files, used for public file transfer services. Directories must be labeled public_content_rw_t. #
Diagnosing SELinux Policy Violations
The easiest way to explain how to diagnose a policy violation is to create one and fix it, so that is what we will do using the httpd service. To do this we will create a new virtual host with an alternate location to hold the website files. Create the new directories for the virtual host called "mysite.co.uk" and place a file in the document root.
# mkdir -p /www/mysite.co.uk/htdocs # mkdir -p /www/mysite.co.uk/logs # echo "This is a test." > /www/mysite.co.uk/htdocs/test.txt
Edit the "/etc/httpd/conf/httpd.conf" file, adding the following virtual host definition. Notice the paths match those created above.
<VirtualHost *:80> ServerAdmin webmaster@mysite.co.uk DocumentRoot /www/mysite.co.uk/htdocs ServerName mysite.co.uk ErrorLog /www/mysite.co.uk/logs/error_log CustomLog /www/mysite.co.uk/logs/access_log common </VirtualHost>
Attempting to restart the service fails.
# service httpd restart Stopping httpd: [ OK ] Starting httpd: [FAILED] #
The "/var/log/httpd/error_log" file is the default httpd service error log file. Checking the contents reveals the following error.
[Tue Apr 24 20:50:59 2012] [notice] caught SIGTERM, shutting down (13)Permission denied: httpd: could not open error log file /www/mysite.co.uk/logs/error_log. Unable to open logs
We know the location exists, so this may well be an SELinux policy violation. To check that we need to check the "/var/log/audit/audit.log" file. Rather than reading the whole file, we can translate it using the
audit2why
command (or the audit2allow -w
command), which gives an explanation for any policy violations in "audit.log" file.# audit2why < /var/log/audit/audit.log type=AVC msg=audit(1335296918.002:796): avc: denied { write } for pid=4531 comm="httpd" name="logs" dev=dm-0 ino=654398 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=dir Was caused by: Missing type enforcement (TE) allow rule. You can use audit2allow to generate a loadable module to allow this access. #
So we do have a policy violation. Checking the directory we can see the default file contexts have not been set for the httpd service.
# cd /www # ls -alZ drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 . dr-xr-xr-x. root root system_u:object_r:root_t:s0 .. drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 mysite.co.uk #
We restore the default file contexts for these directories.
# semanage fcontext -a -t httpd_sys_content_t "/www/mysite.co.uk(/.*)?" # restorecon -F -R -v /www/mysite.co.uk # ls -alZ drwxr-xr-x. root root unconfined_u:object_r:default_t:s0 . dr-xr-xr-x. root root system_u:object_r:root_t:s0 .. drwxr-xr-x. root root system_u:object_r:httpd_sys_content_t:s0 mysite.co.uk #
Now the service starts as expected.
# service httpd start Starting httpd: [ OK ] #
In another case we might have to set different SELinux boolean values. Remember, not all problems will be SELinux policy violations. You need to consider regular file permissions and Access Control Lists (ACLs) also.
The
audit2allow
command can build policy modules from the violations in the "audit.log", but this is not necessary for the RHCSA exam.
Comments
Post a Comment