How to start using SELinux or Security-Enhanced Linux

Introduction

SELinux, Most of the new Linux users will disable once they start with the post configuration. Actually, you are loosing once of precious security feature in Linux by disabling it. Instead of disabling it why can’t we learn and manage SELinux? This guide will make yourself familiar with it in all the way.

SELinux or Security-Enhanced Linux is one of the security Layer in Linux provided by a Security module. In 2000 the initial version released and available under GPL licence. The Authors are the National Security Agency (NSA) & RedHat. SELinux only available for Linux operating system and written in “C” language.

What is the use of SELinux?

SELinux is one of important security layer in Linux which protect the directory, files, process and ports with its own labels by preventing access to other users or processes. For example, by default, a web server up and running with a standard port and directory they have their default labels (httpd_sys_content_t:s0), FTP service running in the same server can’t access the Web server owned ports, files and processes.

Packages and Dependencies of SELinux

SELinux will be enabled by default while the server installation, the package policycoreutils and their libraries libselinux-utils will enable the SELinux up and running. The additional management packages policycoreutils-python can be installed later while our requirement comes in.

Types of modes

There are three types of modes and they are as follows

S:NO: Modes Description
1. Enforcing Active and enforce rules and deny the access accoring to rules
2. Permissive Policy is not enforced and Only logs
3. Disabled Completely disable the SELinux

To change any modes persistently we need to edit configuration file /etc/sysconfig/selinux and change the mode. Once the changes are done we required a reboot to relabel the whole system.

[root@system1 ~]# cat /etc/sysconfig/selinux 
 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 three values:
 targeted - Targeted processes are protected,
 minimum - Modification of targeted policy. Only selected processes are protected.
 mls - Multi Level Security protection.
 SELINUXTYPE=targeted 
[root@system1 ~]#

Checking the Status and Running SELinux

The configuration file of SELinux will be under /etc/sysconfig/selinux, to temporarily disable it can be achieved by running below command, this will change the mode to permissive. In this mode, the rules will not enforce to active instead it will log everything.

# setenforce 0

To change back the mode to active or enforcing mode run

# setenforce 1

To verify the current status run

# sestatus 

The output will show the status in the first line. And the fifth line will show the status of the current mode.

SELinux Status
SELinux Status

Knowing the available SELinux labels

Let us explore the available files, directory and ports default preconfigured labels of SELinux. To list the available Labels for files and directories

# semanage fcontext -l

The output will be very long with fcontext, type and Context. Use grep to sort only the specific context from the long output.

SELinux fcontext                                   type               Context
 /var/www/openshift/broker/httpd/run(/.)?          all files          system_u:object_r:httpd_var_run_t:s0  
 /var/www/openshift/console/httpd/logs(/.)?        all files          system_u:object_r:httpd_log_t:s0 
 /var/www/openshift/console/httpd/run(/.)?         all files          system_u:object_r:httpd_var_run_t:s0  
 /var/www/openshift/console/log(/.)?               all files          system_u:object_r:httpd_log_t:s0 
 /var/www/openshift/console/tmp(/.*)?              all files          system_u:object_r:httpd_tmp_t:s0

To know the ports replace “fcontext” with “port“.

# semanage port -l

All the ports will have a label as shown below.

SELinux Port Type              Proto    Port Number
afs3_callback_port_t           tcp      7001
afs3_callback_port_t           udp      7001
afs_bos_port_t                 udp      7007
afs_fs_port_t                  tcp      2040

All files, directory and process will have labels as shown below. To list the context just we need to use a capital “Z” while listing files or folders.

Files and directory

[root@server ~]# ls -lZ /var/www/html/*
 dr-xr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 EFI
 -r--r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 EULA
 -r--r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 GPL
 dr-xr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 LiveOS

Processes

[root@server ~]# ps -eflZ | grep httpd
 system_u:system_r:httpd_t:s0    4 S root       1532      1  0  80   0 - 53426 poll_s Jun04 ?        00:00:01 /usr/sbin/httpd -DFOREGROUND
 system_u:system_r:httpd_t:s0    5 S apache     3027   1532  0  80   0 - 53426 SYSC_s 03:24 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
 system_u:system_r:httpd_t:s0    5 S apache     3028   1532  0  80   0 - 53426 SYSC_s 03:24 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
 system_u:system_r:httpd_t:s0    5 S apache     3029   1532  0  80   0 - 53426 SYSC_s 03:24 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND

Ports

[root@server ~]# netstat -tunlpZ
 Active Internet connections (only servers)
 Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name     Security Context                                 
 tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1841/master          system_u:system_r:postfix_master_t:s0             
 tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1540/sshd            system_u:system_r:sshd_t:s0-s0:c0.c1023           
 tcp6       0      0 ::1:25                  :::*                    LISTEN      1841/master          system_u:system_r:postfix_master_t:s0             
 tcp6       0      0 :::8010                 :::*                    LISTEN      1532/httpd           system_u:system_r:httpd_t:s0

Managing SELinux Boolean

Booleans are if then else rules written in SELinux policy which used to customize the policy rules for any requirements like allowing FTP to use home directory or to allow FTP anonymous user to write. Booleans can be set using two methods.

Method 1:

Let’s list and filter the boolean for allowing FTP home directory.

# semanage boolean -l | grep  -i ^ftp_home_dir

The current status of boolean is in the off state.

[root@server ~]# semanage boolean -l | grep  -i ^ftp_home_dir
ftp_home_dir                   (off  ,  off)  Allow ftp to home dir
[root@server ~]#

Let’s enable and list.

