SELinux – a boon or bane?


SELinux seems to invoke conflicting emotions for many Linux practitioners. Before we explore why that might be the case, let’s answer some basic questions about SELinux. In this post, our goal is to provide an unbiased view of SELinux and its benefits and weaknesses for organizations considering implementing the tool. We will follow up with another post where we will take a closer under-the-hood look at SELinux.

What is SELinux?

SELinux, short for Security-Enhanced Linux, is a Linux security mechanism based on the principle of mandatory access control. Like the Linux Audit System (AuditD), SELinux is also a feature native to the Linux kernel and is supported today by many Linux distributions (distros) including Debian, Fedora, openSUSE, Red Hat Enterprise Linux (RHEL), Ubuntu, etc. It might be worth noting that SELinux is only one of the security mechanisms available via the Linux kernel, and other Linux monitoring approaches can be employed to implement security controls in place of or to augment SELinux.

SELinux has been in the works for a few decades now. The U.S National Security Agency started a research project in the 1990s to develop a robust security architecture based on mandatory access controls. A working prototype of this architecture called FLASK (Flux Advanced Security Kernel) was released on the Fluke OS, a research operating system. It was later released as an open-source product for general use in 2000. SELinux, an implementation of the FLASK architecture, was then integrated into the 2.6.x Linux kernel through the Linux Security Module kernel subsystem.

SELinux and Mandatory Access Control

SELinux implements a Mandatory Access Control system into the Linux kernel based on the principle of least privilege to provide administrators more granular control over access privileges. The principle of least privilege, as defined by Saltzer and Schroeder in the paper ‘The Protection of Information in Computer Systems, limits what every program and user can do on the system to the absolute minimum required to perform their function. This limits the unintentional and improper use of privileges. When an abuse of privilege occurs, since the activities that can be performed by an account (user/process) is restricted, tracing the impact of the compromise is less complex and can be focused on programs that the account had access to.

Access control is certainly one of the key pillars of cybersecurity. Several compliance standards such as NIST, HIPAA, and PCI DSS have strict and sometimes prescriptive requirements for logical and physical access controls. Logical Access Control requires validation of a user’s or program’s identity to access system resources such as network, applications, memory, databases, etc. 

A quick look at the different types of access control models will be helpful to understand why the Mandatory Access Control model makes SELinux more secure.  Discretionary Access Control, Mandatory Access Control, and Role-Based Access Control are some of the widely used approaches.

  • Discretionary Access Control (DAC): When a user or process requests access to a resource, DAC grants or restricts access to the requestor based on the resources’s owner or groups to which the owner belongs. An owner is a user or process which initially created the resource and each resource is assigned an owner. DAC relies on the human admin’s discretion,  because the resource’s owner controls access permissions for the resource and can pass access privileges to other users or processes that request access. While DAC is widely used because of its flexibility, this benefit can become a concern if access is transferred to other users or processes by a malicious actor posing as the owner. For example, normal Linux filesystem privileges are DAC-based. 
  • Mandatory Access Control (MAC): MAC aims to overcome shortcomings of DAC by restricting access only to users or processes that have the appropriate security level and need to access a system resource. The admin defines which users and processes need access to resources. This is strictly enforced by the operating system and cannot be overridden by other users. Unlike DAC, access privileges cannot be transferred to other users or processes at runtime.
  • Role-Based Access Control (RBAC): RBAC provides access based on the  business function of the requesting users instead of identity. Users are assigned to roles which are then mapped to resources to which they have access. RBAC could lead to role-explosion, which is a proliferation of roles to properly restrict access. In addition, this can be a daunting and error prone process for admins to manage leading to new roles being added without appropriate clean up of abandoned roles. Inefficiently implemented RBAC controls can be leveraged by malicious attackers to gain access to confidential and critical assets.

Why do some like SELinux?

