
Getting Started with SELinux
Author’s note: Some parts of this article appeared in Chapter 46 of my book, “Using and Administering Linux – Zero to SysAdmin: 2nd Edition, Vol. 2.” Image via Creative Commons, modified by Both.org
SELinux1 was developed by the NSA to provide a highly secure computing environment. True to the GPL, they have made this code available to the rest of the Linux community and it is included as part of nearly every mainstream distribution.
I have no idea how much we should trust the NSA itself, but because the code is open source and can be and has been examined by many programmers around the world, the likelihood of it containing malicious code is quite low. With that said, SELinux is an excellent security tool.
SELinux is designed to enhance existing security solutions, not replace them. Even when running SELinux, it is important to continue to follow good security practices, such as keeping software up-to-date, using hard-to-guess passwords, and firewalls.
A brief description of SELinux
SELinux provides Mandatory Access Control (MAC) which ensures that users must be provided explicit access rights to each object in the host system. The objective of SELinux is to prevent a security breach – an intrusion – and to limit the damage that crackers may wreak if they do manage to access a protected host. It accomplishes this by labeling filesystem objects and processes. It uses policy rules to define the possible interactions between labeled objects and the kernel enforces these rules.
According to the Red Hat documentation:
SELinux is a Linux Security Module (LSM) that is built into the Linux kernel. The SELinux subsystem in the kernel is driven by a security policy which is controlled by the administrator and loaded at boot. All security-relevant, kernel-level access operations on the system are intercepted by SELinux and examined in the context of the loaded security policy. If the loaded policy allows the operation, it continues. Otherwise, the operation is blocked and the process receives an error.
Red Hat has a well-done document that covers SELinux.2 Although written for RHEL 7, it will also apply to all current versions of RHEL, CentOS, Fedora, and other Red Hat derived distributions.
Under Fedora, SELinux has provides three sets of policy files although you can create your own and other distros may have other pre-configured policies. By default, only the Targeted policy files are installed by Fedora, but other policy files can be easily installed from the Fedora repositories. Figure 1 shows the pre-configured policies along with a short description of each.
SELinux Policy Name | Description |
Minimum | A very limited policy that protects very little. A good starting place for testing and learning in a real-world environment. |
Targeted | This is the default policy that targets only specific processes and files. Daemons for dhcpd, httpd, named, nscd, ntpd, portmap, snmpd, squid, and syslogd may be protected – the specific ones depend upon the distribution and release. Anything unprotected runs in the unconfined_t domain which allows subjects and objects with that security context to operate using standard Linux security. |
Multi-level Security (MLS) | This policy gives full SELInux protection to all objects. This is what you want if you are really paranoid. |
Sandbox | A set of SELinux policies that allow a system administrator to run an application within a tightly confined SELinux domain. Restrictions on permission to open new files or access to the network can be defined. This enables testing the processing characteristics of untrusted software securely, without risking damage to the system. |
Figure 1: These are the three default SELinux policies provided by Fedora.
SELinux has three modes of operation, enforcing and permissive, as described in Figure 2.
SELinux Mode | Description |
Disabled | SELinux is disabled. |
Permissive | Behaves as if it were enforcing the active policy, including labeling objects and adding entries to log files. It does not actually enforce the policy. This mode could be used to test SELinux policies while not interfering with any aspect of the system. |
Enforcing | Enforces the current policy. This is the default SElinux policy. |
Figure 2: SELinux operational modes.
Any of the SELinux policies can be enabled in either permissive or enforcing mode.
Status
You can easily check the current status of SELinux on your systems. This can be done as a non-root user. Figure 3 shows the minimal result when it’s disabled.
$ sestatus
SELinux status: disabled
Figure 3: SELinux is disabled.
In Figure 4, we see a system on which SELinux is enabled.
$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: permissive
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 34
Figure 4: SELinux is enabled on this system.
In Figure 4 you can also see some details such as the policy name and its current mode. The -v option will also show process and file contexts but those details are beyond the scope of this article.
How to enable SELinux
SELinux is a kernel security module and must be enabled at boot time. The /etc/default/grub file for Fedora contains the kernel command line, in which selinux=1 is the option that enables SELinux.
GRUB_CMDLINE_LINUX="rd.lvm.lv=vg01/root rd.lvm.lv=vg01/usr selinux=1"
Figure 5: The /etc/default/grub file contains this kernel command line to enable SELinux.
You must rebuild the GRUB configuration after changing this (or anything else) in the grub defaults file. Figure 6 illustrates the command required to do that. Note that it must be performed as root.
# grub2-mkconfig > /boot/grub2/grub.cfg
Figure 6: Rebuild the GRUB configuration file.
The default SELinux configuration file, /etc/selinux/conf, is shown in Figure 7. It’s quite a simple file, but there’s a little trick that can prevent a failure to boot. If SELinux hasn’t been previously active, in which case the files it’s monitoring will not have been labeled, you must set its state to permissive. If you set it to enforcing first, an error can prevent the system from booting and you’ll need to boot into recovery mode using a live USB drive to recover.
Just to ensure I have no problems, I always reboot the system into permissive mode first.
# 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=permissive
# SELINUXTYPE= can take one of these three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
Figure 7: The default SELinux configuration file.
Reboot the system to enable SELinux. During the reboot, the files protected by the current policy will be labeled, and the system will be automatically rebooted to activate SELinux. Figure 8 shows the status of SELinux after this reboot.
# sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: permissive
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 34
Figure 8: The SELinux status after rebooting into permissive mode with the targeted policy.
After booting the system into SELinux permissive mode, you should use the system for a few days and review the AUDIT journal entries to ensure that you’re not going to run into any difficulties once you switch to enforcing mode. When you’re ready, change the SELinux configuration to enforcing as shown in Figure 9 and reboot to activate the enforcing mode.
# 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 three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
Figure 9: The SELinux configuration file set for enforcing more with the targeted policy.
Verify that SELinux is in enforcing mode with the desired policy.
$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 34
Figure 10: The SELinux status is shown with enforcing mode for the targeted policy.
Additional SELinux considerations
Making changes to the filesystem while SELinux is disabled may result in improperly labeled objects and possible vulnerabilities. The best way to ensure that everything is properly labeled is to add an empty file named /.autorelabel in the root directory and reboot the system.
SELinux is intolerant of extra whitespace. Be sure to eliminate extra whitespace in SELinux configuration files in order to ensure that there are no errors.
- Opensource.com, A sysadmin’s guide to SELinux: 42 answers to the big questions, https://opensource.com/article/18/7/sysadmin-guide-selinux ↩︎
- Red Hat, Selinux User’s And Administrator’s Guide, https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/selinux_users_and_administrators_guide/index ↩︎