Enhancing Linux Security with SELinux - Learning Linux Security Techniques - Linux Bible 9th Ed (2015)

Linux Bible 9th Ed (2015)

Part V. Learning Linux Security Techniques

Chapter 24. Enhancing Linux Security with SELinux


1. Learning about SELinux benefits

2. Learning how SELinux works

3. Setting up SELinux

4. Fixing problems with SELinux

5. Getting additional information on SELinux

Security Enhanced Linux (SELinux) was developed by the National Security Agency (NSA) along with other security research organizations, such as Secure Computing Corporation (SCC). SELinux was released to the open source community in 2000 and became popular when Red Hat included SELinux in its Linux distributions. Now, SELinux is used by many organizations and is widely available.

Understanding SELinux Benefits

SELinux is a security enhancement module deployed on top of Linux. It provides additional security measures, is included by default, and is set to be in Enforcing mode in RHEL and Fedora.

SELinux provides improved security on the Linux system via Role Based Access Controls (RBAC) on subjects and objects (aka processes and resources). “Traditional” Linux security uses Discretionary Access Controls (DAC).

SELinux is not a replacement for DAC. Instead, it is an additional security layer.

· DAC rules are still used when using SELinux.

· DAC rules are checked first, and if access is allowed, then SELinux policies are checked.

· If DAC rules deny access, SELinux policies are not reviewed.

If a user tries to execute a file that he does not have execute access to (rw-), the “traditional” Linux DAC controls deny access. Thus, the SELinux policies are not even checked.


SELinux is the default security enhancement of Red Hat distributions, whereas AppArmor is the default security enhancement for Ubuntu. You can still install SELinux on Ubuntu by using the command sudo apt-get install selinux and then reboot. If you want to learn more about AppArmor, go to https://help.ubuntu.com/community/AppArmor.

Even though “traditional” Linux security controls still work, there are several benefits to using SELinux. These are a few of SELinux's benefits:

· It implements the RBAC access control model. This is considered the strongest access control model.

· It uses least privilege access for subjects (for example, users and processes). The term least privilege means that every subject is given a limited set of privileges that are only enough to allow the subject to be functional in its tasks. With least privilege implemented, a user or process is limited on the accidental (or on-purpose) damage to objects they can cause.

· It allows process sandboxing. The term process sandboxing means that each process runs in its own area (sandbox). It cannot access other processes or their files unless special permissions are granted. These areas where processes run are called “domains.”

· It allows a test of its functionality before implementation. SELinux has a Permissive mode, which allows you to see the effect of enforcing SELinux on your system. In Permissive mode, SELinux still logs what it considers security breaches (called AVC denials), but it doesn't prevent them.

Another way to look at SELinux benefits is to examine what can happen if SELinux is not running on your Linux system. For example, your web server daemon (httpd) is listening on a port for something to happen. A simple request from a web browser comes in to view a home page. Going through its normal routine, the httpd daemon hears the request and only “traditional” Linux security is applied. Being unconstrained by SELinux, httpd can do these things:

· Access any file or directory, based on read/write/execute permissions for the associated owner and group.

· Perform potentially insecure activities, such as allowing a file upload or changing system limits.

· Listen on any port it likes for incoming requests.

On a system constrained by SELinux, the httpd daemon is much more tightly controlled. Using the preceding example, httpd can only listen on the port SELinux allows it to listen on. SELinux prevents httpd from accessing any file that doesn't have the proper security context set and denies insecure activities that are not explicitly enabled in SELinux. In essence, SELinux severely limits malicious code and activity on your Linux system.

Understanding How SELinux Works

SELinux could be compared to a guard at a door: In this comparison, the subject (the user) wants to access the object (the file) inside the room. To gain access to this object:

1. The subject must present an ID badge to the guard.

2. The guard reviews the ID badge and access rules kept in a large manual.

· If the access rules allow this particular ID badge inside the door, the subject may enter the room to access the object.

· If the access rules do not allow this particular ID badge access to the object, then the guard refuses entry.

SELinux provides a combination of Role Based Access Control (RBAC) and either Type Enforcement (TE) or Multi-Level Security (MLS). In Role Based Access Control, access to an object is based on a subject's assigned role in the organization. Therefore, it is not based on the subject's username or process ID. Each role is granted access rights.

Understanding type enforcement

Type Enforcement (TE) is necessary to implement the RBAC model. Type Enforcement secures a system through these methods:

· Labeling objects as certain security types

· Assigning subjects to particular domains and roles

· Providing rules allowing certain domains and roles to access certain object types

The example that follows uses the ls -l command to show the DAC controls on the file my_stuff. The file has owner and group listed as well as its assignments for read, write, and execute. If you need a review of file permissions, see Chapter 4, “Moving around the Filesystem.”

$ ls -l my_stuff

-rw-rw-r--. 1 johndoe johndoe 0 Feb 12 06:57 my_stuff

The example that follows includes ls -Z and the same file, my_stuff, but instead of just the DAC controls, the -Z option displays the SELinux security RBAC controls, too.

$ ls -Z my_stuff

-rw-rw-r--. johndoe johndoe

unconfined_u:object_r:user_home_t:s0 my_stuff

The ls -Z example displays four items associated with the file that are specific to SELinux:

· A user (unconfined_u)

· A role (object_r)

· A type (user_home_t)

· A level (s0)

These four RBAC items (user, role, type, and level) are used in the SELinux access control to determine appropriate access levels. Together, the items are called the SELinux security context. A security context (ID badge) is sometimes called a “security label.”

These security context assignments are given to subjects (processes and users). Each security context has a specific name. The name given depends upon what object or subject it has been assigned: Files have a file context, users have a user context, and processes have a process context, also called a “domain.”

