Oracle 8i | Oracle 9i | Oracle 10g | Oracle 11g | Oracle 12c | Miscellaneous | PL/SQL | SQL | Oracle RAC | Oracle Apps | Linux

Security-Enhanced Linux (SELinux)

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:

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.

For more information see:

Hope this helps. Regards Tim...

Back to the Top.