Security-Enhanced Linux (SELinux), initially known for its perceived complexity in configuration and maintenance, has evolved into an indispensable security architecture across most Linux distributions. It empowers administrators to finely control the actions permitted to individual users, processes, and system daemons, thereby bolstering defense against potential security breaches.

Through the enforcement of precise security parameters, SELinux functions within the kernel to partition security policies and oversee their implementation, granting administrators heightened authority over system security. Additionally, SELinux’s seamless integration into the Linux kernel guarantees uninterrupted functionality, as it maintains continuous operation and is resistant to any attempts by users or processes to deactivate it. This inherent safeguard significantly strengthens the overall security of Linux systems.

The origin of SELinux dates back to its development by the National Security Agency (NSA), initiated through a sequence of patches applied to the Linux kernel via Linux Security Modules (LSM). Initially introduced as a loadable kernel module for Linux kernel v2.4, SELinux addressed inherent vulnerabilities in Linux security by augmenting Discretionary Access Controls (DAC) with robust Mandatory Access Control (MAC) mechanisms. Its inaugural release occurred with Linux Kernel 2.6 in 2000, marking a significant milestone in Linux security evolution.

Various Linux Security Module (LSM) framework listings are accessible under the /security directory within the kernel source tree. While AppArmor is the default choice for recent Ubuntu versions, SELinux is the default option for Android 5.0+ and distributions within the Red Hat/Fedora ecosystem.

Discretionary and Mandatory Access Controls

The foundation of traditional Linux security lies in Discretionary Access Control (DAC), which offers limited protection against malicious software or user actions. With DAC, access to files and devices is determined solely by user identity and ownership, allowing malware or compromised software to exploit the privileges of the user or root. As a result, when a user holds root privileges or an application is setuid or setgid to root, the process attains unrestricted control over the entirety of the file system.

SELinux brings Mandatory Access Control (MAC) to the Linux kernel, empowering administrators to define detailed security policies governing users, processes, files, and devices. This comprehensive control restricts the actions of processes, even those running as root, reducing the attack surface and enhancing system security. The kernel’s access control decisions are based on all the security-relevant information available and not solely on the authenticated user identity.

While SELinux complements DAC rather than replacing it, it offers the ability to restrict root processes and define more detailed access rules based on user groups, effectively limiting access to specific parts of the system.

Understanding the Mechanisms of SELinux

SELinux encompasses a comprehensive security framework consisting of various architectural components, policy and user types, and operational modes to ensure robust system protection and access control.

The SELinux architecture comprises four primary components:

  1. Subjects: Processes seeking access to resources. Subject requests are managed through Access Vector Rules.
  2. Object Manager (OM): Controls subject access, querying the Security Server for permission decisions.
  3. Security Server: Makes decisions based on the Security Policy and returns responses.
  4. Access Vector Cache (AVC): Stores security server decisions to enhance performance.

SEQ Figure \* ARABIC 1: source: https://github.com/SELinuxProject/selinux-notebook/raw/main/src/images/1-core.png

SELinux enforces access controls for applications, processes, and files on a system using security policies. These policies dictate the allowed access through a set of rules. When a subject (application or process) requests access to an object (such as a file), SELinux consults the access vector cache (AVC) for cached permissions. If a decision cannot be made based on cached permissions, the request is sent to the security server. The security server evaluates the security context of the subject and object using the SELinux policy database. Based on this evaluation, permission is either granted or denied.

SELinux labeling

SELinux functions as a labeling system, assigning labels to files, processes, and ports for logical grouping. The kernel manages label assignment during system boot. SELinux MAC assigns a security context to subjects (processes) and objects (system or userspace resources).

Following is the label syntax of SELinux:

user:role:type:level

  • User: SELinux user names typically end with _u. An SELinux user is distinct from a Linux user and can be associated with multiple Linux users, facilitating integration between the Linux and SELinux environments. There are several types of SELinux users:
  • unconfined_u: Unrestricted users.
  • sysadm_uUsers that only perform administrative tasks.
  • staff_u: Users that are for both end-user consumption as well as administrative tasks.
  • user_u: Non-privileged users.
  • system_u: Special SELinux user meant for system services.
  • Role: A vital component of the Role-Based Access Control (RBAC) model. They signify the authorized roles of users, such as administrator or regular user. Each role is authorized for specific domains and may cover multiple SELinux users, typically ending with _r. This setup mitigates vulnerability to privilege escalation attacks.
  • Type: In SELinux, types are crucial as all rules depend on them. They define permissions for subjects, domains, and objects. When linked to a process, a type determines which processes or domains the SELinux user can access. When connected to an object, it specifies the access permissions granted to the SELinux user. Type enforcement ensures only authorized processes and users access specific resources.
  • Level (optional): In SELinux, levels are part of Multilevel Security (MLS) and Multicategory Security (MCS). MLS ranges consist of sensitivity levels, written in pairs such as low_levelhigh_level. If levels are the same, it’s abbreviated as low_level, like s0-s0 being the same as s0.

SELinux Modes

SELinux consists of three modes: Enforcing, Permissive, and Disabled.

  • Enforcing mode: This is the default and most secure setting in SELinux. This mode strictly enforces access control policies defined by the sysadmin, preventing users from overriding them. Unauthorized access attempts are denied, and the decisions are recorded in AVC.
  • Permissive mode: Less secure than enforcing mode. In this mode, SELinux doesn’t enforce policies but logs events when unauthorized access is attempted. This allows sysadmins to monitor for security issues and adjust policies before switching to enforcing mode.
  • Disabled mode: The least secure. Here, SELinux doesn’t enforce any access control policies, offering no protection for system resources. This mode is typically used for testing or debugging purposes.

Conclusion

SELinux serves as a robust security framework for Linux systems, providing granular access control and defense against a multitude of security threats. When properly configured, it becomes an essential security tool. However, as with all software, misconfigurations can lead to vulnerabilities. Understanding its implementation and policies is crucial for effectively securing Linux systems. SELinux effectively secures and isolates system components, with its versatile modes, rigorous policy enforcement, and seamless integration with the Linux kernel, rendering it indispensable for safeguarding system integrity and mitigating risks across diverse Linux computing environments.


Editor’s Note: The opinions expressed in this guest author article are solely those of the contributor and do not necessarily reflect those of Tripwire.