Latest revision as of 05:08, 24 October 2018

Security-Enhanced Linux (SELinux) is a Linux feature that provides a variety of security policies, including U.S. Department of Defense style Mandatory Access Control (MAC), through the use of Linux Security Modules (LSM) in the Linux kernel. It is not a Linux distribution, but rather a set of modifications that can be applied to Unix-like operating systems, such as Linux and BSD.

Running SELinux under a Linux distribution requires three things: An SELinux enabled kernel, SELinux Userspace tools and libraries, and SELinux Policies (mostly based on the Reference Policy). Some common Linux programs will also need to be patched/compiled with SELinux features.

All of the other SELinux-related packages may be included without changes nor risks.

Concepts: Mandatory Access Controls

Note: This section is meant for beginners. If you know what SELinux does and how it works, feel free to skip ahead to the installation.

Before you enable SELinux, it is worth understanding what it does. Simply and succinctly, SELinux enforces Mandatory Access Controls (MACs) on Linux. In contrast to SELinux, the traditional user/group/rwx permissions are a form of Discretionary Access Control (DAC). MACs are different from DACs because security policy and its execution are completely separated.

An example would be the use of the sudo command. When DACs are enforced, sudo allows temporary privilege escalation to root, giving the process so spawned unrestricted systemwide access. However, when using MACs, if the security administrator deems the process to have access only to a certain set of files, then no matter what the kind of privilege escalation used, unless the security policy itself is changed, the process will remain constrained to simply that set of files. So if sudo is tried on a machine with SELinux running in order for a process to gain access to files its policy does not allow, it will fail.

Another set of examples are the traditional (-rwxr-xr-x) type permissions given to files. When under DAC, these are user-modifiable. However, under MAC, a security administrator can choose to freeze the permissions of a certain file by which it would become impossible for any user to change these permissions until the policy regarding that file is changed.

As you may imagine, this is particularly useful for processes which have the potential to be compromised, i.e. web servers and the like. If DACs are used, then there is a particularly good chance of havoc being wreaked by a compromised program which has access to privilege escalation.

Precompiled modular Reference policy with headers and documentation but without sources. Development Arch Linux Refpolicy patches included, which fixes issues related to path labeling and systemd support. These patches are also sent to Reference Policy maintainers and their inclusion in selinux-refpolicy-archAUR is mainly a way to perform updates between Refpolicy releases.

Using the GitHub repository

All packages are maintained at https://github.com/archlinuxhardened/selinux . This repository also contains a script named build_and_install_all.sh which builds and installs (or updates) all packages in the needed order. Here is an example of a way this script can be used in a user shell to install all packages (with downloading the GPG keys which are used to verify the source tarballs of the package):

Of course, it is possible to modify the content of build_and_install_all.sh before running it, for example if you already have SELinux support in your kernel.

Changing boot loader configuration

If you have installed a new kernel, make sure that you update your bootloader accordingly to boot on it. Moreover you may need to add security=selinux selinux=1 to the kernel command line. More precisely, if the kernel configuration does not set CONFIG_DEFAULT_SECURITY_SELINUX, security=selinux is needed, and if it contains CONFIG_SECURITY_SELINUX_BOOTPARAM=yCONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0, selinux=1 is needed.

GRUB

Add security=selinux selinux=1 to GRUB_CMDLINE_LINUX_DEFAULT variable in /etc/default/grub
Run the following command:

Checking PAM

A correctly set-up PAM is important to get the proper security context after login. Check for the presence of the following lines in /etc/pam.d/system-login:

# pam_selinux.so close should be the first session rule
session required pam_selinux.so close

# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open

Installing a policy

Warning: The reference policy as given by Tresys is not very good for Arch Linux, as before release 20170805 almost no file were labelled correctly. The major problems were:

/lib and /usr/lib were considered different (and also /bin, /sbin, /usr/bin and /usr/sbin). This introduced some instability when applying labels to the whole system, as files in these folders might be seen with 2 (or 4) different labels.

Since refpolicy release 20170805 these two points have been addressed, but most people submitting patches to improve the policy use an other distribution (Debian, Gentoo, RHEL, etc.). Therefore the compatibility with Arch Linux packages is not perfect (for example the policy may not support the most recent features of a program).

to install the reference policy as it is. Those who know how to write SELinux policies can tweak them to their heart's content before running the commands written above. The command takes a while to do its job and taxes one core of your system completely, so do not worry. Just sit back and let the command run for as long as it takes.

To load the reference policy run:

# make load

Then, make the file /etc/selinux/config with the following contents (Only works if you used the defaults as mentioned above. If you decided to change the name of the policy, you need to tweak the file):

/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.
# Set this value once you know for sure that SELinux is configured the way you like it and that your system is ready for deployment
# permissive - SELinux prints warnings instead of enforcing.
# Use this to customise your SELinux policies and booleans prior to deployment. Recommended during policy development.
# disabled - No SELinux policy is loaded.
# This is not a recommended setting, for it may cause problems with file labelling
SELINUX=permissive
# SELINUXTYPE= takes the name of SELinux policy to
# be used. Current options are:
# refpolicy (vanilla reference policy)
# <custompolicy> - Substitute <custompolicy> with the name of any custom policy you choose to load
SELINUXTYPE=refpolicy

This is required to remove a few messages from /var/log/audit/audit.log which are a nuisance to deal with in the reference policy. This is an ugly hack and it should be made very clear that the policy so installed simply patches the reference policy in order to hide the effects of incorrect labelling.

Testing in a Vagrant virtual machine

It is possible to use Vagrant to provision a virtual Arch Linux machine with SELinux configured. This is a convenient way to test an Arch Linux system running SELinux without modifying a current system. Here are commands which can be used to achieve this:

Working with SELinux

SELinux defines security using a different mechanism than traditional Unix access controls. The best way to understand it is by example. For example, the SELinux security context of the apache homepage looks like the following:

The first three and the last columns should be familiar to any (Arch) Linux user. The fourth column is new and has the format:

user:role:type[:level]

To explain:

User: The SELinux user identity. This can be associated to one or more roles that the SELinux user is allowed to use.

Role: The SELinux role. This can be associated to one or more types the SELinux user is allowed to access.

Type: When a type is associated with a process, it defines what processes (or domains) the SELinux user (the subject) can access. When a type is associated with an object, it defines what access permissions the SELinux user has to that object.

Level: This optional field can also be know as a range and is only present if the policy supports MCS or MLS.

This is important in case you wish to understand how to build your own policies, for these are the basic building blocks of SELinux. However, for most purposes, there is no need to, for the reference policy is sufficiently mature. However, if you are a power user or someone with very specific needs, then it might be ideal for you to learn how to make your own SELinux policies.

This is a great series of articles for someone seeking to understand how to work with SELinux.

Troubleshooting

The place to look for SELinux errors is the systemd journal. In order to see SELinux messages related to the label system_u:system_r:policykit_t:s0 (for example), you would need to run:

# journalctl _SELINUX_CONTEXT=system_u:system_r:policykit_t:s0

Useful tools

There are some tools/commands that can greatly help with SELinux.

restorecon

Restores the context of a file/directory (or recursively with -R) based on any policy rules