Table of Contents
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.
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.