SELinux; How it works and a cheat sheet

SELinux. Many probably heard of it, some may have ‘run into it’ and disabled it, but few actually seem to take the effort to properly set it up.

Even though it’s actually really trivial to use, if you know how.

What is SELinux / Mandatory Access Control?

Security Enhanced Linux, is a Mandatory Access Control (MAC) implementation at kernel and tools level.

That’s a whole mouth full, so lets break that down a little.

Mandatory Access Control, if you haven’t used it before, is a system to control access based on something’s purpose in a system. As opposed to Discretionary Access Control, where a user/group has access to a certain resource, with MAC, a program has to have the right labels to access a certain type of labeled resource.

For instance, a Webserver is expected to access webserver files, its webserver config, and open some ports to listen on. It is usually NOT expected to need access to other programs’ files, the user’s home directory, and so forth.

And vice versa, a game the user is playing is expected to access the home directory and gamesave files, as well as memory map large textures and such.

Thanks to the MAC labeling system, one can define what folders and what programs are associated with what type of actions, and what to expect from these, allowing you to keep the webserver out of the directories of users and other programs, easily using simple labels on top of the usual user rights.

There are many of these systems out there; AppArmor is also a widely used one, however, that one works at service level rather than from the kernel itself, which means that if the service dies or gets compromised, the MAC stops working. GRSec also a good one, which is less known but very powerful, and has a bunch of extra features. It can be more convenient in some situations, but here I’ll focus on SELinux, as I know more about it, and find it more intuitive and easy to use.

Why did SELinux cause issues with someapplication? Even as root user?

Because it’s an extra level of security. You can see it as yet another user/groups permissions system (DAC), on top of the existing user permissions system.

If SELinux detects that your webserver is e.g trying to access files it usually isn’t expected to access, such as the user’s home directory, it will block the attempt, which usually manifests as an ‘access denied’ error, even if you’re the root user.

A quick way to test if SELinux is in the way, is to disable its enforcement and try to see if it still causes issues.

This can be done with setenforce 0.

Do note however that this is a temporary setting, also shouldn’t be kept in this state; when you reboot it’ll reset back to enforcement (unless you disable it in /etc/selinux/config), and it’s a good practice to always keep SELinux enabled, unless you’re messing with it.

How do I allow my program to work under SELinux?

It’s actually really simple, but there’s various ways to go about it;

Option 1) execute audit2why -a and see what rules are causing the problem. Often audit2why will suggest you how to fix it with an example command.

Option 2) execute audit2allow -a -M policyname and create a policy from your current audit file’s contents.

Beware that both of these create a policy based on the entire audit file, and if you want something more specific, you should empty /var/log/audit/audit.log, execute setenforce 0, run the application, exit the application, and then run the commands above.

You can opt to leave SELinux disabled for a day or two to get a full picture of the program/service’s permission needs, but if it’s been a week and there’s no new problems in the audit log, it should be safe to re-enable it.

Diving deeper into SELinux

There’s of course, a lot more to say about SELinux than the surface which I touched here. I may eventually write a dedicated deep dive about how the labeling works, what kind of things are being blocked, and how all of this works, but to be quite frank it gets a lot more complicated quite quickly there, and I haven’t fully groked the material myself yet. In the future I do plan to address this, but then I also kind of want to touch deeper on AppArmor and GRSec, which each also have their own unique advantages and disadvantages.

SELinux is a system that looks at the context label a process has, and matches them to the context label of a (network) resource or file.

A label consists of the following attributes (taken from’s cheatsheet): user → identity known to the policy authorized for a specific set of roles and a specific MLS/MCS range role → attribute of RBAC, serves as an intermediary between domains and SELinux users type → attribute of type enforcement, defines a domain for processes and a type for files level → attribute of MLS/MCS, pair of levels, written as lowlevel-highlevel if the levels differ, or lowlevel if the levels are identical

Cheat sheet

I may add more stuff here later, but this should cover the basics.

Temporarily disable SELinux enforcement

setenforce 0

Persistently disable SELinux enforcement

edit /etc/selinux/config and set it to ‘permissive’.

Explain all the errors currently in the audit file

audit2why -a

Create a policy from the audit file’s contents

audit2allow -a -M MODULENAME

Relabel a folder or file based on its current location in the file system

restorecon PATH touch /.autorelabel and reboot, if you want to relabel the entire filesystem.

Interact with the SELinux labels using the GNU toolchain

ls -Z PATH – List attributes id -Z – shows user SELinux context ps -Z – shows SELinux contexts of processes netstat -Z – shows the SELinux context with every connection cp -Z – set SELinux security context of destination (specify context) mkdir -Z – set SELinux security context of destination (specify context)

Other people’s cheat sheets


I don’t have audit2allow/audit2why/etc

  • Install setroubleshoot and setroubleshoot-server