The rules allowing access are called “allow rules” or “policy rules.” A policy rule is the process SELinux follows to grant or deny access to a particular system security type. Returning to the comparison of SELinux with the guard, SELinux serves as the guard who must see the subject's security context (ID badge) and review the policy rules (access rules manual) before allowing or denying access to an object. Thus, Type Enforcement ensures that only certain “types” of subjects can access certain “types” of objects.

Understanding multi-level security

With SELinux, the default policy type is called targeted, which primarily controls how network services (such as web servers and file servers) can access on a Linux system. The targeted policy places fewer restrictions on what valid user accounts can do on the system. For a more restricted policy, you can choose Multi-Level Security (MLS). MLS uses Type Enforcement along with the additional feature of security clearances. It also offers Multi-Category Security, which gives classification levels to objects.


The Multi-Level Security (MLS) names can cause confusion. Multi-Category Security (MCS) is sometimes called Multi-Clearance Security. Because MLS offers MCS, it is sometimes called MLS/MCS.

Multi-Level Security enforces the Bell-LaPadula Mandatory Access security model. The Bell-LaPadula model was developed by the U.S. government to impose information confidentiality. Enforcing this model is accomplished by granting object access based on the role's security clearance and the object's classification level.

Security clearance is an attribute granted to roles allowing access to classified objects. Classification level is an attribute granted to an object, providing protection from subjects who have a security clearance attribute that is too low. You most likely have heard the classification level “Top Secret.” The fictional book and movie character James Bond had a top-secret security clearance, which granted him access to top-secret classified information. This is a classic example of the Bell-LaPadula model.

The combination of RBAC along with either Type Enforcement (TE) or Multi-Level Security (MLS) enables SELinux to provide such a strong security enhancement. SELinux also offers different Operational Modes for its use.

Implementing SELinux security models

The Role Based Access Control model, Type Enforcement, Multi-Level Security, and Bell-LaPadula models are all interesting topics. SELinux implements these models through a combination of four primary SELinux pieces:

· Operational Modes

· Security contexts

· Policy types

· Policy rule packages

Although I've touched on some of these design elements, the following gives you an in-depth understanding of them. This understanding is needed before you begin configuring SELinux on your system.

Understanding SELinux operational modes

SELinux comes with three Operational Modes: Disabled, Permissive, and Enforcing. Each of these modes offers different benefits for Linux system security.

Using the Disabled mode

In the Disabled mode, SELinux is turned off. The default method of access control, Discretionary Access Control (DAC), is used instead. This mode is useful for circumstances in which enhanced security is not required.

If at all possible, Red Hat recommends setting SELinux to Permissive mode rather than disabling it. However, sometimes disabling SELinux is appropriate.

If you are running applications that are working properly (from your perspective), but generating massive amounts of SELinux AVC denial messages (even in Permissive mode), you may end up filling up log files to the point of making your systems unusable. The better approach is to set the proper security context on the files you want applications to access. But disabling SELinux is the quicker fix.

Before you disable SELinux, however, think about whether you may ever want to enable it on that system again. If you decide to set it to Enforcing or Permissive later, the next time you reboot your system, your system goes through an automatic SELinux file relabel before it comes up.


If all you care about is turning SELinux off, you have found the answer. Just edit the configuration file /etc/selinux/config and change the text SELINUX= to the following: SELINUX=disabled. SELinux will be disabled after a system reboot. You can now skip the rest of this chapter.

Using the Permissive mode

In Permissive mode, SELinux is turned on, but the security policy rules are not enforced. When a security policy rule should deny admission, access is still allowed. However, a message is sent to a log file denoting that access should have been denied.

SELinux Permissive mode is used for the following:

· Auditing the current SELinux policy rules

· Testing new applications to see what effect SELinux policy rules will have on them

· Testing new SELinux policy rules to see what effect the new rules will have on current services and applications

· Troubleshooting why a particular service or application is no longer working properly under SELinux

In some cases, you can use the audit2allow command to read the SELinux audit logs and generate new SELinux rules to selectively allow the denied actions. This can be a quick way to get your applications working on your Linux system without disabling SELinux.

Using the Enforcing mode

The name says it all. In Enforcing mode, SELinux is turned on and all the security policy rules are enforced.

Understanding SELinux security contexts

As mentioned earlier, an SELinux security context is the method used to classify objects (such as files) and subjects (such as users and programs). The defined security context allows SELinux to enforce policy rules for subjects accessing objects. A security context consists of four attributes: user, role, type, and level.

· user—The user attribute is a mapping of a Linux username to an SELinux name. This is not the same as a user's login name and is referred to specifically as the SELinux user. The SELinux username ends with a u, making it easier to identify in the output. Regular unconfined users have an unconfined_u user attribute in the default targeted policy.

· role—A designated role in the company is mapped to an SELinux role name. The role attribute is then assigned to various subjects and objects. Each role is granted access to other subjects and objects based on the role's security clearance and the object's classification level. More specifically, for SELinux, users are assigned a role and roles are authorized for particular types or domains. Using roles can force accounts, such as root, into a less privileged position. The SELinux role name has an “r” at the end. On a targeted SELinux system, processes run by the root user have a system_r role, while regular users run under the unconfined_r role.

· type—This attribute defines a domain type for processes, a user type for users, and a file type for files. This attribute is also called “security type.” Most policy rules are concerned with the security type of a process and what files, ports, devices, and other elements of the system that process has access to (based on their security types). The SELinux type name ends with a t.

· level—The level is an attribute of Multi-Level Security (MLS) and enforces the Bell-LaPadula model. It is optional in TE, but required if you are using MLS.

The MLS level is a combination of the sensitivity and category values that together form the security level. A level is written as sensitivity : category.

· sensitivity

