SELinux System Administration

5 (2 reviews total)
By Sven Vermeulen
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies

About this book

NSA Security-Enhanced Linux (SELinux) is a set of patches and added utilities to the Linux kernel to incorporate a strong, flexible, mandatory access control architecture into the major subsystems of the kernel. With its fine-grained yet flexible approach, it is no wonder Linux distributions are firing up SELinux as a default security measure.

SELinux System Administration covers the majority of SELinux features through a mix of real-life scenarios, descriptions, and examples. Everything an administrator needs to further tune SELinux to suit their needs are present in this book.

This book touches on various SELinux topics, guiding you through the configuration of SELinux contexts, definitions, and the assignment of SELinux roles, and finishes up with policy enhancements. All of SELinux's configuration handles, be they conditional policies, constraints, policy types, or audit capabilities, are covered in this book with genuine examples that administrators might come across.

By the end, SELinux System Administration will have taught you how to configure your Linux system to be more secure, powered by a formidable mandatory access control.

Publication date:
September 2013


Chapter 1. Fundamental SELinux Concepts

SELinux (Security Enhanced Linux) brings additional security measures for your Linux system to further protect the resources on the system.

In this chapter, we will cover:

  • Reasons for SELinux using labels to identify resources

  • The way SELinux differentiates itself from regular Linux access controls through the enforcement of security rules

  • How to know these rules are provided through policy files

At the end, we will provide an overview of the differences between SELinux implementations across distributions.


Providing more security to Linux

Seasoned Linux administrators and security engineers already know that they need to have some trust in the users and processes on their system in order for the system to remain secure. Part of that is because users can attempt to exploit vulnerabilities found on the software running on the system, but a large part of it is because the secure state of the system depends on the behavior of the users. A Linux user with access to sensitive information can easily leak that out to the public, manipulate the behavior of the applications he launches, and can do many more things. The default access controls in place in a regular Linux system are discretionary, meaning it is up to the user's discretion how the access controls should behave.

The Linux DAC (Discretionary Access Control) mechanism is based on the user and/or group information of the process versus the user and/or group information of the file, directory, or other resource that is being manipulated. Consider the /etc/shadow file, which contains the password and account information of the local Linux accounts:

$ ls -l /etc/shadow
-rw------- 1 root root 1010 Apr 25 22:05 /etc/shadow

Without additional access control mechanisms in place, this file is readable and writable by any process that is owned by the root user, regardless of the purpose of the process on the system. The shadow file is a typical example of a sensitive file that we don't want to see leaked or abused in any other fashion. Yet, the moment someone has access to the file he can copy it elsewhere, for example, to their home directory or even mail it to his own computer and attempt to attack the password hashes stored within.

Another example of how Linux DAC requires trust from its users is when a database is hosted on the system. Database files themselves are (hopefully) only manageable by the runtime user of the database management system (DBMS) and the Linux root user. Properly secured systems will grant the additional users access to these files (for instance through sudo) by allowing these users to change their effective user ID from their personal user to the database runtime user, or even root. Those users too can analyze the database files and gain access to potentially very confidential information in the database without going through the DBMS.

But users are not the only reason of securing a system. Lots of software daemons run as the Linux root user or have significant privileges on the system. Errors within those daemons can easily lead to information leakage or might even be exploitable remote command execution vulnerabilities. Backup software, monitoring software, change management software, scheduling software, and so on, they all often run with the highest privileged account possible on a regular Linux system. Even when the administrator does not fully trust the users, their interaction with the daemons still induces a potential security risk. As such, the users still get some kind of trust in order for the system to function properly. And through that, he leaves the security of the system to the discretion of its (many) users.

Enter SELinux which provides an additional access control layer on top of the standard Linux DAC mechanism. SELinux provides a MAC (Mandatory Access Control) system that, unlike its DAC counterpart, gives the administrator full control over what is allowed on the system and what isn't. It accomplishes this by supporting a policy-driven approach on what processes are and aren't allowed to do and what not, and enforcing this policy through the Linux kernel.

