SELinux: Playing with fire


Author: Preston St. Pierre

One of the much-talked-about features in Fedora Core 3 (FC3) is Security-Enhanced Linux, which some people believe will make Linux a truly military-grade secure operating system. But SELinux is available to secure many other distributions as well.

SELinux started life in early 1990s as Flask, a secure architecture for a secure OS, and prototyped in the Fluke operating system, the result of a joint effort by the U.S. National Security Agency, Secure Computing Corp., and the University of Utah’s Flux research group.

SELinux is being actively developed — so much so that its implementations in FC2 and FC3 are phenomenally different. While FC2 was also SELinux-equipped, FC3 enables it by default. Bill McCarty’s book “SELinux” deals with the FC2 implmentation of SELinux. A lot has changed from FC2 to FC3 but the concepts remain the same.

The SELinux way of life

With the de facto Linux security mechanism called Discretionary Access Control (DAC), the execution of a program depends upon the permissions of the user running it. If a user runs a program it can operate only in his home directory and nowhere else.

SELinux adds another level of security to Linux’s DAC. With Mandatory Access Control (MAC), a program runs within a domain or sandbox with limited permissions, much like chroot. On a SELinux-enabled box, an action must first pass the Linux DAC; if it does, SELinux performs its check based on the MAC before permitting the action.

Every program under SELinux is governed by a policy. A policy, in essence, defines the access parameters for every resource. SELinux needs a policy to determine whether a requested operation is to be allowed or not.

SELinux runs in two modes — permissive and enforcing. The permissive mode allows operations that violate a policy but makes a note in the log (/var/log/messages). This mode helps people test and fine-tune their policies. Once the policies have been tested, adminstrators enable enforcing mode, which prevents operations violating a policy and makes a note of the attempt in the log. This can help SELinux administrators identify break-in attempts.

Policies are what drives (or breaks) SELinux and distinguishes it from the Linux DAC. Policies help SELinux make access decisions by reviewing the security context of the subject and object of the action. Oops, let’s define some terms. A subject is a process (with a process ID), while an object is one of the dozens of security classes that SELinux defines, such as directories, files, filesystems, and links. An action is an operation a subject can perform on the object, such as append, write, read, create, execute, and rename. Security context is established through the security attributes that are associated with the subjects and objects. SELinux uses three security attributes: user identity (the SELinux user account), role (a set of permissions for users), and type (groups of related subjects and objects).

How does this all work in practice? Let’s say you start a program wherein a process wants to read a certain file. The SELinux security server first translates this into subjects, objects, actions, and a security context. Then it looks for a policy and compares the two. Based on the comparison, one of three access vectors is selected and the associated operation performed. The three access vectors are: allow (operation allowed, no need for logging), auditallow (log the operation), and dontaudit (don’t allow and don’t log). A fourth option is the default operation of denying the operation while logging the denial when a policy rule isn’t matched. This action can be overriden by the dontaudit vector to avoid logging the denial operation.

Types of policies

FC3 comes with two sets of policies: a targeted policy, which is enabled by default, and a strict policy. Under the target policy, apart from certain crucial services (such as httpd, named, and dhcpd), everything works as normal in the unconfined_t domain, which trusts the Linux DAC. Everything under this domain that is allowed by the DAC is allowed to execute. If that sounds confusing, read the Fedora Core 3 SELinux FAQ.

The strict policy covers the entire installation. You have little chance of getting away with errors without tweaking the strict policy. Get familiar with SELinux in the targeted policy, then try running the strict policy under the permissive mode, and tweaking the policies on the errors, before attempting to run the strict policy under the enforcing mode.

SELinux policies are configurable and modifiable. While the syntax isn’t easy, you get used to it over time. In FC3 you can find SELinux under /etc/selinux directory. Depending on your install, this directory will either have a targeted/ or a strict/ subdirectory (or both). Under these you’ll find the files and subdirectories that define that policy.

For FC3 you need the selinux-policy-targeted-source and selinux-policy-strict-source packages for modifying the targeted and strict policy sources respectively. Once you have made changes to the policy you need to transform it into a binary form for it to be implemented. The make load command will combine all the policy source files into a policy.conf file (/etc/selinux/targeted/targeted/src/policy) and the checkpolicy will convert it into a binary file (/etc/selinux/targeted/policy). FC3 comes installed with a factory-default binary file.

Modifying policies is a vast topic more suited for a book. There are various files that can be modfied, although you’ll find yourself making changes mostly to the type enforcement and file context files.

The type enforcement (.te) files contain statements related to a particular domain. TE files for the targeted domain in FC3 are under the /etc/selinux/targeted/src/policy/domains/program directory.

Each file has a context associated with it, which defines the user ID, role, and domain. The command ls -Z will list the context of files. The file context (.fc) files under the /etc/selinux/targeted/src/policy/file_contexts/program directory specify the context of every file on the system. Changes to the context of a resource need to be followed by a relabeling of the file system. While the prescribed command for this operation is make relabel, I suggest doing a touch /.autorelabel and rebooting. make relabel has been accused of not restarting the daemons in the correct context sometimes.


Let’s take a look at how this all might work. The statements below, though syntactically correct, are based on a hypothetical policy, to keep things simple.

First log in as a normal user and find your context.

$ id -Z


This means you are a normal user with no powers outside your home directory.

Now relogin as root and find its context:

# id -Z


Now lets add a user.

#useradd -c "Test SELinux user" -m -g users setestuser
#passwd setestuser

To assign it a role, open the file /etc/selinux/<some policy>/src/policy/users for editing and append to the bottom:

user setestuser roles { user_r };

Save and exit.

A make load should load the policy. Now log in as setestuser and find the context, which should be the same as any other user.

Now let’s do something exciting.

Find the context of /proc.

ls -Z / 

drwxr-xr-x  root     root     system_u:object_r:proc_t         proc

This means proc belongs to the proc_t domain. Our normal user doesn’t belong in this domain. To allow him access, begin by creating a new domain file under /etc/selinux/<some policy>/src/policy/domains/misc. Give it any custom name, let’s say test.te, and add the following line in the file:

# Policy Rule ro allow normal users (user_t) access to the proc_t domain
r_dir_file (user_t,proc_t)

The r_dir_file describes that the folder should be read-only, user_t is the type of user for whom the rule is defined, and proc_t is the domain of the folder.

Again load the policy. Now setestuser will be able to list the contents of the proc directory.

Looking ahead

Tresys Technology has bundled several GUI-based tools for managing policies into a single package called setools. Among them: Apol helps you analyze your SELinux policy, SePCuT can help you customize them, and SeAudit can make the audit messages in your logs easy to comprehend. SeUser is a user-manager for SELinux.

Another tool, if used properly, is your best bet for tweaking policies. Audit2allow (/usr/bin/audit2allow), based on the audit messages in the log, writes you appropriate allow rules. But use it wisely — you can make a system less secure by following its every recommendation.

SELinux began life just like any other open source project. But with the quickened pace of its development since last year and with its inclusion in RHEL, it’s beginning to look like SELinux is the future of securing Linux systems.