§ Represents the security or sensitivity level of an object, such as confidential or top secret.

§ Is hierarchical with s0 (unclassified) typically being the lowest.

§ Is listed as a pair of sensitivity levels (lowlevel-highlevel) if the levels differ.

§ Is listed as a single sensitivity level (s0) if there are no low and high levels. Yet in some cases, even if there are no low and high levels, the range is still shown (s0-s0).

· category

§ Represents the category of an object, such as No Clearance, Top Clearance, and so on.

§ Traditionally, the values are between c0 and c255.

§ Is listed as a pair of category levels (lowlevel:highlevel) if the levels differ.

§ Is listed as a single category level (level) if there are no low and high levels.

Users have security contexts

To see your SELinux user context, enter the id command at the shell prompt. The following is an example of the security context for user johndoe:

$ id

uid=1000(johndoe) gid=1000(johndoe) groups=1000(johndoe)


The user's security context list shows the following:

· user—The Linux user, johndoe, is mapped to the SELinux unconfined_u user.

· role—The SELinux user, unconfined_u, is mapped to the role of the unconfined_r.

· type—The user has been given the type of unconfined_t.

· level—

· sensitivity—The user has only one sensitivity level, and it is the lowest level of s0.

· categories—The user has access to c0.c1023, which is all categories (c0 through to c1023).

Files have security contexts

A file also has a security context. To see an individual file's context, use the -Z option on the ls command. The following is a security context for the file my_stuff:

$ ls -Z my_stuff

-rw-rw-r--. johndoe johndoe

unconfined_u:object_r:user_home_t:s0 my_stuff

The file context list shows the following:

· user—The file is mapped to the SELinux unconfined_u user.

· role—The file is mapped to the role of object_r.

· type—The file is considered to be part of the user_home_t domain.

· level—

· sensitivity—The user has only one sensitivity level, and it is the lowest level of s0.

· categories—MCS is not set for this file.

Processes have security contexts

A process's security context has the same four attributes as a user and a file's context. To see process information on a Linux system, you typically use a variant of the ps command. In the following code, the ps -el command was used.

# ps -el | grep bash

0 S 1000 1589 1583 0 80 0 - 1653 n_tty_ pts/0 00:00:00 bash

0 S 1000 5289 1583 0 80 0 - 1653 wait pts/1 00:00:00 bash

4 S 0 5350 5342 0 80 0 - 1684 wait pts/1 00:00:00 bash

To see a process's security context, you need to use the -Z option on the ps command. In the example that follows, the ps -eZ command was used and then piped into grep to search for only processes running the bash shell.

# ps -eZ | grep bash

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 1589 pts/

0 00:00:00 bash

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 5289 pts/

1 00:00:00 bash

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 5350 pts/

1 00:00:00 bash

The process context list shows the following:

· user—Process is mapped to the SELinux unconfined_u user.

· role—Process is running as the unconfined_r role.

· type—Process is running in the unconfined_t domain.

· level—

· sensitivity—Process has only level s0.

· categories—Process has access to c0.c1023, which is all categories (c0 through to c1023).

These security contexts can be changed to meet your organization's particular security needs. However, before you learn how to change the settings of these security contexts, you need to understand another piece of the SELinux puzzle, SELinux policy types.

Understanding SELinux policy types

The policy type chosen directly determines what sets of policy rules are used to dictate what an object can access. The policy type also determines what specific security context attributes are needed. This is where you start to see the fine level of access control that can be implemented via SELinux.


The policy types available on your distribution may not match the ones listed here. For example, on older Linux distributions, the strict policy is still available. On newer distributions, the strict policy has been merged into the Targeted policy, with Targeted used by default.

SELinux has different policies you can choose among:

· Targeted


· Minimum

Each policy implements different access control to match your organization's needs. It is critical to understand these policy types in order to select the correct one for your particular security requirements.

Targeted policy

The Targeted policy's primary purpose is to restrict “targeted” daemons. However, it can also restrict other processes and users. Targeted daemons are sandboxed. A sandbox is an environment where programs can run, but their access to other objects is tightly controlled.

A process running in such an environment is said to be “sandboxed.” Thus, a targeted daemon is restricted so that no malicious attacks launched through it can affect other services or the Linux system as a whole. Targeted daemons make it safer for you to share your print server, file server, web server, or other services, while limiting the risks that access to those services poses to other assets on your system.

All subjects and objects not targeted are run in the unconfined_t domain. The unconfined_t domain has no SELinux policy restrictions and thus only uses the “traditional” Linux security.

SELinux comes with the Targeted policy set as the default. Thus, by default, SELinux targets only a few daemons.

MLS (Multi-Level Security) policy

The MLS policy's primary purpose is to enforce the Bell-LaPadula model. It grants access to other subjects and objects based upon a role's security clearance and the object's classification level.

In the MLS policy, a security context's MLS attribute is critical. Otherwise, the policy rules will not know how to enforce access restrictions.

Minimum policy

This policy is just as it sounds—minimal. It was originally created for low-memory machines or devices such as smart phones.

The Minimum policy is essentially the same as the Targeted policy, but only the base policy rule package is used. This “bare bones” policy can be used to test out the effects of SELinux on a single designated daemon. For low-memory devices, the Minimum policy allows SELinux to run without consuming a great deal of resources.

Understanding SELinux policy rule packages

Policy rules, also called allow rules, are the rules used by SELinux to determine if a subject has access to an object. Policy rules are installed with SELinux and are grouped into packages, also called modules. Each particular policy package file ends with a *.pp.

The /etc/selinux/policy_type/modules/active/modules directory contains a number of policy package (*.pp) files. The example that follows shows the policy rule packages for a Linux system with the Targeted policy implemented:

# ls /etc/selinux/targeted/modules/active/modules/*.pp












