Security Enhanced Linux, SELinux, is a project that was created with the intention of providing stricter security measures for access control and user permits, processes, files, devices, etc in Linux systems. This idea saw the light initially in the year 2000 from the NSA (National Security Agency) in the United States, published as an open code under the GNU PNL license. This project was integrated in Linux’s (LSM) security modules from the 2.6.0 version of the Linux kernel published in 2003. From that moment on a number of people, communities and organizations have collaborated to implement, improve and maintain the project. Red hat, or Selinux Project, are two main characters in this process.
What is SELinux?
SELinux is mandatory access control (MAC) implementation, in this case for Linux systems. With regards to traditional mechanisms based on file permissions, the mandatory access control contributes a greater security in the access and interactions between objects (devices, files) and subjects (users, processes, communications and actions) of the system. Besides, this access control system is “transparent” for the system’s user and its configuration depends on an administrator with maximum privileges in the system.
SELinux is based on “security contexts”, allocating “tags” to every element that is under supervision and a policy that defines what access and what operations are permitted. The rules established by the SELinux policy will be applied in an unavoidable manner on the contexts, over the file permissions (read, write, execute), that are typical of a discretional access control (DAC).
There are two fundamental terms to understand SELinux: tags and types of restrictions. With SELinux every file, user, port, process, etc. has some “tags” that characterize the permissions and actions that are permitted and it defines what is known as a SELinux security context. The restrictions are determined by the rules established in the policy.
- Etiquetas y políticas SELinux -
SELinux incorporates two types of policies:
- “Targeted” policy: Where only a number of demons selected by the system are under SELinux’s control, amongst them apache, dns, proxy squid, snmp and syslog. It’s the defect policy and it provides a quite efficient and relatively simple administration control. The remaining demons or processes are beyond SELinux’s security contexts and Linux’s security standard is applied on them.
- Multilevel/Multicategory policy (MLS/MCS): it’s an advanced SELinux application with a complexity and reach that is beyond this article. It’s used when you want to apply a strict control such as in organizations where security is critical.
SELinux context and tags
SELinux tags follow the following format::
The user tag identifies the selinux user, a different concept to the Linux user.
The role tag is the part of the model based on roles (RBAC) also used by SELinux.
The type tag defines the type of restriction. In the case of a process it is known as a domain and in the case of a file it is known as a type. The rules of the SELinux policy determine how types can access between themselves, domains with types or accesses between domains.
The level tag is used with advanced MLS/MCS policies. They’re extensions that enable an even more precise control through an added tagging with two entities: sensitivity and category. The sensitivity tag is hierarchical, this way a process in a certain level has reading access to inferior levels but can only write in a same or superior level. The category tag is a non-hierarchical attribute. With this type of policy more granular and precise rules can be defined, although the complexity increases.
The easiest way of operating SELinux is through the “targeted” policies which are based mainly on the use of type tags.
The contexts that defined by the tags can be viewed in an easy way with the “Z” parameter in commands such as ls for files and directories.
In the following example we can see the context defined by the content of the directory /var/www. We can see that in this context SELinux established the user system _u, the role object _r, and the type associated to each object, in this case types (domains) related to the contents of the apache programme and its demon httpd. Finally s0 marks the level at which it is only relevant in MLS/MCS policies.
- SELinux tags and contexts . The “.” That follows the rxw terna of the permissions indicate the presence of SELinux in the system -
Similarly, the tagging can be checked with the same parameter for users (id-Z) or processes (ps-Z). Observe the “unconfined_t” type and the extended MLS/MCS (s0-s0:c0.c1023) tags.
- User SELinux (id- Z) and processes (ps -Z) tags -
Booleans are certain values of SELinux policies that can be changed in execution time without having to manipulate a defined policy. It’s useful to modify elements or certain actions in execution time or make them persistent with the option of making the change permanent (-P parameter). The commands used to view and manipulate Booleans are getsebool and setsebool.
In the following example we can see how changing the allow_ftpd_anon_write Boolean to the value “on” gives an ftp writing permission to the anonymous user.
- Graphic 2. Chaning a Boolean value of the ftpd demon -
SELinux execution mode.
SELinux can operate in three different modes:
- Enforcing: : SELinux applies its policies and takes the established actions if any violations occur.
- Permissive: : SELinux applies its policies but doesn’t take action, it only registers and alerts the administrator that a rule has been violated.
- Disabled: SELinux is disabled.
The mode can be fixed permanently in the /ect/selinux/config configuration file.That file also specifies the type of policy (by defect, “targeted”).
- SELinux operating mode-
In execution time, the sestatus, getenforce, setenforce commands enable you to comfortably check, activate and deactivate SELinux without having to restart the system and without the results being persistent to restarts:
- Dynamic activation, deactivation of SELinux -
How does SELinux works?
The defined rules in the SELinux policy are cached by the system’s kernel in AVC (Access Vector Cache) vectors that contain the permissions of each object and subject that is under control. When an operation or access is going to be executed, the kernel checks the AVC cache permitting or blocking the action appropriately.
- SELinux decisión process (Red Hat. Selinux Users and Administrators Guide) -
Every action that SELinux adopts is determined by the contexts (tagging) and the restrictions that are defined in the rules of the policy that is stored in the AVC vectors.
SELinux in action
The context created by the SELinux tagging is applied to every element in the system, including its users (_u tag). This enables the creation of “domains” that are characterized by their security contexts and the application of rules for the interaction between elements of the different domains.
For example, in the case of users of the Linux system, they all have a context determined by their tags, one of which is the _u tag that identifies the corresponding selinux user. This enables adding an additional security layer to the traditional discretionary permissions (DAC) of the Linux user with the mandatory access control (MAC). The selinux user’s permissions apply their tagging depending on the context that the user is confined in.
- Selinux users tagging. -
- Classic Discretionary Access Control (DAC) -
Similarly, every process and file is tagged with a type (_t tag). We can understand that the type represents a domain for the processes and a type for files. This way they can separate each process from others that are running in a different domain that is determined by its context. SELinux policies establish how the processes can interact with other processes or files. What do we achieve with this? Confinement. This mode of operating decreases, for example, the risk of the elevation of privileges or processes from accessing certain files or executables although the classic permissions (DAC) enable it. All of this thanks to the separation in SELinux contexts. For example, imagine an HTTP server is compromised by an attacker. With a well configured SELinux policy, the attack will be confined and restricted to what is permitted in the context and domain of the user process, role, type and optionally the level, as well as the domain of the process. The option to access other resources that under a discretionary mechanism could be violated is denied.
- MAC Control Access. SELinux. Confinements in contexts -
A practical example.
We’re going to explain an example in which the SELinux access control ultimately denies the execution of a file, even when the standard Linux permissions permit it.
Selinux users and their context
Every Linux system user is “mapped” to a type of a SELinux user with the corresponding policy.
Let’s look at the types of selinux users:
- User and role tags of a selinux user -
The unconfined_u SELinux user is a type of selinux user that isn’t under any particular context restrictions. This way, with this type of user only the standard Linux DAC restrictions will be applied.
In the following graphic we will demonstrate how usuario2 can execute the “fichero.sh” file, given that the standard permissions it has enable both the owner user (usuario1) and the users of the group and others to execute:
-rwxrwxr-x usuario1 usuario1 fichero.sh
As the standard permissions enable an access and there are no restrictions in the SELinux context, the execution of the file on behalf of usuario2 is permitted:
- Selinux users in the system. By default, every Linux user is assigned the “unconfined_u” selinux user -
Now we will demonstrate what happens when usuario2 (the unconfined_u selinux user) modifies its SELinux mapping and is associated to the selinux guest_u user.
According to the SELinux administration guide published by Red Hat, the selinux guest_u user has restricted execution permissions:
"By default, Linux users in the guest_t and xguest_t domains cannot execute applications in their home directories or the /tmp/ directory, preventing them from executing applications, which inherit users’ permissions, in directories they have write access to. This helps prevent flawed or malicious applications from modifying users’ files."
In other words, a Linux user that is mapped to a “guest_u” user can’t execute files even when it possesses Linux (DAC) execution permissions to do so.
Effectively, if we change the mapping of usuario2 to guest_u selinux user’s we will demonstrate how the application of SELinux’s policy impedes its execution:
- Modification of the tag that identifies the selinux user. We change the unconfined_u type to guest_u -
- EjExecution denied by SELinux despite there being execution permissions for every Linux user -
SELinux also has a mechanism that registers events when an AVC violation has taken place and tools aimed at detecting possible problems and also suggesting a solution. These registrations are stored in a log register that is governed by a process of the system. In the case of the example, the generated event is the following:
- Log register generated by SELinux -