Most people who know Linux have at least heard about SELinux. SELinux, or Security-Enhanced Linux, was originally developed primarily by the NSA (U.S. National Security Agency), as an implementation of the Flask operating system security architecture. Flask implements MAC (Mandatory Access Control), a means of designating what processes have access to what resources (be they network ports, files, and so on). A lot of work has been done to make SELinux as easy to use as possible, although at first glance it does look hideously complex.
Since 2003, SELinux has been integrated into the mainline Linux kernel, and is fully supported in distributions such as Red Hat Enterprise Linux, Fedora, CentOS, Debian (disabled by default), Ubuntu, openSUSE, Hardened Gentoo, and others. On Red Hat Enterprise Linux and Fedora, SELinux is enabled at installation.
There is a lot of information out there on SELinux; a lot of it, if you look at it quickly, may scare you off of SELinux. Don't feel bad, it did the same to me as well. When I was developing Annvix, I opted to use AppArmor instead of SELinux because it seemed like the easier of the two and offered nearly the same end-result functionality. If I had to make that choice again, today, I would choose SELinux, however.
From a security standpoint, distributions and Linux vendors today do a herculean job of keeping Linux operating systems safe. This is good news for anyone using Linux; however, the bad news is that a lot of this is reactive security. If there is a vulnerability in Apache, the vendor will typically backport a fix and release an update. However, there is a window of vulnerability between when the fix is released and when the problem is made public; there may be an even larger window of vulnerability if this is something that hasn't necessarily been made public, but is already being exploited (the so-called 0-day flaws). SELinux and tools like it are designed to protect you from these flaws by offering proactive security mechanisms.
For instance, if there were a flaw in Apache that allowed an attacker to make it display arbitrary files, this could be used to display the contents of files like /etc/passwd. This in turn makes it easier for an attacker to brute force SSH accounts by knowing in advance the account names to target.
Typically, Apache doesn't serve this content, so under normal circumstances (unless there is a flaw in a PHP application, etc.) this information would not be disclosed. If SELinux were installed and in enforcing mode, access to this file would be denied because the SELinux policy would prevent it (since these files are of the wrong type for Apache to access).
So while you may be running a vulnerable version of Apache, or a web application with a flaw in it, SELinux would prevent that disclosure because Apache has no rights to that file (of course, SELinux will happily allow Apache to display files that it does have the rights to access). In this instance, SELinux is a mitigation that would prevent a fairly serious confidentiality breach until such a time as a patched Apache could be installed. In a situation such as this, you really only have four choices:
- Turn Apache off to prevent the flaw from being exploited (generally, this would be considered bad for business)
- Continue to run Apache in a vulnerable state and pray for a quick update from the vendor
- Roll your own update to fix it
- Use something like SELinux, AppArmor, or some other MAC system for the proactive system hardening and security features it provides.
Speaking of features, SELinux has a number of features that make it compelling:
- It allows applications to query the policy, so they aren't fully hidden from view, unlike with some other MAC systems.
- It allows in-place policy changes; this means you can change the policy without having to reboot in order to activate the changes (I well remember having to do this with RSBAC).
- It has control over process initialization, inheritance, and program execution — this gives you the ability to write very flexible policies to suit your needs.
- It has control over file systems, directories, files, open file descriptors, as well as sockets (such as TCP, UDP, etc.), messaging interfaces, and network interfaces.
Using SELinux, you can fully tweak your system for any kind of operation, be it a web server, file server, print server, even a desktop system can be suitably secured with SELinux.
Of course, all of this comes at a price, and this is what puts most people off. SELinux is complex, and it becomes even more so when you have to write your own policies. Fortunately, distributions such as Red Hat Enterprise Linux and Fedora come with very comprehensive policies to cover a variety of situations. The policies are quite cookie-cutter, but if you want to change them to accommodate your own system (such as a web directory that exists in a place other than /var/www/html), you can easily do so.
Finally, SELinux offers three modes: enforcing, permissive, and disabled. Most distributions that support SELinux out-of-the-box will have it set to permissive mode first. This tells SELinux to log violations, so that you can use your system and use the reports to build a suitable policy. In permissive mode, a violation is logged, but the access is granted. In enforcing mode, a violation would be logged and the access denied. Disabled, of course, allows access but does not provide any information on what would have been denied. So before disabling SELinux, consider keeping it in permissive mode. You may get a number of alerts, particularly on a desktop system, but these can be used to tweak policy, reducing the number of alerts you will receive later.
Next time, I will look at some basics of SELinux and tweaking the policies, as well as identifying some of the tools that are used to monitor violations and modify policy.
Vincent Danen works on the Red Hat Security Response Team and lives in Canada. He has been writing about and developing on Linux for over 10 years and is a veteran Mac user.