On your Linux system, there is user documentation on these various policy modules, in the form of HTML files. To view this documentation on Fedora or RHEL, open your system's browser and type in the following URL: file:///usr/share/doc/selinux-policy-selinuxversion#/html/index.html. For Ubuntu, the URL is file:///usr/share/doc/selinux-policy-doc/html/index.html. If you do not have the policy documentation on your system, you can install it on a Fedora or RHEL system, by typing yum install selinux-policy-doc at the command line. On Ubuntu, type sudo apt-get install selinux-policy-doc at the command line.

You can review this policy documentation to see how policy rules are created and packaged.

The policy rule packages, along with the SELinux operation mode, policy type, and various security contexts, work together to secure your Linux system via SELinux. The following section covers how to begin configuring SELinux to meet your particular organization's security needs.

Configuring SELinux

SELinux comes preconfigured. You can use the SELinux features without any configuration work. However, rarely do the preconfigured settings meet all your Linux system's security needs.

SELinux configurations can only be set and modified by the root user. Configuration and policy files are located in the /etc/selinux directory. The primary configuration file is the /etc/selinux/config file and it appears as follows:

# cat /etc/selinux/config

# 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 - SELinux is fully disabled.


# SELINUXTYPE= type of policy in use. Possible values are:

# targeted - Only targeted network daemons are protected.

# strict - Full SELinux protection.


This main SELinux configuration file allows you to set the mode and the policy type.

Setting the SELinux mode

To see SELinux's current mode on your system, use the getenforce command. To see both the current mode and the mode set in the configuration file, use the sestatus command. Both commands are shown in the code that follows:

# getenforce


# 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

Max kernel policy version: 28

To change the mode setting, you can use the setenforce newsetting, where newsetting is either:

· enforcing or 1

· permissive or 0

Notice that you cannot use the setenforce command to change SELinux to disabled mode.

The example that follows shows the SELinux mode being changed immediately to permissive mode via the setenforce command. The sestatus command shows the current Operational Mode and the mode in the configuration file, which has not been modified. When the system is rebooted, it determines the SELinux Operational Mode from the configuration file. Thus, the permissive mode set in the example that follows is temporary because the enforcing mode is set via the configuration file when the system is rebooted.

# setenforce 0

# getenforce


# sestatus

SELinux status: enabled

SELinuxfs mount: /sys/fs/selinux

Loaded policy name: targeted

Current mode: permissive

Mode from config file: enforcing



It is best to switch from the disabled to the enforcing mode by modifying the configuration file and rebooting. Switching from disabled to enforcing via the setenforce command may hang your system as a result of incorrect file labels. Keep in mind that, when rebooting after changing from disabled mode, there could be a long wait for your filesystem to be relabeled after the system comes back up in permissive or enforcing mode.

To disable SELinux, you must edit the SELinux configuration file. Rebooting the system always changes the mode back to what is set in that configuration file. The preferred method of changing the SELinux mode is to modify the configuration file and then reboot the system.

When switching from disabled to either enforcing or permissive mode, SELinux automatically relabels the filesystem after a reboot. This means SELinux checks and changes the security contexts of any files with incorrect security contexts (for example, mislabeled files) that can cause problems in the new mode. Also, any files not labeled are labeled with contexts. This relabeling process can take a long time because each file's context is checked. The following is the message you receive when a system is going through a relabeling process after a reboot:

*** Warning -- SELinux targeted policy relabel is required.

*** Relabeling could take a very long time, depending on file

*** system size and speed of hard drives.

To modify the mode in the /etc/selinux/config file, change the line SELINUX= to one of the following:

· disabled

· enforcing

· permissive

The SELinux configuration file example that follows shows that the mode has been set to permissive. Now, when a system reboot occurs, the mode is changed.

# cat /etc/selinux/config

# 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 - SELinux is fully disabled.



The primary SELinux configuration file does not just contain the mode setting. It also specifies the policy type, which will be enforced.

Setting the SELinux policy type

The policy type you choose determines whether SELinux enforces TE, MLS, or a base package. This type setting directly determines the sets of policy rules used to dictate what an object can access.

By default, the policy type is set to targeted. To change the default policy type, edit the /etc/selinux/config file. Change the line SELINUXTYPE= to one of the following:

· targeted

· mls

· minimum

If you set the SELinux type to mls or minimum, you need to make sure you have their policy package installed first. Check by typing the following command: yum list selinux-policy-mls or yum list selinux-policy-minimum.


To check the SELinux policy packages on Ubuntu, use the command sudo apt-cache policy package_name.

The example of the SELinux configuration file that follows shows that the type has been set to mls. Now, when a system reboot occurs, the policy type is changed.

# cat /etc/selinux/config

# This file controls the state of SELinux on the system.


# SELINUXTYPE= type of policy in use. Possible values are:

# targeted - Only targeted network daemons are protected.

# strict - Full SELinux protection.



Do not be fooled by the out-of-date comments in the SELinux configuration file. You cannot set SELINUXTYPE to strict in newer Linux distributions. If you do, the system hangs on the next reboot and you must use grub commands to fix the problem. Thestrict policy type is now a part of the targeted policy type.

Managing SELinux security contexts

SELinux security contexts allow SELinux to enforce policy rules for subjects accessing objects. Your Linux system comes with security contexts already assigned.

To view current SELinux file and process security contexts, use the secon command. Table 24.1 lists options available on the secon command.

Table 24.1 secon Command Options




Use this option to show the user of the security context.


Use this option to show the role of the security context.


Use this option to show the type of the security context.


Use this option to show the sensitivity level of the security context.


Use this option to show the clearance level of the security context.


Use this option to show the sensitivity and clearance level of the security context as an MLS range.

