Configuring sensitivity categories
Although MCS policies are MLS-enabled, they are configured to only support a single sensitivity (namely s0
). Yet even with this limitation, an MCS policy can be very useful, for instance, in situations where a system hosts services for multiple customers. This is because MCS can still benefit from security clearances based on categories.
Unlike sensitivities, categories are more like a discretionary access control system. Categories are meant to be used by users (or administrators) to label files and other resources as being a member of one or more categories. Access to those resources is then based on the clearance level of the process and the categories assigned to the resource. Categories are also not hierarchically structured.
An example of a use case where categories play a major role is in multitenant deployments: systems that host one or more services for multiple tenants (multiple customers), which, of course, require proper security segregation so that one tenant cannot access resources of another tenant.
In most cases, administrators will try to separate those services through the runtime user (and group membership). This is, however, not always possible. There are situations where these separate processes still need to run as the same runtime user (although with support for additional Linux security subsystems—such as capabilities—the number of situations has significantly reduced again).
In this recipe, we'll configure a system to use multiple categories to differentiate between resources of different customers for a web server that the customers also have shell access to. Through categories, we can provide more protection for the resources of other customers, in case one of the customers is able to execute an exploit that would elevate their privileges.
Getting ready
You need to prepare a system for the multiple tenants. For instance, we can host the entire website content in /srv/web/<companyname>/
and have the web server configuration at /etc/apache/conf/<companyname>/
.
In this recipe, as an example, we will configure the system for two companies called CompanyX
and CompanyY
. Each company also has a regular user (userX
for the first company and userY
for the second).
How to do it…
To instantiate different categories, follow this approach:
- Settle on the category naming (and numbers) for different customers and configure those in the
setrans.conf
file inside/etc/selinux/mcs/
:s0:c100=CompanyX s0-s0:c100=CompanyXClearance s0:c101=CompanyY s0-s0:c101=CompanyYClearance
- Restart the
mcstrans
service so that it is aware of this configuration. - List the categories to make sure that the changes are properly interpreted:
~$ chcat –L s0 SystemLow s0-s0:c0.c1023 SystemLow-SystemHigh s0:c0.c1023 SystemHigh s0:c100 CompanyX s0-s0:c100 CompanyXClearance s0:c101 CompanyY s0-s0:c101 CompanyYClearance
- Create SELinux users that have clearance to handle the right categories:
~# semanage user –a –L s0 –r CompanyXClearance –R "user_r" userX_u ~# semanage user –a –L s0 –r CompanyYClearance –R "user_r" userY_u
- Configure the Linux users (logins) with the right security clearance:
~# semanage login –m –s userX_u userX ~# semanage login –m –s userX_u userY
- Set the right category on the company resources:
~# chcon –l CompanyX –R /srv/web/www.companyX.com/ /etc/apache/conf/companyX/ ~# chcon –l CompanyY –R /srv/web/www.companyY.com/ /etc/apache/conf/companyY/
- Configure the Apache
init
scripts to launch Apache with the right security level by launching it throughruncon
. For instance, on a Red Hat Enterprise Linux 6 system for the first company's web server, the following script is used:LANG=$HTTPD_LANG daemon --pidfile=${pidfile} runcon –t httpd_t –l CompanyX $httpd $OPTIONS
- (Re)start the web server and validate that it is running with the right security level:
~# ps –efZ | grep httpd
How it works…
We started by configuring the system so that we can name categories and ranges rather than having to use the integer representations. Next, we created an SELinux user for each company and assigned each (regular) Linux account to the right SELinux user. After updating the contexts of all company-related files, we configured Apache to start in the right context.
The mcstrans and setrans.conf files
The setrans.conf
file is a regular text file that the MCS transition daemon (mcstransd
) uses to substitute the real security level (such as s0:c100
) with a human readable string (such as CompanyX
).
The Linux utilities themselves (such as ls
and ps
) use the SELinux libraries to get information about the contexts of files and processes. These libraries then connect with the mcstransd
process (through the /var/run/setrans/.setrans-unix
socket), sending the real security level and retrieving the human-readable representation for it.
It is important to remember that this is only a representation and not how the security level is stored. In other words, do not use this in file context definition files (that is, the SELinux policy .fc
files).
SELinux users and Linux user mappings
In the example, an SELinux user is created for each company. This SELinux user is given the clearance to work with resources tagged with the category of the respective companies. The real Linux accounts are then mapped to this SELinux user.
From the example, we see that there are two definitions for each company:
s0:c100 CompanyX s0-s0:c100 CompanyXClearance
The first one is a security level and can be assigned to both resources as well as processes (users). The second one is a security clearance (a range). In this particular example, the clearance tells us that the high security level (which can be seen as what the process is allowed to access) are the resources of the company (s0:c100
), and the low security level (which can be seen as the security level of the process itself ) is just s0
.
The users for the company, therefore, have clearance to access the files (and other resources) that have their company's category assigned to it. However, all activities performed by these user accounts do not get this category by default—the users will need to use chcon
to set the category, as follows:
~$ chcon –l CompanyX public_html/index.html
It is possible to give the users the security level itself rather than the clearance. When that occurs, any resource created by the user will also get the proper category set. But, do not use this as a way to confine resources—users can always remove categories from resources.
Granting the security level can be done on the SELinux user level, but it is also possible to do this through the SELinux user mapping as long as the range passed on is dominated by the range set on the SELinux user level. For instance, to set CompanyX
(s0:c100
) as the security level rather than CompanyXClearance
, which is the default for users mapped to the userX_u
SELinux user, the following command can be used:
~# semanage login –m –r CompanyX user1
Running Apache with the right context
The last change made in the example was to configure the system to start the web server with the right security level. This is done through the runcon
command, where we pass on the sensitivity level (and not the security clearance) to make sure that every resource created through the web server inherits the right category as well as the target type.
The SELinux policy knows that if an init
script launches the Apache binary (httpd
), then this application has to run in the httpd_t
domain. However, now the init
script launches runcon
—which the SELinux policy sees as a regular binary—so the application would continue to run in the initrc_t
domain. Hence, we need to pass on the target type (httpd_t
). On systems with an SELinux policy without unconfined domains, forgetting this would prevent the web server to run. On systems with an SELinux policy with unconfined domains, this might result in the web server to run in an unconfined domain (initrc_t
), effectively disabling the SELinux protections we need for the web server!
See also
The following are some more examples on multitenancy and how SELinux interacts with it:
- sVirt ( to segregate virtual guests from one another
- Linux containers, such as through the LXC project (https://linuxcontainers.org), use SELinux for further isolation of containers from the main system
- Apache has support for multitenancy through the
mod_selinux
module, which is covered in Chapter 3, Confining Web Applications