# semanage boolean -m --on ftp_home_dir
# semanage boolean -l | grep  -i ^ftp_home_dir

Check the current status after enabling the boolean.

[root@server ~]# semanage boolean -m --on ftp_home_dir 
[root@server ~]# semanage boolean -l | grep  -i ^ftp_home_dir
ftp_home_dir                   (on   ,   on)  Allow ftp to home dir
[root@server ~]#

Method 2:

To list the current status use get command with “-a” to show all booleans. Use grep to filter a keyword.

# getsebool -a | grep ftp

To set a boolean use “on” or number “1” to turn off the boolean use “off” or “0“. The option capital “-P” make the changes persistent across reboots.

# setsebool ftp_home_dir on -P
# setsebool ftp_home_dir 1 -P

Temporarily labelling file and directories

To change the context temporarily we can use “chcon” command by following with option and arguments. This changes will be restored to original context when we reboot the server or when we run “restorecon” command.

In below example, we are recursively changing the context of web servers root directory /srv/www/html/ with “ftpd_exec_t” once we run restorecon it will revert back to the original context.

# chcon -Rv -t ftpd_exec_t /srv/www/html
# restorecon -Rv /srv/www/html/

Wrongly assigned with a context

[root@system1 ~]# 
[root@system1 ~]# chcon -Rv -t ftpd_exec_t /srv/www/html
 changing security context of '/srv/www/html/index.html'
 changing security context of '/srv/www/html'
[root@system1 ~]# 

Restoring to the original context.

[root@system1 ~]# 
[root@system1 ~]# restorecon -Rv /srv/www/html/
 restorecon reset /srv/www/html context unconfined_u:object_r:ftpd_exec_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
 restorecon reset /srv/www/html/index.html context unconfined_u:object_r:ftpd_exec_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
[root@system1 ~]#

This will help a lot when we do some troubleshooting.

Persistently labelling files and directory

Now let us see how to label a file, directory and ports. In this example, I will use /srv/www/html as my web servers root directory and expose 8010 port for serving web contents.

# ls -ldZ /srv/www/html/
# semanage fcontext -a -t httpd_sys_content_t '/srv/www/html(/.*)?'
# restorecon -Rv /srv/www/html/
# ls -ldZ /srv/www/html/
  • The option “-a” to add the context
  • Option “-t” to mention the type of context
  • (/.*)? – The type needs to apply for files and folder after the leading /

To remove a context use “-d” by replacing “-a” and rerun the command.

The output of above commands for your reference

[root@system1 ~]# ls -ldZ /srv/www/html/
 drwxr-xr-x. root root unconfined_u:object_r:var_t:s0   /srv/www/html/
 [root@system1 ~]# 
 [root@system1 ~]# semanage fcontext -a -t httpd_sys_content_t '/srv/www/html(/.*)?'
 [root@system1 ~]# 
 [root@system1 ~]# restorecon -Rv /srv/www/html/
 restorecon reset /srv/www/html context unconfined_u:object_r:var_t:s0->unconfined_u:object_r:httpd_sys_content_t:s0
 [root@system1 ~]# 
 [root@system1 ~]# 
 [root@system1 ~]# ls -ldZ /srv/www/html/
 drwxr-xr-x. root root unconfined_u:object_r:httpd_sys_content_t:s0 /srv/www/html/
[root@system1 ~]#

Now the /srv/www/html have httpd_sys_content_t context let us try to touch a file inside html/ and verify the default context.

# touch /srv/www/html/index.html
# ls -lZ /srv/www/html/*

Verify the context for the newly created file.

[root@system1 ~]# touch /srv/www/html/index.html
 [root@system1 ~]# 
 [root@system1 ~]# ls -lZ /srv/www/html/*
 -rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 /srv/www/html/index.html
[root@system1 ~]#

Labelling a Port in SELinux

To serve the web content through non-standard Apache port first we need to label it. Let’s start to list and filter.

# semanage port -l | grep ^http

Allow port 8010 to used by apache service and distribute web contents.

# semanage port -a -t http_port_t -p tcp 8010
  • -a to add the port
  • -t to add the type “http_port_t”
  • -p protocol for the port number

To revoke the port replace “-a” with “-d” and rerun the command.

At last, verify and confirm

# semanage port -l | grep ^http
# netstat -tlpZ | grep httpd

Output for your reference

[root@system1 ~]# semanage port -l | grep ^http
 http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
 http_cache_port_t              udp      3130
 http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
 [root@system1 ~]#
 [root@system1 ~]# semanage port -a -t http_port_t -p tcp 8010 
 [root@system1 ~]# 
 [root@system1 ~]# semanage port -l | grep ^http
 http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
 http_cache_port_t              udp      3130
 http_port_t                    tcp      8010, 80, 81, 443, 488, 8008, 8009, 8443, 9000
[root@system1 ~]#
[root@system1 ~]# netstat -tlpZ | grep httpd
 tcp6       0      0 [::]:8010               [::]:*                  LISTEN      9555/httpd           system_u:system_r:httpd_t:s0                      
 tcp6       0      0 [::]:http               [::]:*                  LISTEN      9555/httpd           system_u:system_r:httpd_t:s0                      
[root@system1 ~]#

Hope we are good with knowing SELinux now. Red Hat provides a cool colouring book about SELinux have a look into it.

Conclusion:

This Brief guide on how to use SELinux may help you to understand with clear examples. Let us continue with our troubleshooting guides in future write up. If you learned something new today your comment in below comment section will give us a boost to provide more on how-to guide on SELinux.