If you use the secon command with no designation, it shows you the current process's security context. To see another process's security context, use the -p option. The example that follows shows you how to use secon to view the current and the systemd process's security context.

# secon -urt

user: unconfined_u

role: unconfined_r

type: unconfined_t

# secon -urt -p 1

user: system_u

role: system_r

type: init_t

To view a file's security context, you use the -f option, as shown here:

# secon -urt -f /etc/passwd

user: system_u

role: object_r

type: etc_t

A user's security context is not viewed using the secon command. To see a user's security context, the id command must be used. To see a user's security context besides your own, the command syntax is id -Z username.

Managing the user security context

Remember that every system user login ID is mapped to a particular SELinux user ID. To see a mapping list on your system, enter the semanage login -l command. The semanage command and its output are shown in the code that follows. If a user login ID is not listed, then it uses the “default” login mapping, which is the Login Name of _default_. Notice that the associated MLS/MCS settings for each SELinux user are shown as well.

# semanage login -l

Login Name SELinux User MLS/MCS Range Service

__default__ unconfined_u s0-s0:c0.c1023 *

root unconfined_u s0-s0:c0.c1023 *

system_u system_u s0-s0:c0.c1023 *

To see a current display of the SELinux users and their associated roles, use the command semanage user -l. The partial display that follows shows roles mapped to SELinux usernames:

# semanage user -l

Labeling MLS/ MLS/

SELinux User Prefix MCS Level MCS Range SELinux Roles

guest_u user s0 s0 guest_r


user_u user s0 s0 user_r

xguest_u user s0 s0 xguest_r

If you need to add a new SELinux username, the semanage utility is used again. This time, the command is semanage user -a selinux_username. To map a login ID to the newly added SELinux username, the command is semanage login -a -s selinux_username loginID. Thesemanage utility is a powerful tool in managing your SELinux configuration. For more information on the semanage utility, see the man pages.

Managing the file security context

Labeling files is critical to maintaining proper access control to each file's data. SELinux does set file security labels upon installation and upon system reboot when the SELinux mode is switched from disabled. To see a file's current label (aka security context), use the ls -Z command, as shown here:

# ls -Z /etc/passwd

-rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/passwd

You can use several commands to manage file security context labels, as shown in Table 24.2.

Table 24.2 File Security Context Label Management Commands




Use this to change a file's security context label's category.


Use this to change a file's security context label.


This calls the restorecon/setfiles utility.


This does the exact same thing as setfiles utility, but it has a different interface than setfiles.


Use this to verify and/or correct security context labels. It can be run for file label verification and/or relabeling files when adding a new policy module to the system. Does exactly the same thing as the restorecon utility, but has a different interface thanrestorecon.

The chcat and chcon commands, shown in Table 24.2, allow you to change a file's security context. In the example below, the chcon command is used to change the SELinux user associated with file.txt from undefined_u to system_u.

# ls -Z file.txt

-rw-rw-r--. johndoe johndoe

unconfined_u:object_r:user_home_t:s0 file.txt

# chcon -u system_u file.txt

# ls -Z file.txt

-rw-rw-r--. johndoe johndoe

system_u:object_r:user_home_t:s0 file.txt

Notice in Table 24.2 that fixfiles, restorecon, and setfiles are essentially the same utility. However, restorecon is the popular choice to use when fixing files' labels. The command restorecon -R filename changes a file back to its default security context.

Managing the process security context

The definition of a process is a running program. When you run programs or start services on a Linux system, each one is given a process ID (see Chapter 6). On a system with SELinux, a process is also given a security context.

How a process gets its security context depends upon which process started it. Remember that systemd (previously init) is the “mother” of all processes (see Chapter 15). Thus, many daemons and processes are started by systemd. The processes systemd starts are given new security contexts. For instance, when the apache daemon is started by systemd, it is assigned the type (aka domain) httpd_t. The context assigned is handled by the SELinux policy written specifically for that daemon. If no policy exists for a process, then it is assigned a default type, unconfined_t.

For a program or application run by a user (parent process), the new process (child process) inherits the user's security context. Of course, this occurs only if the user is allowed to run the program. A process can also run a program. The child process in this case also inherits its parent process's security context. Thus, the child process runs in the same domain.

So a process's security context is set before the program is run and depends upon who started it. You can use a couple of commands to change the security contexts under which a program is run:

· runcon—Run the program using options to determine the user, role, and type (aka domain).

· sandbox—Run the program within a tightly controlled domain (aka sandbox).

You can cause several problems by using runcon, so use it with caution. However, sandbox offers a great deal of protection. It allows flexibility in testing out new programs on your Linux system.

Managing SELinux policy rule packages

Policy rules are the rules used by SELinux to determine whether a subject has access to an object. They are grouped into packages, also called modules, and are installed with SELinux. An easy way to view the modules on your system is to use the semodule -lcommand. It lists all the policy modules along with their current version number. An example of the semodule -l command is shown here:

# semodule -l

abrt 1.2.0

accountsd 1.0.6

acct 1.5.1


xserver 3.8.4

zabbix 1.5.3

zarafa 1.1.0

zebra 1.12.0

zoneminder 1.1.1

zosremote 1.1.1

Several tools can help you to manage and even create your own policy modules. Table 24.3 shows the various Policy rule package tools available on a Fedora system.

Table 24.3 SELinux Policy Package Tools

Policy Tool



Generates policy allow/dontaudit rules from logs of denied operations


Generates a description of why the access was denied from logs of denied operations


Compiles policy modules


Compiles SELinux policies


Loads new policies into the kernel


Manages policy modules


Lists dependencies between policy packages


Expands a policy module package


Links policy module packages together


Creates a policy module package

The following is an example policy typically used as a framework to create local policy rules. The example policy is rather long, so only a portion of it is shown.

