Setting Up SELinux (A quickstart)

What This Tutorial Covers

The aim of this tutorial is to get the user up and running with SELinux quickly and provide additional resources for further research.

Tutorial performed on: CentOS-7 with kernel version 3.10.0-514.el7.x86_64

Installing SELinux

Note: For this tutorial, all commands are run as root.

Start by installing all necessary SELinux files:

yum install policycoreutils policycoreutils-python selinux-policy selinux-policy-targeted libselinux-utils setroubleshoot-server setools setools-console mcstrans netlabel_tools selinux-policy-mls

Configuring MLS

Enable MLS

For a more in depth explanation of MLS concepts see here.

Next we must enable MLS. SELinux enables MLS via the /etc/selinux/config file. We suggest users change the SELinux mode to permissive. SELinux enforcing mode blocks connections and may prevent the operating system from booting. Change the SELINUXTYPE to MLS.

vim /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.
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.

Now we need to instruct the system to relabel all files according to a default labeling scheme. This is accomplished by instructing the system to autorelabel everything. Do this by adding the .autorelabel file to the root directory.

touch ./autorelabel

Now reboot the system. It may take a bit for the system to relabel everything. You should see the following message while it is relabeling:

Once the system reboots you can check to ensure it is running in permissive mode and  that MLS is enabled:


SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: mls
Current mode: permissive
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: denied
Max kernel policy version: 28

Warning: Most setups have a number of errors generated when MLS is enabled. MLS likely blocks a number of critical processes. I suggest you resolve these errors before swapping from permissive to enforcing.

You can check the logs to see the activity SELinux blocks:

cat /var/log/audit/audit.log | grep SEL

If nothing appears when you run the command you are likely safe to swap to enforcing assuming the system has performed all of its expected functionality.

Configuring MLS Security Levels

To configure the security levels for files and processes edit the file /etc/selinux/mls/setrans.conf:

# Multi-Level Security translation table for SELinux
# Uncomment the following to disable translation libary
# disable=1
# Objects can be labeled with one of 16 levels and be categorized with 0-1023
# categories defined by the admin.
# Objects can be in more than one category at a time.
# Users can modify this table to translate the MLS labels for different purpose.
# Assumptions: using below MLS labels.
#  SystemLow
#  SystemHigh
#  Unclassified
#  Secret with compartments A and B.
# SystemLow and SystemHigh

# Unclassified level

# Secret level with compartments

# ranges for Unclassified

# ranges for Secret with compartments

For an in depth explanation of configuring the security levels see this power point. Page 42 includes a sample configuration for a simple US DOD style classification system. You can print a quick listing of the security levels with the chcat -L command.

Configuring Users and Files for MLS

Next we need to add a system user to the list of SELinux users. SELinux maps the system users to SELinux users. SELinux users map to roles. The roles define which users may access what processes. Processes have permissions to act on specific objects IE: files, directories, TCP sockets, etc. This tutorial does a good job of explaining these concepts. See the section titled “Some Basic Terminology”. Now we will add a user:

semanage login --add --seuser user_u grant

user_u is what is called a type in SELinux terminology. In this case we want to add a user of user_u type. grant is the system user we want to add, or at least, I want to add :-D.

To view the user mappings you can use the list command within the semanage tool.

semanage login -l

This mapping also shows us what MLS range users have access to. In this case, we can see the user grant (me) only has access to the s0 security sensitivity. We can edit a user’s security access levels with the following command:

semanage login –modify –seuser user_u –range s0-s2 grant

If user_u has not been configured, you will likely receive this error:

[root@localhost ~]# semanage login --modify --seuser user_u --range s2:c100 grant
libsemanage.validate_handler: MLS range s2:c100 for Unix user grant exceeds allowed range s0 for SELinux user user_u (No such file or directory).
libsemanage.validate_handler: seuser mapping [grant -> (user_u, s2:c100)] is invalid (No such file or directory).
libsemanage.dbase_llist_iterate: could not iterate over records (No such file or directory).
OSError: No such file or directory

What this is telling you is that the user_u SELinux user does not have access to either s1 or s2 or both (you don’t know which). To fix this you must grant the user_u SELinux user permissions to those security sensitivities first.

semanage user --modify --range s0-s2 user_u

Now we can rerun the semanage login command and it should go through.

Finally, we have to set the permissions for files within the file system. First, it is helpful to be able to check the permissions on the file system. In most Linux commands which support SELinux, the security permissions of an object are viewable with the -Z option. Ex: ps -Z, ls -Z, etc.

ls -Z

WARNING: SELinux permissions do not supersede the regular DACL permissions set by Linux. DACL permissions are checked first and only after that check does the system consult SELinux. This means if DACL denies a user access to a file and SELinux permits it, the user will not be able to access the file.

Right now we see that test_file has a permission level of s0. If we wanted to make it so that user grant could not access the file we could change the file’s security sensitivity to s3.

Note: In SELinux processes may write to their own security level or up and may read their security level and down. The process cannot read up or write down.

You can set the SELinux file permissions with the chcon utility.

chcon -l s3 test_file

Now we see the permissions of test_file require s3 access.


Hope this tutorial saves everyone some time! If you have questions feel free to comment.

Helpful Commands

Edit SELinux Configuration File

vim /etc/selinux/config

Check SELinux Status


Check logs for SELinux activity:

cat /var/log/audit/audit.log | grep SEL

Configure MLS Security Levels

vim /etc/selinux/mls/setrans.conf

Print a listing of the security levels:

chcat -L

Add a User to SELinux

semanage login --add --seuser user_u grant

List SELinux User Mappings and Permissions

semanage login -l

Grant permissions to an SELinux user for a specific security sensitivity range:

semanage user --modify --range s0-s2 user_u

Grant permissions to a system user for a specific security sensitivity range:

semanage login --modify --seuser user_u --range s0-s2 grant

List file or process SELinux permissions:

ls -Z
ps -Z

Change the SELinux file permissions:

chcon -l s3 test_file


Leave a Reply