The ability to enable fine-grained access controls and limit risks arising from processes with excess privileges sharing sensitive data makes the strongest case in favor of SELinux. When SELinux is enabled, users cannot edit admin policies or share access granted to them — only admins can define which users or programs have access to specific system resources. SELinux also allows for a very granular and precise definition of access privileges. Access will be denied unless allowed by an existing policy.

SELinux is enabled by default for some Linux distros and provides security features that can be used to protect confidential data, network ports, sockets, and files from unauthorized access. Even when an attacker gains access to a process or servers, SELinux mitigates the potential risk of such an attack as the attacker will only have limited access to objects defined in the policy. It also makes it much harder for an attacker to get root access, which can still happen through a kernel exploit within the scope of the SELinux restricted process or with misconfigured policies allowing you to pivot through other programs. 

SELinux is also available for enhancing security containerized environments by controlling processes running within containers from interacting with the host or other containers. It can also ensure that containers don’t run as root. RHEL offers an SELinux policy tool for Docker and Kubernetes. Some container OS’s such as Bottlerocket, a container OS built by AWS, include SELinux policies that are enabled by default. 

Why do some dislike SELinux?

Keeping aside conspiracy theories around NSA having a potential backdoor in the SELinux module, there are some genuine weaknesses in using SELinux successfully. Difficulty in understanding, managing, and troubleshooting SELinux are often listed as the main reasons to abandon the tool despite higher levels of security.

SELinux troubleshooting woes are one of the reasons it is disabled by users even if it is enabled by default by the Linux distribution or vendor. For this reason, some run SELinux in permissive mode instead of enforcing mode. 

In enforcing mode, SELinux policies actively restrict access based on the permissions enumerated in the policies. Permissive mode instead logs any access attempts which would have been denied in enforcing mode, allowing admins to see potential outcomes of switching to enforcing mode. It is important to note that the system is protected by SELinux only in the enforcing model — but this enforcement comes with the heavy price of challenging troubleshooting, which even Redhat’s SELinux troubleshooting guide acknowledges. Completely disabling SELinux also comes with its challenges — security context for system resources might have to be defined again when reenabled.

Performance is another area organizations need to pay attention to when SELinux is enabled. Considering that SELinux is a kernel module, it can log everything — all allowed and denied requests. Detailed logging is also required to troubleshoot issues. It is important to define logging requirements and tune the system to reduce performance impact.

Administrators should be cognizant that SELinux does not offer complete threat protection. Security offered by SELinux is defined by the policies and its limitations. The policy can control what privileges a process has but will not protect against exploitation of kernel vulnerabilities where writing to kernel memory is permitted. The blast radius can be reduced by limiting what the process can do. Therefore, care should be taken to design and test policies before they are implemented. An attacker can exploit a legitimate process and SELinux will not detect or protect against exploitation of processes; it will only limit the ability of the process to deviate from its normal behaviour post-exploitation

SELinux will log policy changes and processes which we blocked/allowed when trying to access a resource. These logs need to be aggregated and monitored to provide real detection value for admins. For smaller installations, standard Linux utilities such as auditD, ausearch, and aureport can be used to alert, filter, and report on specific events.  Larger deployments typically will employ log management tools for aggregation and alerting.

Conclusion

The key takeaway here is that SELinux is a useful security tool for organizations who have the resources and skills needed to manage it. The benefits of this free utility need to be weighed against the effort to implement, maintain, troubleshoot and tune for performance. Unfortunately, a poorly understood security tool can become a burden. 

The two big questions most people ask when it comes to SELinux are: What additional value comes from augmenting SELinux capabilities, taking performance overhead into consideration? Is SELinux really needed when other third party tools can provide more comprehensive security coverage? 

While SELinux provides granular control over which processes can use which system resources, risks around attackers exploiting legitimate processes and inability to protect against kernel vulnerabilities still exist. Organizations that have security and compliance needs should likely evaluate other tools to access their need to augment or replace SELinux.

Stay tuned for our next post on SELinux where we will give a more under-the-hood view of how SELinux works.