# cat /usr/share/selinux/devel/example.te




# Declarations


type myapp_t;

type myapp_exec_t;


domain_entry_file(myapp_t, myapp_exec_t)

type myapp_log_t;


type myapp_tmp_t;



allow myapp_t myapp_tmp_t:file manage_file_perms;


The preceding example code shows that a special syntax is used in policy code. To create and modify policy rules, you need to learn this policy rule language syntax, learn how to use the SELinux policy compilers, and learn how to link policy rule files together to form modules; you probably need to take a couple of day-long classes. You may be tempted to give up on SELinux at this point. However, it is much easier to use Booleans to modify policies.

Managing SELinux via booleans

SELinux policy rule writing and module creation is a rather complicated and time-consuming activity. Creating incorrect policy rules could potentially compromise your Linux system's security. Thankfully, SELinux provides Booleans.

A Boolean is a toggle switch that toggles a setting on or off. A Boolean switch allows you to change parts of SELinux policy rules, without any knowledge of policy writing. These policy changes can be done without a system reboot, too!

To see a list of all the current Booleans used in SELinux, use the getsebool -a command. The following is an example of the SELinux policy rules with Booleans on a Fedora Linux system:

# getsebool -a

abrt_anon_write --> off

abrt_handle_event --> off


xserver_object_manager --> off

zabbix_can_network --> off

To see a specific policy that can be modified by a Boolean, the getsebool command is used again. This time, the policy name is passed to it, as shown in the following example:

# getsebool httpd_can_connect_ftp

httpd_can_connect_ftp --> off

To toggle a policy, you can use either the setsebool command or the togglebool command. Both of these commands change the policy rule temporarily. When the system is rebooted, the Boolean returns to its original setting. If you need this setting to be permanent, you can use only the setsebool with the -P option.

The togglebool command just toggles the current Boolean setting of the policy you specify between on and off. For instance, if you issued the command togglebool httpd_can_connect_ftp, you would change the policy setting status from its previous setting of “off” to “on.”

The setsebool command has six settings: three for turning a policy on (on, 1, or true), and three for turning a policy off (off, 0, or false).

For an example using setsebool, in some situations, it is not good security to allow users to execute programs from their /home directory. To prevent this from happening, the allow_user_exec_content policy rule needs to be turned off. The example that follows shows thesetsebool command being used to do just that. Notice that the -P option is used to make this setting permanent.

# setsebool -P allow_user_exec_content off

The getsebool command verifies that the Boolean setting has been correctly made:

# getsebool allow_user_exec_content

allow_user_exec_content --> off

Booleans make modifying current SELinux policy rules much easier. Overall, the SELinux command line configuration utilities, such as getsebool, are easy to use. However, if you want a GUI configuration tool, SELinux has one. It is installed via the command yum install policycoreutils-gui. On Ubuntu, use the command sudo apt-get install policycoreutils. To use this configuration tool, simply type in the command system-config-selinux and a GUI interface appears.

Monitoring and Troubleshooting SELinux

SELinux is another tool for monitoring your system. It logs all access denials, which can help you determine whether an attack is being attempted. These same SELinux log files are also useful in troubleshooting SELinux problems.

Understanding SELinux logging

SELinux uses a cache called the Access Vector Cache (AVC) when reviewing policy rules for particular security contexts. When access is denied, called an AVC denial, a denial message is put into a log file.

These logged denial messages can help you diagnose and address routine SELinux policy violations. Where these denial messages are logged depends upon the status of the auditd and rsyslogd daemons:

· If the auditd daemon is running, the denial messages are logged to /var/log/audit/audit.log.

· If auditd is not running, but the rsyslogd daemon is running, the denial messages are logged to /var/log/messages.


If both auditd and rsyslogd are running, and you have the setroubleshootd daemon on your system, denial messages are sent to both the audit.log and messages log files. However, denial information in the messages log file is put into a more understandable format by the setroubleshootd daemon.

Reviewing SELinux messages in the audit log

If you have the auditd daemon running, you can quickly see if any AVC denials have been logged by using the aureport command. The example that follows shows the use of aureport and grep to search for AVC denials. At least one denial has been logged to/var/log/audit/audit.log:

# aureport | grep AVC

Number of AVC's: 1

After you discover that an AVC denial has been logged in audit.log, you can use ausearch to review the denial message(s). The example that follows shows the ausearch command being used to review the logged AVC denial message.

# ausearch -m avc

type=AVC msg=audit(1411184014.986:69860): avc: denied { create } for

pid=21875 comm="vsftpd" name="services"


tcontext=system_u:object_r:user_home_t:s0 tclass=file

The display provides information on who was attempting access, along with his security context when attempting it. Look for these key words in an AVC denial message:

· type=AVC

· avc: denied

· pid=

· exe=

· subj=

This can give you enough data to either begin fixing a problem or track down malicious activity.

Reviewing SELinux messages in the messages log

If you have the rsyslogd running, you can find AVC denial messages by searching through the /var/log/messages file using grep. For RHEL 7, Fedora 21, or any Linux using systemd, you can run the journalctl command to check for AVC denial log messages. In each log message is an sealert command line that you can run to get information about each AVC denial. For example:

# journalctl | grep sealert

Sep 18 23:58:03 fedora20.example.com setroubleshoot[13449]:

SELinux is preventing /usr/sbin/vsftpd from getattr access on the

directory /home/chris/Music. For complete SELinux messages.

run sealert -l 8f52dd56-8025-4208-af41-7d296bdaa46b

From the example, you can see that a Linux user attempted to log into an FTP service (vsftpd) as a particular user. Because FTP uses clear text passwords, that action is considered insecure and is, therefore, denied by SELinux. Notice that the AVC denial message tells you that you can run the sealert -l command to get more information.

