Mandatory Access Control (MAC) with SELinux
No Access!
SELinux provides a safer system through the powerful concept of mandatory access controls.
Linux is an extremely safe operating system, but legacy access privileges provide no protection against misconfiguration or badly programmed software. If a program runs haywire because the administrator has forgotten to install the latest patch, or if a user escalates privileges due to an incorrect setting, the native safety of the system is no protection. SELinux mitigates the potential danger by adding an extra level of access control called the Mandatory Access Control (MAC) level.
About seven years ago, the National Security Agency (NSA) [1] launched the first version of SELinux. Intended as an extension for kernel 2.4 at the time, the kernel patches have since found their way into the official 2.6 kernel. For many distributions, SELinux is part of the standard configuration. The examples introduced in this article are based on the Red Hat community distribution Fedora Core 8, although they are generically valid on any other platform that supports SELinux. The important thing is that the required kernel support (CONFIG_SECURITY_SELINUX) and the libselinux, policycoreutils, and selinux-policy-targeted packages are installed. SELinux also requires a few standard packages (SysV-Init, pam, util-linux, coreutils, and others).
The legacy Linux security system is based on Discretionary Access Controls (DACs). This means that the owner of a file has absolute control over the object they have created. If a user inadvertently grants global write access to the file, a separate process that validates this step does not exist.
Or, if an attacker manages to execute arbitrary program code on the web server by exploiting a vulnerability in the web server software, the program code – a shell for example – will run with the privileges of a user account the server is running on. If that account is the apache user, the attacker has access to all files that the apache user account can access.
In most cases, no process checks whether the web server really needs to access the files that it is accessing to be able to do its chores. An attacker who gains access to the system then may be able to escalate their privileges on the machine. Just recently, many Linux systems were compromised because of a bug in the kernel that allowed attackers to exploit the vmsplice() system call. As a consequence, attackers gained complete control over the whole system.
On systems with SELinux, every file, or every object, is given a separate security label by MAC for an extra level of control. In the case of file objects, Linux stores this label in the extended attributes. At the same time, each process, or each subject, is also given the corresponding label. This label, which is known as the security context, typically comprises three components: User:Role:Type/Domain. Two examples of this for the Apache server process file /usr/bin/httpd file are as follows:
# ls -lZ /usr/sbin/http -rwxr-xr-x root root system_u:object_r:httpd_exec_t /usr/sbin/httpd
and:
# ps -AZ|grep httpd user_u:system_r:httpd_t 2571 ? 00:00:01 httpd
Just like security labels, the Posix ACLs extend attributes of a file. In this example, they look like this:
# getfattr -d -m security /usr/sbin/httpd ... security.selinux="system_u:object_r:httpd_exec_t\000"
File System Security Label
Although SELinux will work on file systems that do not support extended attributes, such as NFS or ISO9660, administrators have to resort to various workarounds to get this to happen. The mount command has an option to handle this: context=<security-label>. This lets you specify a security label for the complete filesystem.
SE Policy
The policy is another important component. An SE policy defines access between individual objects and subjects. The policy specifies which objects the process (such as an httpd process with a specific role) is allowed to access. If access is not explicitly permitted, it is initially logged and finally prohibited – at least in enforcing mode.
The kernel's security server makes sure that no infringement against the policy occurs. The security server is an entity that references the policy, and the security label defines whether access is permitted. To avoid performance overheads, the kernel-based server uses the Access Vector Cache (AVC).
SELinux Functions
SELinux distinguishes three different implementations:
- Type Enforcement (TE)
- Role-Based Access Control (RBAC)
- Multi-Level Security (MLS)
TE specifies which subject is permitted to access which objects – for example, which process is allowed to access which files. However, a wide variety of different objects exists, including network ports or memory areas. SELinux assigns a domain to each subject and a type to each object. To explain this generically, type enforcement controls which domain is allowed to access which types. Both types and domains are identified in a similar way; they always end with _t (e.g., httpd_t).
RBAC uses an abstract user model and assigns each user exactly one role. Users then inherit the privileges assigned to the role. It is thus possible to assign a role to the root user that does not possess any administrative privileges. To change to another role with extended privileges, the user would first need to authenticate with a password. This is an interesting feature if you want to set up the machine without the omnipotent root user. The user can only assume a single role at any given time; however, users can give the newrole command (which is similar to su) to change roles, assuming the policy allows this. A typical role name is user_r (roles always end with _r).
Russell Coker offers a couple of SELinux play machines on the network [2] to allow people to experiment; these machines demonstrate RBAC functionality. Coker has published the root account for these machines, allowing anybody who is interested to log in as the administrator. Testers will soon find out that the command set available to them is extremely restricted, in that the root user is not the administrative user on these play machines.
Finally, MLS defines different security levels and is primarily used in high-security environments, such as military applications. Objects are assigned to security levels (confidential, strictly confidential, secret, and so on), and subjects are given permissions for these different levels of confidentiality. Wherever MLS is deployed, the security label is extended by adding a fourth and fifth component until it looks like this:
User:Role:Type/
Domain:Sensitivity:Category
Demo
As a short demonstration of the way type enforcement works, consider the following: The administrator creates a file called index.html in the /tmp folder. After doing so, the administrator moves (doesn't copy) the file into the web server's document root, which, on Fedora, is /var/www/html/. Finally, the administrator launches the web server (/etc/init.d/httpd start) and accesses the page just created in a web browser (http://localhost/index.html). If SELinux enforcing mode is enabled (default), the web browser displays an error message because index.html was created in /tmp and inherited its security label:
# ls -lZ /tmp/index.html -rw-r--r-- root root root:object_r:tmp_t /tmp/index.html
In contrast, the web server process runs in the domain titled httpd_t:
# ps -AZ|grep httpd user_u:system_r:httpd_t2571 ?00:00:02 httpd
The policy needs a rule that gives the httpd_t domain access to tmp_t type files, but it does not exist. The web server needs to access its own configuration files, CGI scripts, and other content in its directory. Specific types exist for all of these files; for example, httpd_config_t, httpd_log_t, httpd_sys_script_exec_t, and httpd_sys_content_t.
Files in the /tmp folder are not typically the kinds of objects the web server accesses; thus, no allow instruction is in the policy file for the tmp_t type.
If you check the /var/log/audit/audit.log file, you will find a message to the effect that an unauthorized attempt to open a file has just taken place:
... audit(1202241301.521:12): avc: denied {getattr } for pid=6608 comm="httpd" name="index.html" dev=dm-0 ino=179881 scontext=user_u:system_r:httpd_t tcontext=root:object_r:tmp_t tclass=file
This log entry reveals that the process with PID 6608 and name httpd has just attempted to issue the getattr system call (i.e., it attempted to call the attributes) for a file with inode number 179881 and name index.html. scontext and tcontext refer to the security label for the source process (apache) and the target file (index.html). avc: denied indicates that the security server running in the kernel prevented this action.
If you prefer a more structured approach, you can use seaudit to view logfiles (Figure 2); the tool displays individual log entries graphically.
By calling seaudit-report --html logfile, you can even generate an HTML page that displays both the logs and various statistics on the SELinux system (see Figure 3).
Spotting Trouble
If setroubleshootd is running, the following additional entry is displayed in the logfile /var/log/messages:
setroubleshoot: #012 SELinux is preventing the /usr/sbin/httpd from using potentially mislabeled files (/var/www/html/index.html).#012 For complete SELinux messagesrun sealert -l 5e982b3b-3ae7-4848-b8bd-7d8553a07732
The setroubleshoot demon was developed some time back to make the slightly cryptic messages issued by the audit daemon more readable and to give users tips on resolving problems. If the user issues the command specified in the log entry, they get to see the explanation shown in Listing 1.
Listing 1
sealert -l
Summary SELinux is preventing the /usr/sbin/httpd from using potentially mislabeled files (/var/www/html/index.html). Detailed Description SELinux has denied /usr/sbin/httpd access to potentially mislabeled file(s) (/var/www/html/index.html). This means that SELinux will not allow /usr/sbin/httpd to use these files. It is common for users to edit files in their home directory or tmp directories and then move (mv) them to system directories. The problem is that the files end up with the wrong file context which confined applications are not allowed to access. Allowing Access If you want /usr/sbin/httpd to access this files, you need to relabel them using restorecon -v /var/www/html/index.html. You might want to relabel the entire directory using restorecon -R -v /var/www/html. ...
The Gnome desktop displays a small icon (a yellow shield) in the taskbar whenever an SELinux log entry is created. Users can click the icon to pop up the graphical SELinux troubleshooting browser, which lets you browse graphically through the processed messages (Figure 4). This tool provides novice admins a way to resolve problems:
restorecon -v /var/www/html/index.html
The command uses a policy to set the correct label for the index.html file. Alternatively, the administrator can specify the correct file type manually:
chcon -t httpd_sys_content_t /var/www/html/index.html
Either way, the results should be:
# ls -lZ /var/www/html/index.html -rw-r--r-- root root system_u:object_r:httpd_sys_content_t /var/www/html/index.html
The next time somebody tries to display a file in the web browser, there shouldn't be any security obstacles.
The example here shows how SELinux works. Independent of legacy privileges, Linux only permits access if a corresponding entry in the SELinux policy exists (MAC). The security-conscious distributor or administrator will only create this entry if access is really necessary.
Buy this article as PDF
(incl. VAT)
Buy Linux Magazine
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters
Support Our Work
Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.
News
-
New Linux Kernel Patch Allows Forcing a CPU Mitigation
Even when CPU mitigations can consume precious CPU cycles, it might not be a bad idea to allow users to enable them, even if your machine isn't vulnerable.
-
Red Hat Enterprise Linux 9.5 Released
Notify your friends, loved ones, and colleagues that the latest version of RHEL is available with plenty of enhancements.
-
Linux Sees Massive Performance Increase from a Single Line of Code
With one line of code, Intel was able to increase the performance of the Linux kernel by 4,000 percent.
-
Fedora KDE Approved as an Official Spin
If you prefer the Plasma desktop environment and the Fedora distribution, you're in luck because there's now an official spin that is listed on the same level as the Fedora Workstation edition.
-
New Steam Client Ups the Ante for Linux
The latest release from Steam has some pretty cool tricks up its sleeve.
-
Gnome OS Transitioning Toward a General-Purpose Distro
If you're looking for the perfectly vanilla take on the Gnome desktop, Gnome OS might be for you.
-
Fedora 41 Released with New Features
If you're a Fedora fan or just looking for a Linux distribution to help you migrate from Windows, Fedora 41 might be just the ticket.
-
AlmaLinux OS Kitten 10 Gives Power Users a Sneak Preview
If you're looking to kick the tires of AlmaLinux's upstream version, the developers have a purrfect solution.
-
Gnome 47.1 Released with a Few Fixes
The latest release of the Gnome desktop is all about fixing a few nagging issues and not about bringing new features into the mix.
-
System76 Unveils an Ampere-Powered Thelio Desktop
If you're looking for a new desktop system for developing autonomous driving and software-defined vehicle solutions. System76 has you covered.