SE Linux for Even Mere-er Mortals

By Lukas Vacula

During my Authentication and Security Models class, I (along with the rest of the class) was assigned to secure the DVWA using only SE Linux. However, neither I nor my four group mates could find a guide or resource that was easy enough to understand in order to complete the assignment. This guide is my attempt to fix that for myself by condensing the hardest parts of SELinux down to the parts needed for a basic understanding. By the end, the reader should be able to:

  • Understand what SELinux is•
  • Understand some of the underlying theory and terms of SELinux
  • Configure their SELinux installation
  • Write a basic SELinux policy

This guide will not cover:

  • Multi-level or multi-category security
  • Application-specific configuration

In other words, this guide is meant for people who are just starting to learn about SELinux.


SE Linux was created and originally developed by the National Security Agency. After some performance problems when made as an addon to the kernel, it was integrated into the Linux mainline kernel source code in version 2.6. Recent additions and developments are led by the Red Hat project, but the source code is available on Github for all to see. SE Linux is currently installed and enabled by default on Red Hat and CentOS, but is available for a wide variety of distrobutions.

An important note is that while Linus Torvalds, benevolent dictator of the Linux kernel, wanted to include SELinux, he wanted it to be a modular addition instead of baked directly into the kernel. This led to the creation of the Linux Security Module framework. Since the creation os LSM, three other modules have been accepted into the main kernel besides SELinux: Simple Mandatory Access Control Kernel (Smack), AppArmor, and TOMOYO Linux. SELinux remains the most popular use case by far, but AppArmor has been gaining popularity for its simplicity.

Subjects, Access, and Objects

Similar to sentence grammar, SE Linux uses subjects and objects to describe security policies. Subjects make up users, processes, applications, and daemons, while objects make up files and file-like things (though, everything in Linux is a file). Subjects must be given permission to conduct actions, called access, on objects.


Now that the background of SELinux has been covered, I need to shift from the “what” to the “why”. Why is SELinux used? The answer is in the difference between the typical permission system of Linux versus the kind implemented by SELinux.

Anyone who has used Linux (and some who have used *nix OSes in general) will be familiar with the standard permissions on files: user, group, and other. This is commonly referred to as “discretionary access control”. However, real discretionary access control is defined (loosely) as a subject being able to change the attributes or permissions of a file in a way that allows others to access the file as well.

SELinux adds mandatory access control. MAC will define the level of access for all subject, and prevent any subject from giving permission (directly or indirectly) to any other subject. In other words, you may own a file, but that doesn’t mean you have total control over it. This applies both at the user level and the process level.

There is a third type of access control commonly referred to as “role-based access control”. This type of security model is centered more around groups, or Roles, for controlling access. SELinux allows for RBAC on top of standard MAC.

What does all this mean? To quote the official website of the SELinux project:

With SELinux an administrator can differentiate a user from the applications a user runs. For example, the user shell or GUI may have access to do anything he wants with his home directory but if he runs a mail client the client may not be able to access different parts of the home directory, such as his ssh keys.

This allows for extremely granular level of permission controls.

Users, Types, Etc

SELinux has its own sub-set of users in addition to the normal set of Linux users. However, SEL users are not usually mapped 1:1 to standard users. Instead, they are usually their own kind of grouping of users (such as normal users or staff). Often, these users are denoted with a format such as user_u, staff_u, or system_u. The system_u user is included by default in SELinux, and is reserved for system-specific processes.

Likewise, roles follow a *_r format, types follow a *_t format. Roles are more-or-less groupings of SEL users, and types are where the actual restrictions or permissions are applied. On processes, it defined which ones an SEL user has to. On objects, it defines what the SEL user can do to the object. Users, roles, and types can all be considered “domains”.

SEL users, roles, and types come together to form a “security context”, or label. Every process and object must have a security context taking the form of user:role:type. There is an optional “range” label, but that is outside of the scope of this post.

Users can be mapped to SEL users and roles using semanage login -a -s “user_u” -r “role_r” user_name.


Generally speaking, working with labels will involve the “-Z” flag in a command. For example, the “ls -Z” command will display the SEL content for files the same way a standard “ls -l” would. “chcon” can be used to temporarily change a file’s context. “restorecon” will return it to the default. semanage fcontext can be used for permanent changes.


Policies themselves cover four rules applied to labels. Almost all rules take the format rule_name source_t target_t:class permissions.

“rule_name” must be one of the four rule types: allow, dontaudit, allowaudit, and neverallow. “allow” is the most common, and simply allows the source to do the permission action to the target. “dontaudit” is designed for expected denials of no consequence. “auditallow” forces an audit. It does not implicitly apply an allow. “neverallow” will explicitly override any “allow” rules.

“Source_t” should be replaced by the type label of the subject, and “target_t” should be replaced with the object’s type label. “class” is a special case to explain to SELinux what the object is. There are far to many classes to list here, but to give a few to show the breadth and depth: files, links, directories, network interfaces, databases, and even X window system fonts all have their own classes. Permissions vary with class, and can be defined either individually or as a group using curly braces.

As an example of a complete rule: allow staff_t http_t:file {read write}; This will allow all users/processes of type “staff_t” to read/write/append to files of type “http_t”.

A few more notes


Unconfined (_u,_r, and _t) domains are almost as if SEL should avoid interfereing with a particular subject or object.


By starting the auditd daemon, SELinux will begin logging denials, usually to /var/log/audit.log or /var/log/audit/audit.log


Audit2allow is the “easy” solution to generating SEL policies. Simply run the system normally in permissive or enforcing mode to generate a list of denial messages, then run audit2allow -a to generate a list of policy rules to allow all denied access. Keep in mind that this could potentially add more permissions than you wish to grant. Always review the rules before implementing them.


Booleans are ways to change parts of an SEL policy without restarting the system or recompiling the system. Using these is done with just two commands: getsebool and setsebool. They’re simple enough to need little explanation outside of the man pages.

Some notes on SELinux, AppArmor, and the value of each

As stated earlier, AppArmor is an alternative MAC implementation for Linux. AppArmor is, by all means, far easier to implement than SELinux. All controls can be done through configuration files rather than filesystem labels, and allowance or denial can be done with file paths or preset names.

Arguably, SELinux is the “more secure” option because of the level of granular control that can be implemented. But those quotes are incredibly important. SEL may have more granular control, but it comes with a massive skill curve. This page barely scratches the surface of all the complexities of the module. AppArmor, on the other hand, has a better chance of being implemented correctly. A steel door is stronger than a wooden one, but only if it is installed properly.

If your chosen distrobution of Linux uses a specific module for MAC, I highly recommend you use that one. It will probably come with some ready-made configurations for common programs (such as apache configs on CentOS). However, if you aren’t familiar with either and your distro does not prefer one, AppArmor is the better choice simply because it easier to configure correctly.

Concluding Remarks

Hopefully this document serves as some help to someone. Should this get posted to the RIT CSEC 380 blog, I will probably be unable to fix or update it – so please refer to my normal blog at for any fixes, erratas, etc.

Sources/Further Reading

Red Hat Enterprise Linux SELinux Manual

CentOS SELinux Documentation

SELinux Project Wiki

Gentoo SELinux Documentation

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s