The word "mandatory" here, just like the word "discretionary" before, is not chosen by accident to describe the abilities of the access control system. Both are known terms in the security research field and have been described in many other publications, including the TCSEC (Trusted Computer System Evaluation Criteria) ( standard (also known as the "Orange Book") by the Department of Defense, in the United States of America's in 1985. This publication has lead to the common criteria standard for computer security certification at (ISO/IEC 15408)

Mandatory means that access control is enforced by the operating system and defined solely by the administrator. Users and processes that do not have the permission to change the security rules cannot work around the access control; security is not left at their discretion anymore.

Linux security modules to the rescue

Consider the example of the shadow file again. A MAC system can be configured so that the file can only be read from and written to by particular processes. A user logged on as root cannot directly access the file or even move it around. He can't even change the attributes of the file:

# id
uid=0(root) gid=0(root)
# cat /etc/shadow
cat: /etc/shadow: Permission denied
# chmod a+r /etc/shadow
chmod: changing permissions of '/etc/shadow': Permission denied

This is enforced through rules that describe when the contents of a file can be read. With SELinux, these rules are defined in the SELinux policy and are loaded when the system boots. It is the Linux kernel itself that is responsible for enforcing the rules, and does so through LSM (Linux Security Modules).

High-level overview of how LSM is integrated in the Linux kernel

LSM has been available in the Linux kernel since version 2.6, somewhere in December 2003. It is a framework that provides "hooks" inside the Linux kernel on various locations, including the system call entry points, and allows a security implementation (for example, SELinux) to provide functions to be called when a hook is triggered. These functions can then do their magic (for instance, checking the policy and other information) and give a go / no go back to allow the call to go through or not. LSM by itself does not provide any security functionality, instead it relies on security implementations that do heavy lifting. SELinux is one of these implementations that uses LSM, but others such as TOMOYO Linux and AppArmor also use it.

SELinux versus regular DAC

SELinux does not change the Linux DAC implementation, nor can it override denials made by the Linux DAC permissions. If a regular system (without SELinux) prevents a particular access, there is nothing SELinux can do to override this decision. This is because the LSM hooks are triggered after the regular DAC permission checks have been done.

If you need to allow an additional user access to a file, you will need to look into other features of Linux such as the use of POSIX Access Control Lists through the setfacl and getfacl commands. These allow the user (not only the administrator!) to set additional access controls on files and directories, opening up the provided permission to additional users or groups.

Restricting root privileges

The regular Linux DAC allows for an all-powerful user: root. Unlike most other users on the system, a logged on root user has all the rights needed to fully manage the entire system, ranging from overriding access controls to controlling audit, changing user ID, managing the network, and many more. This is handled through a security concept called capabilities (for an overview of Linux capabilities, check out the capabilities manual page: man capabilities). SELinux is also able to restrict access to these capabilities in a fine-grained manner.

Due to this fine-grained authorization aspect of SELinux, even the root user can be quite confined without impacting the operations on the system. The example of accessing /etc/shadow previously is just one example of things that a powerful user as root still might not be able to do due to the SELinux access controls in place.

When SELinux was added to the mainstream Linux kernel, some security projects even went as far as providing public root shell access to a SELinux protected system, asking hackers and other security researchers to compromise the box. The ability to restrict root was welcomed by system administrators that sometimes need to pass on the root password or root shell to other users (for example, database administrators) that needed root privileges when their software went haywire. Thanks to SELinux, the administrator can now pass on a root shell while reassuring himself that the user only has those rights he needs, and not full system administration rights.

Enabling SELinux – not just a switch

To enable SELinux on a Linux system, it is not just a matter of enabling the SELinux LSM module within the Linux kernel. SELinux comprises not only of the kernel implementation, but also has libraries and utilities that are needed on the system. These libraries and utilities are called the SELinux userspace ( Next to the userspace applications and libraries, various components on a Linux system need to be updated with SELinux-specific code, including the init system, core utilities, and the C library. And finally, we need a policy that tells SELinux how it should enforce access.

Because SELinux isn't just a switch that needs to be toggled, Linux distributions that support SELinux usually come with SELinux predefined and loaded: Fedora and RedHat Enterprise Linux (with its derivatives, for example, CentOS and Oracle Linux) are the most well-known examples. Other supporting distributions might not automatically have SELinux enabled but can easily support it through the installation of additional packages (which is the case for Debian and Ubuntu), and others have a well-documented approach on how to convert a system towards SELinux (for example, Gentoo and Arch Linux).

Throughout the book, examples will be shown from Gentoo and Fedora 19 (which is similar to RedHat Enterprise Linux). We opt to use these two because they have different implementation details, allowing us to show the full potential of SELinux.


Everything gets a label

In natural language, the term "context" can be used in a sentence for example, "it depends on the context". Well, with SELinux, it does depend on the context! The context of a process is what identifies the process to SELinux. SELinux has no notion of Linux process ownership and frankly doesn't care how the process is called, which process ID it has and under which account the process runs. All it wants to know is what the context is of that process. Let's look at an example context: the context of the current user (try it out yourself if you are on a SELinux enabled system):

$ id -Z

The id command, which returns information about the current user, with the -Z switch (a commonly agreed switch for displaying SELinux information) shows us the context of the current user (actually the context of the id process itself when it was executing). As we can see, the context is a string representation, and looks like it has five fields (it doesn't, it has four fields. The last field just happens to contain a ':').

SELinux developers decided to use contexts (strings) instead of real process metadata as well as contexts on resources (often called labels) for its access controls. This is different to MAC systems such as AppArmor which use the path of the binary (and thus the process name) and the paths of the resources to handle permission checks. The decision to make SELinux a label-based mandatory access control was taken for various reasons, which are as follows:

  • Using paths might be easier for administrators, but this doesn't allow to keep the context information close to the resource. If a file or directory is moved, remounted, or a process has a different namespace view on the files, the access controls might behave differently. With contexts, this information is retained and the system keeps controlling the resource properly.

  • Contexts reveal the context of the process very well. The same binary application can be launched in different contexts depending on how it got started. The context value (for example, the one shown in the id -Z output earlier on) is exactly what the administrator needs. With it, he knows what the rights are of each of the running instances, but he can also deduce from it how the process might have been launched.

  • Contexts also make abstraction of the object itself. We are talking now about processes and files, but this is also applicable to less tangible resources, for example: pipes (inter-process communication) or database objects. Path-based identification only works as long as you can write a path.

As an example, consider the following two sentences:

  • Allow the httpd processes to bind to the TCP port 80

  • Allow the processes labeled with "httpd_t" to bind to TCP ports labeled with "http_port_t"

In the first example, we cannot easily reuse this policy when the web server process isn't using the httpd binary (perhaps because it was renamed, or it isn't Apache but another web server), or when we want to have HTTP access on a different port. With the labeled approach, the binary can be called "apache2" or ""; as long as the process is labeled httpd_t then the policy applies. The same with the port definition, you can label port 8080 with http_port_t and thus allow the web servers to bind to that port as well.

The context fields

To come to a context, SELinux uses at least three, and sometimes four values. Let us look at the context of the Apache web server as an example:

$ ps -eZ | grep httpd
system_u:system_r:httpd_t:s0  511  ?   00:00:00 httpd

As we can see, the process is assigned a context which is made up of the following fields:

  • system_u - represents the SELinux user

  • system_r - represents the SELinux role

  • httpd_t - represents the SELinux type (also known as domain in case of a process)

  • s0 - represents the sensitivity

The roles can be depicted as follows:

Structure of a SELinux context, using the id -Z output as an example

When we work with SELinux, contexts are all that we need. In the majority of cases, it is the third field (called the domain or type) that is most important as the majority of SELinux policy rules (over 99 percent) consists of rules related to the interaction between two types (without mentioning roles, users, or sensitivities).

SELinux types

As mentioned, SELinux is a label-based access control mechanism. In most SELinux literature, this is fine-tuned to say that SELinux is a type enforcement mandatory access control system. This is because the type of a process (called the domain) defines the fine-grained access controls of that process with respect to itself or other types (which can be processes, files, sockets, network interfaces, and more). When some access attempts are denied, the fine-grained access controls on the type level are most likely to blame.

With type enforcement, SELinux is able to control what an application is allowed to do based on how it got executed in the first place: a web server that is launched interactively by a user will run with a different type than a web server executed through the init system, even though the process binary and path are the same. The web server launched from the init system is most likely trusted (and thus allowed to do whatever web servers are supposed to do), whereas a user launched web server is less likely to be of "normal behavior" and as such will have different privileges.

For instance, look at the following dbus-daemon processes:

# ps -eZ | grep dbus-daemon
system_u:system_r:system_dbusd_t 4531 ?        00:00:00 dbus-daemon
staff_u:staff_r:staff_dbusd_t    5266 ?        00:00:00 dbus-daemon

In the preceding example, one dbus-daemon process is the system D-Bus daemon running with the aptly named system_dbusd_t type, whereas another one is running with the staff_dbusd_t type assigned to it. Even though their binaries are completely the same, they both serve a different purpose on the system and as such have a different type assigned. SELinux then uses this type to govern the actions allowed by the process towards other types, including how system_dbusd_t can interact with staff_dbusd_t.

SELinux types are by convention suffixed with "_t", although this is not mandatory.

SELinux roles

SELinux roles - the second part of a SELinux context, enable SELinux to support role-based access controls. Although type enforcement is the most used (and known) part of SELinux, role-based access control is vital in order to keep a system secure, especially from malicious user attempts. SELinux roles are used to define which types a user processes can be in. As such, SELinux roles help define what a user can and cannot do.

On most SELinux enabled systems, the following roles are made available to be assigned to users. By convention, SELinux roles are defined with an "_r" suffix. Some of the roles and their descriptions are as follows:


This role is meant for restricted users, the user_r SELinux role is only allowed to have processes with types specific to end-user applications. Privileged types, for instance, those used to switch Linux user are not allowed for this role.


This role is meant for non-critical operator tasks, the SELinux staff_r role is generally restricted to the same applications as the restricted user, but is also allowed to (a very few) more privileged types. It is the default role for operators to be in (so as to keep those users in the "least privileged" role as long as possible).


This role is meant for system administration tasks, the sysadm_r SELinux role is very privileged, allowing for various system administration tasks. However, certain end user application types might not be supported (especially if those types are used for potentially vulnerable or untrusted software) to try and keep the system free from infections.


This role is meant for daemons and background processes, the system_r SELinux role is quite privileged, supporting the various daemon and system process types. However, end user application types and other administrative types are not allowed in this role.


This role is meant for end users, the unconfined_r role is allowed a limited number of types, but those types are very privileged as it is meant for running any application launched by a user in a more or less unconfined manner (not restricted by SELinux rules). This role as such is only available if the system administrator wants to protect certain processes (mostly daemons) while keeping the rest of the system operations almost untouched by SELinux.

Other roles might be supported as well, such as guest_r and xguest_r (Fedora). It is wise to consult the distribution documentation for more information about the supported roles.

SELinux users

A SELinux user is different from a Linux user. Unlike the Linux user information which can change while the user is working on the system (through tools such as sudo or su), the SELinux policy will enforce that the SELinux user remains the same even when the Linux user itself has changed. Because of the immutable state of the SELinux user, specific access controls can be implemented to ensure that users cannot work around the (limited) set of permissions granted to them, even when they get privileged access. An example of such an access control is the UBAC (User Based Access Control) feature that some Linux distributions (optionally) enable, not allowing access to files of different SELinux users.

But the most important feature of SELinux users is that SELinux user definitions restrict which roles the (Linux) user is allowed to be in. Once a user is assigned a SELinux user, he cannot switch to a role that he isn't meant to be in. This is the role-based access control implementation of SELinux.

SELinux users are, by convention, defined with a "_u" suffix, although this is not mandatory. The SELinux users that most distributions have available are named after the role they represent, but instead of ending with "_r" they end with "_u". For instance, for the sysadm_r role, there is a sysadm_u SELinux user.

Sensitivity labels

Although not always present (some Linux distributions by default do not enable sensitivity labels), the sensitivity labels are needed for the MLS (Multi-Level Security) support within SELinux. Sensitivity labels allow classification of resources and restriction of access to those resources based on a security clearance. These labels consists of two parts: a confidentiality value (prefixed with "s") and a category value (prefixed with "c").

In many organizations and companies, documents are labeled internal, confidential, or strictly confidential. SELinux can assign processes a certain clearance level towards these resources. With MLS, SELinux can be configured to follow the Bell-LaPadula model, a security model that can be characterized by "no read up, no write down": based on a process' clearance level, that process cannot read anything with a higher confidentiality level nor write to (or communicate otherwise with) any resource with a lower confidentiality level. SELinux by itself, does not use the "internal", "confidential", and other labels. Instead, it uses numbers from 0 (lowest confidentiality) to whatever the system administrator wants to be as the highest value (this is configurable and set when the SELinux policy is built).

Categories allow for resources to be tagged with one or more categories on which access controls are also possible. The idea behind categories is to support multi-tenancy (for example, as systems hosting applications for multiple customers) within a Linux system, by having processes and resources belonging to one tenant to be assigned a particular category whereas the processes and resources of another tenant getting a different category. When a process does not have proper categories assigned, it cannot do anything with resources (or other processes) that have other categories assigned.

In that sense, categories can be seen as tags, allowing access to be granted only when the tags of the process and the target resource match.


Policies – the ultimate dictators

Enabling SELinux does not automatically start enforcement of access, if SELinux is enabled and it cannot find a policy, it will refuse to start. That is because the policy defines the behavior of the system (what should SELinux allow). Because SELinux is extremely flexible, its policy developers already started differentiating one policy implementation from another through what it calls a policy type or policy store.

A policy store contains a single policy, and only a single policy can be active on a system at any point in time. Administrators can switch a policy, although this requires the system to be rebooted, and might even require relabeling the entire system (relabeling is the act of resetting the contexts on all files and resources available on that system). The active policy on the system can be queried using sestatus (SELinux status) as follows:

# sestatus | grep "Loaded policy"
Loaded policy name:             targeted

In the preceding example, the currently loaded policy is named targeted. The policy name that SELinux will use upon its next reboot is defined in the /etc/selinux/config configuration file as the SELINUXTYPE parameter.

Most SELinux supporting distributions base their policy on the reference policy [], a fully functional SELinux policy set managed as a free software project. This allows distributions to ship with a functional policy set rather than having to write one themselves. Many project contributors are distribution developers, trying to push changes of their distribution to the reference policy project itself, where the changes are peer-reviewed to make sure no rules are brought into the project that might jeopardize the security of any platform.

SELinux policy store names and options

The most common SELinux policy store names are strict, targeted, mcs, and mls. None of the names assigned to policy stores are fixed though, so it is a matter of convention. Hence, it is recommended to consult the distribution documentation to verify what should be the proper name of the policy. Still, the name often gives some information about the options that are enabled on the system.

MLS status

One of the options is MLS support that can either be enabled or disabled. If disabled, then the SELinux context will not have a fourth field with sensitivity information in it, making the contexts of processes and files look as follows:


To check if MLS is enabled, it is sufficient to see if the context indeed doesn't contains such a fourth field, but it can also be acquired from the Policy MLS status line in the output of sestatus:

# sestatus | grep MLS
Policy MLS Status:            disabled

Another method would be to look into the pseudo file, /sys/fs/selinux/mls. a value of 0 means disabled, whereas a value of 1 means enabled:

# cat /sys/fs/selinux/mls

Dealing with unknown permissions

Permissions (such as read, open, and lock) are defined both in the Linux kernel and in the policy itself. However, sometimes newer Linux kernels support permissions that the current policy doesn't.

A recently introduced one is block_suspend (to be able to block system suspension) and when that occurs, SELinux has to take the decision: as the policies are not aware of this new permission, how should it deal with the permission when triggered? SELinux can allow (assume everything is allowed to perform this action), deny (assume no one is allowed to perform this action), or reject (stop loading the policy at all and halt the system) the request. This is configured through the deny_unknown value.

To see the state for unknown permissions, look for the Policy deny_unknown status line in sestatus:

# sestatus | grep deny_unknown
Policy deny_unknown status:   denied

Administrators can set this for themselves in the /etc/selinux/semanage.conf file through the handle-unknown key (with allow, deny, or reject).

Supporting unconfined domains

A SELinux policy can be written as very strict, limiting applications as close as possible to their actual behavior, but it can also be written to be very liberal in what applications are allowed to do. One of the concepts available in many SELinux policies is the idea of unconfined domains. When enabled, it means that certain SELinux domains (process contexts) are allowed to do almost anything they want (of course within the boundaries of the regular Linux DAC permissions which still hold) and only a few selected are truly confined (restricted) in their actions.

Unconfined domains have been brought forward to allow SELinux to be active on desktops and servers where administrators do not want to fully restrict the entire system, but only a few of the applications running on it.

With other MAC systems, for example, AppArmor, this is inherently part of the design of the system. However, SELinux was designed to be a full mandatory access control system and thus needs to provide access control rules even for those applications that shouldn't need any. By marking these applications as unconfined, almost no additional restrictions are imposed by SELinux.

We can see if unconfined domains are enabled on the system through seinfo:

# seinfo -tunconfined_t
# seinfo -tunconfined_t
ERROR: could not find datum for type unconfined_t

Most distributions that enable unconfined domains call their policy targeted, but this is just a convention that is not always followed. Hence, it is always best to consult the policy using seinfo to make this sure.

User-based access control

When UBAC is enabled, certain SELinux types will be protected by additional constraints. This will ensure that one SELinux user cannot access files (or other specific resources) of another user. UBAC gives some additional control on information flow between resources, but is far from perfect. In its essence, it is made to isolate SELinux users from one another.

Many Linux distributions disable UBAC. Gentoo allows users to select if they want UBAC or not through a Gentoo USE flag (which is enabled by default).

Policies across distributions

As mentioned, policy store names are not standardized. What is called targeted in Fedora is not targeted in Gentoo. Of the options mentioned previously, the following table shows us how some of the policy stores are implemented across these two distributions:


Policy store name



Unconfined domains?







Yes (configurable)

Fedora 19


Yes (only s0)


Yes, but limited







Yes (configurable)

Fedora 19


Yes (only s0)






Yes (only s0)


Yes (configurable)

Yes (configurable)





Yes (configurable)

Yes (configurable)

Fedora 19






Other distributions might even have different names and implementation details.

Yet, besides the naming differences, many of the underlying settings can be changed by the administrator. For instance, even though Fedora does not have a strict policy, it does have a documented approach on running Fedora without unconfined domains. It would be wrong to state that Fedora as such does not support fully confined systems.

MCS versus MLS

In the feature table, we notice that for MLS, some policies only support a single sensitivity (s0). When this is the case, we call the policy an MCS (Multi Category Security) policy. The MCS policy enables sensitivity labels, but only with a single sensitivity while providing support for multiple categories (and hence the name).

With the continuous improvement made in supporting Linux in PaaS (Platform as a Service) environments, implementing proper multitenancy requires proper security isolation as a vital part of its offering.

Policy binaries

While checking the output of sestatus, we see that there is also a notation of policy versions:

# sestatus | grep version
Max kernel policy version:      28

As the output states, 28 is the highest policy version the kernel supports. The policy version refers to the supported features inside the SELinux policy: every time a new feature is added to SELinux, the version number is increased. The policy file itself (which contains all the SELinux rules loaded at boot time by the system) can be found in /etc/selinux/targeted/policy (where targeted refers to the policy store used, so if the system uses a policy store named strict, then the path would be /etc/selinux/strict/policy).

If multiple policy files exist, we can use the output of seinfo to find out which policy file is used:

# seinfo
Statistics for policy file: /etc/selinux/targeted/policy/policy.27
Policy Version & Type: v.27 (binary, mls)

The next table gives the current list of policy feature enhancements and the Linux kernel version in which that feature is introduced. Many of the features are only of concern to the policy developers, but knowing the evolution of the features gives us a good idea on the evolution of SELinux.


Linux kernel




It is the "Old API" for SELinux, now deprecated



It is the "New API" for SELinux



It provides conditional policy extensions



It provides IPv6 support



It adds fine-grained netlink socket support



It provides enhanced multi-level security



It doesn't access vector table size optimizations”, the version (20) improved the access vector table size (it is a performance optimization).



It provides object classes in range transitions



It provides policy capabilities (features)



It provides per-domain permissive mode



It provides explicit hierarchy (type bounds)



It provides filename based transition support



It provides role transition support for non-process classes



It supports flexible inheritance of user and role for newly created objects



It supports flexible inheritance of type for newly created objects

By default, when a SELinux policy is built, the highest supported version as defined by the Linux kernel and libsepol (the library responsible for building the SELinux policy binary) is used. Administrators can force a version to be lower using the policy-version parameter in /etc/selinux/semanage.conf.

SELinux policy modules

Initially, SELinux used a single, monolithic policy approach: all possible access control rules are maintained in a single, binary policy file that the SELinux utilities then load. It quickly became clear that this is not manageable in long term, and thus the idea of developing a modular policy approach was born.

Within the modular approach, policy developers can write isolated policy sets for a particular application (or set of applications), roles, and so on. These policies then get built and distributed in their own policy modules. Platforms that need access controls for that particular application load the SELinux policy module that defines the access rules.

On some Linux distributions, these SELinux policy modules are stored inside /usr/share/selinux, usually within a subdirectory named after the policy store (such as "targeted" or "strict"). The policy modules that are currently loaded are always available in /etc/selinux/targeted/modules/active and its modules subdirectory.

Of all the *.pp files in these locations, the base.pp one is special. This policy module file contains core policy definitions. The remaining policy module files are "isolated" policy modules, providing the necessary rules for the system to handle applications and roles related to the module itself. For instance, the screen.pp module contains the SELinux policy rules for the GNU screen (and also tmux) application.

Once those files are placed on the system, the distribution package manager usually calls the semodule command to load the policy modules. This command then combines the files into a single policy file (for example, policy.28) and loads it in memory.

On Fedora, the SELinux policies are provided by the selinux-policy-targeted (or -minimum or -mls) package. On Gentoo, they are provided by the various sec-policy/selinux-* packages (Gentoo uses separate packages for each module, reducing the amount of SELinux policies that are loaded on an average system).



In this chapter, we saw that SELinux offers a more fine-grained access control mechanism on top of the Linux access control. SELinux uses labels to identify its resources and processes, based on ownership (user), role, type, and even the security sensitivity and categorization of the resource.

Linux distributions implement SELinux policies which might be a bit different from each other based on supporting features such as sensitivity labels, default behavior for unknown permissions, support for confinement levels, or specific constraints put in place, for example, UBAC. However, most of the policy rules themselves are similar.

Switching between SELinux enforcement modes and understanding the log events that SELinux creates when it prohibits a certain access, is the subject of our next chapter. In it, we will also cover how to approach the often-heard requirement of disabling SELinux and why this is the wrong solution to implement.

About the Author

  • Sven Vermeulen

    Sven Vermeulen is a long-term contributor to various free software projects and the author of various online guides and resources. He got his first taste of free software in 1997 and never looked back. In 2003, he joined the ranks of the Gentoo Linux project as a documentation developer and has since worked in several roles, including Gentoo Foundation trustee, council member, project lead for various documentation initiatives, and (his current role) project lead for Gentoo Hardened SELinux integration and the system integrity project.

    During this time, Sven gained expertise in several technologies, ranging from OS-level knowledge to application servers. He used his interest in security to guide his projects further in the areas of security guides using SCAP languages, mandatory access controls through SELinux, authentication with PAM, (application) firewalling, and more.

    Within SELinux, Sven contributed several policies to the Reference Policy project, and he is an active participant in policy development and user space development projects.

    In his daily job, Sven is an IT architect in a European financial institution as well as a self-employed solution engineer and consultant. The secure implementation of infrastructures (and the surrounding architectural integration) is, of course, an important part of this. Prior to this, he graduated with an MSc in computer engineering from Ghent University and MSc in ICT enterprise architecture from, and he worked as a web application infrastructure engineer.

    Sven is the main author of the Gentoo Handbook, which covers the installation and configuration of Gentoo Linux on several architectures. He also authored the Linux Sea online publication (a basic introduction to Linux for novice system administrators) and SELinux System Administration and SELinux Cookbook for Packt Publishing.

    Browse publications by this author

Latest Reviews

(2 reviews total)
Comprehensive overview of a complex subject.
SELinux System Administration
Unlock this book and the full library for FREE
Start free trial