The sealert utility allows you to get more information on a particular AVC denial message. The information format sealert provides can help you diagnose your problems. The example that follows shows the information sealert provides concerning the AVC denial, which was shown in the previous example. Notice the command used is exactly the same command suggested from the preceding message log file. The long number used in the sealert command is the AVC denial message's ID number.

# sealert -l 8f52dd56-8025-4208-af41-7d296bdaa46b

SELinux is preventing /usr/sbin/vsftpd from getattr access

on the directory /home/chris/Music.

***** Plugin catchall_boolean (47.5 confidence) suggests ********


If you want to determine whether ftpd can read and write files in

user home directories.

Then you must tell SELinux about this by enabling the 'ftp_home_dir'


You can read 'None' man page for more details.

Do setsebool -P ftp_home_dir 1

***** Plugin catchall_boolean (47.5 confidence) suggests ********


If you want to determine whether ftpd can login to local users and

can read and write all files on the system, governed by DAC.

Then you must tell SELinux about this by enabling the

'ftpd_full_access' boolean.

You can read 'ftpd_selinux' man page for more details.

Do setsebool -P ftpd_full_access 1


The sealert output provides a great deal of helpful information. In this case, it gives the proper diagnosis that if you want to allow a user to log into an existing user account from an FTP service, you must turn on the ftp_home_dir boolean (setsebool -P ftp_home_dir=on). If you have SELinux enforced on your system, it would be wise to have the setroubleshootd daemon running as well.

Troubleshooting SELinux logging

Obviously, the log files are extremely important for diagnosing and addressing SELinux policy violations. The log files or directly querying the systemd journal (journalctl command) are your first steps in troubleshooting SELinux. Thus, it is important to make sure your Linux system is logging messages in the first place.

A quick way to determine if the logging is taking place is to check if the proper daemons are running: auditd, rsyslogd, and/or setroubleshootd. Use an appropriate command, such as systemctl status auditd.service. Of course, the command you use depends on your Linux distribution and its version. See Chapter 15 for more details. If the daemon is not running, start it so that logging may begin to occur.


Sometimes AVC denials are not logged because of dontaudit policy rules. Although the dontaudit rules help reduce false positives in the logs, they can cause you problems when you're troubleshooting. To fix this, temporarily disable all dontaudit policy rules using the command semodule -DB.

Troubleshooting common SELinux problems

When you begin working with SELinux, it is easy to overlook the obvious. Whenever access is denied, you should first check the “traditional” Linux DAC permissions. For example, use the ls -l command and double-check that a file's owner, group, and read, write, and execute assignments are correct.

With SELinux, several regular items can cause problems:

· Using a nonstandard directory for a service

· Using a nonstandard port for a service

· Moving files that result in losing their security context labels

· Having Booleans set incorrectly

Each one of these problems can be solved fairly quickly.

Using a nonstandard directory for a service

For various reasons, you may decide to store a service's files in a nonstandard directory. When you do this, SELinux needs to know that this nonstandard behavior has occurred. Otherwise, it denies access to legitimate service access requests.

For example, you decided to keep your HTML files in a different location from the standard /var/www/html. You put the files in /abc/www/html. You must let SELinux know you want the http service to be able to access the files within /abc/www/html. The commands to accomplish this are semanage and restorecon. In the following, the commands are used to add the proper security context type on the /abc/www/html directory and all it contains:

# semanage fcontext -a -t httpd_sys_content_t "/abc/www/html(/.*)?"

To actually set the new security context type to the files within the directory, you need to use the restorecon -R command. This is accomplished in the following:

# restorecon -R -v /srv/www/html

Now the httpd daemon has permission to access your HTML files in their nonstandard directory location.

Using a nonstandard port for a service

Similar to the problem just described, you may decide to have a service listening on a nonstandard port. When you make this port change, the service often fails to start.

For example, you decide for security purposes to move sshd from port 22 to a nonstandard port, 47347. SELinux does not know about this port, and the service fails to start. To fix this problem, you must first find the security context type for sshd. This is accomplished using the code that follows by issuing the semanage port -l command and piping the results into grep to search for ssh.

# semanage port -l | grep ssh

ssh_port_t tcp 22

In the preceding example, the context type needed is ssh_port_t. Now, using the semanage command again, add that type to port 47347, as shown here:

# semanage port -a -t ssh_port_t -p tcp 47347

Next, edit the /etc/ssh/sshd_config file to add a Port 47347 line to the file. Then restart the sshd service so the service listens on the nonstandard port 47347.

Moving files and losing security context labels

You used the cp command to move a file from /etc temporarily to the /tmp directory. Then you used the mv command to put it back. Now, the file has the security context of the temporary directory instead of its original security context, and your system is getting AVC denial messages when the service using that file tries to start up.

This is an easy fix, thanks to the restorecon -R command. Simply type restorecon -R file, and the file has its original security context restored.

Booleans set incorrectly

Another common problem is setting a Boolean incorrectly. This can give you several AVC denials.

For example, if your system's scripts are no longer able to connect to the network and you are getting AVC denials in your logs, you need to check the httpd Booleans. Use the getsebool -a command, and pipe it into grep to search for any Booleans that affect httpd. The example here shows these commands being used:

# getsebool -a | grep http


httpd_can_network_connect --> off


The getsebool command shows the Boolean httpd_can_network_connect is set to off. To change this Boolean, use the following command: setsebool -P httpd_can_network_connect on. Notice the -P option was used to make the setting permanent. Now, your scripts should be able to connect out to the network.

As you encounter various problems with SELinux, your troubleshooting skills will improve. Meanwhile, here is another excellent resource to help you with troubleshooting: http://docs.redhat.com. The Red Hat document “Red Hat Enterprise Linux” has an entire chapter (Chapter 8) dedicated to troubleshooting SELinux.

