SELinux: Spook Tested, Admin Approved

By Carla Schroder | Aug 16, 2005 | Print this Page

Linux's basic security structure, which is based on Unix's least privilege model, works quite well. It's simple to understand and use; the basic idea is to never use more than the absolutely required permissions to perform a task.

Under this model, there are three levels of file ownership: owner, group, world. And three levels of file permissions: read, write, execute. Using "sticky" bits allows permissions to be inherited. Since everything in Linux and Unix is treated as a file -- data and system files, directories, and hardware devices -- it's a simple, flexible system for controlling access. This allows you, the ace sysadmin, to do neat things like grant users the ability to execute a script, but not read or edit it. Or to create shared directories that automatically set group ownership and permissions on new files, or to run daemons as unprivileged users. Human users run with minimal permissions to prevent them from mucking with system files; or if their accounts are compromised, limiting the damage to files owned by the user.

The Achilles' heel in this scheme is the root account, or superuser. Root has unlimited access to everything, so the goal of an attacker is to gain root access. The usual starting point is to penetrate an unprivileged user's account, then escalate privileges to root. In a well-administered Linux system this is difficult to do. But if an intruder does get root, well, game over.

Jailing Daemons
For Internet-facing systems like Web, DNS, and mail servers, one technique for limiting the damage from a successful intrusion is to run the server in a chroot jail. This means all the files necessary to run the server are contained in a special directory that is "walled off" from the rest of the system. So an intruder sees only the jail, and not the rest of the system. In theory anyway; chroot jails can be broken. And administering a complex server like Apache from a chroot jail quickly attains nightmarish dimensions.

The new darling of the Linux world is SELinux, Security Enhanced Linux. Developed by the NSA (National Security Agency), SELinux is one tough, tyrannical mama that takes the principal of least privilege to the extreme of Mandatory Access Controls (MAC). It even restricts the root user. It can be thought of as a security server than runs inside the kernel, which then controls what parts of the system a particular process can have access to. Somewhat like a big chroot jail with lots of cells, or a very paranoid house with locks on every door, window, cabinet, and drawer -- if one part of the system is compromised, SELinux aims to confine the damage in as narrow a space as possible, and to force an intruder to work hard for small gains.

SELinux does things differently than the standard Linux permissions scheme. Here is a rundown of terminology and concepts.

Subjects and objects are two primary elements in the way SELinux works. Subjects do things to objects. Subjects are processes. (Remember that processes are already read into memory and are doing things; a single program can spawn many processes.)

Objects in SELinux are files, directories, filesystems, block devices, soft and hard links, network sockets, character devices, and processes.

SELinux can be run in enforcing or permissive mode, or it may be disabled completely. In enforcing mode, SELinux blocks activities that are not specifically allowed. In permissive mode it merely logs what would have happened if SELinux were run in enforcing mode. Permissive mode is great for testing.

SELinux is all about type enforcement. A type is a security attribute assigned to an object, and it determines who has access to the object and what they can do with it. A type is like a domain, except domains are for processes, and types are for objects. You can think of a type as a sandbox, an effective foil to privilege escalation.

Domains are lists of what processes are allowed to do, and what they are permitted to access. Every process runs in a domain. Some examples of domains are Red Hat's unconfined_t, which is unrestricted, like not using SELinux at all. sysadm_t is for system administrators, and user_t is the unprivileged user domain. mysqld_t, dhcpd_t, httpd_t, and syslogd_t are examples of domains for common services.

Roles define which SELinux user identities get access to which domains. sysadm_r is a special role for administering SELinux. Unprivileged users get the user_r role.

SELinux maintains its own set of identities separate from Linux user IDs, so you need to create identities for your human users. SELinux identities are placed in the users file in the policy directory, like this:

user carla roles { staff_r sysadm_r };

Policies are central to administering SELinux. These are the sets of rules that you create for controlling access to the system. Creating policies involves editing several text files, then running the included checkpolicy compiler to create a binary policy file.

Using SELinux
SELinux is no picnic to administer; most ordinary mortals should practice on a test system first. A lot. And keep a rescue disk like Knoppix handy, in case you lock yourself out. It's still just a baby, so we should see some nice management utilities created for it as it matures. SELinux can be added to an existing Linux system, or you can take the easy way and install a distribution that already has it enabled, such as Fedora, Red Hat Enterprise 4 or Gentoo. Getting Started with SE Linux HOWTO is a great howto for adding it to an existing system.

When should you consider using SELinux? Any system that is open to untrusted networks -- firewall/gateway, server, router -- is an obvious candidate. Keep in mind there is a performance hit, plus the increased complexity of administration. Sensitive internal servers might also be worthy of being SELinux-ized. Workstations? I think life is too short to be that controlling. Remember, anyone with physical access to a box owns it, so don't go nuts with the esoteric stuff and overlook the obvious. Though Red Hat and Fedora ship with a default policy that locks down daemons, but does not hassle human users, which is a nice extra layer of protection from users who like to poke around in places they don't belong.