Putting It All Together

Obviously, SELinux is a rather complicated and rich tool. You now have a good, solid foundation on the SELinux basics. Here are some recommendations as you get started implementing SELinux on your system.

You can use the default targeted SELinux mode to secure most basic network services (httpd, vsftpd, Samba, and so on) without needing to assign special user roles or otherwise lock down your system. In this case, the main things you need to do are put files in standard locations (or run commands to assign the proper file contexts to nonstandard locations), make sure Booleans are turned on for less secure features you want on anyway, and watch AVC denials for problems.

· Start with the permissive operational mode. This allows requests that SELinux sees as insecure to succeed.

· Run your current system for a significant amount of time in Permissive mode. Review the logs and see what problems may occur with the default SELinux settings. You can then change Booleans or file contexts so features improperly denied can be allowed. After the problems are worked out, turn on enforcing mode.

· Overall, implement SELinux configuration changes one at a time, in a test environment or using Permissive mode. See what kind of effect each configuration change has before moving on to the next one. You can then use the audit2allow command to selectively allow actions that cause AVC denials to be added to the policy of what is allowed for a service.

Obtaining More Information on SELinux

Several additional sources of information can help you with SELinux on your Linux system:

· Your system's man pages—Issue the command man -k selinux to find all the various man pages you can review for the SELinux utilities currently installed on your system. If you are debugging SELinux problems for a well-known service (such as httpd, vsftpd, Samba, and so on), there is probably a man page associated with how to specifically fix SELinux problems with that service.

· The Red Hat Enterprise Linux manuals—Located at http://docs.redhat.com, this site contains an entire manual on SELinux.

· The Fedora Project SELinux Guide—Located at http://docs.fedoraproject.org, this site has a Security-Enhanced Linux Guide. However, the guide is not updated for every Fedora version, so you may need to look in older versions to find it. Also, the SELinux Guide is not located within the Security manual, but the Security manual is a good manual to review as well.

· SELinux on Ubuntu—Because there are subtle differences between SELinux on RHEL/Fedora and Ubuntu, the site https://wiki.ubuntu.com/SELinux provides you with the additional help you need.

· SELinux Project Wiki—This is the official SELinux project page. Several resources are available at this site, which is located at http://selinuxproject.org.

· SELinux News—Just as it sounds, there is current news on SELinux at http://selinuxnews.org.


SELinux provides a security enhancement to Linux and is installed by default on many Linux distributions. In this chapter, you learned the benefits of SELinux, how it works, how to set it up, how to fix various problems with SELinux, and how to get more information about this important security enhancement.

SELinux at first glance appears rather complicated. However, after it's broken down into its various components—Operational Modes, Security contexts, Policy types, and policy packages—you can see how the various pieces work together. Each component has an important role for enforcing and testing the chosen security requirements for your organization.

You learned the various steps to configure SELinux. Even though SELinux comes preconfigured, you may need to make some modifications to meet your organization's security needs. Each component has its own configuration steps and settings to choose. Though policy rule creation was not covered, you did learn how to modify the supplied policies via Booleans.

SELinux provides another tool for monitoring your Linux system's security. Because SELinux logs all access denials, it can help you determine if an attack has been or is being attempted. Even the best made plans can go badly. Therefore, in this chapter, you learned how to fix common SELinux configuration problems.

In the next chapter, you'll learn how to protect your Linux system on a network. You'll learn about controlling access, managing firewalls, and securing remote access.


Use these exercises to test your knowledge of using SELinux. These tasks assume you are running a Fedora or Red Hat Enterprise Linux system (although some tasks work on other Linux systems as well). If you are stuck, solutions to the tasks are shown in Appendix B (although in Linux, there are often multiple ways to complete a task).

1. Making no changes to the SELinux primary configuration file, write down the command to set your system into the Permissive Operating Mode for SELinux.

2. Making no changes to the SELinux primary configuration file, write down the command to set your system into the Enforcing mode for SELinux.

3. What current and permanent SELinux policy types are set on your system, and how did you find them?

4. List the security context for the /etc/hosts file, and identify its different security context attributes.

5. Create a file called test.html in your home directory, and assign its type to httpd_sys_content_t. (This is something you might do to make content available to be shared by your web server outside the common /var/www/html directory.)

6. List the security context for the running crond process, and identify its security context attributes.

7. Create a file called /etc/test.txt, change its file context to user_tmp_t, restore it to its proper content (the default context for the /etc directory), and remove the file. Use the ls -Z /etc/test.txt command to check the file at each point in the process.

8. You have an FTP server on your private network, and you want to allow users to log into that server with their regular user accounts (while SELinux is in enforcing mode). Determine what Boolean allows users to access their home directories via FTP, and turn that Boolean on.

9. What command would list out all the SELinux policy modules on your system, along with their version number?

10.Prepare your system to run a vsftpd FTP server that is protected by SELinux (I did this on a Fedora system). Then log in as a regular, and try to copy a file (which should cause an AVC denial) as follows:

11. # getenforce

12. Enforcing

13. # yum install vsftpd lftp rsyslog setroubleshoot-server

14. # systemctl start syslog

15. # systemctl start vsftpd

16. # semodule -DB

17. # getsebool ftp_home_dir

18. ftp_home_dir --> off

19. # lftp -u chris localhost

20. Password: ********

21. lftp chris@localhost:~> put /etc/services

22. put: Access failed: 553 Could not create file. (services)

lftp chris@localhost:~> quit

Your assignment is to list the AVC denial from your system's log messages. View information about the denial, and change the Boolean to allow FTP access, as the AVC denial's description suggests.