Getting Started with Multi-Category Security (MCS)

Previously, I posted a brief introduction to Multi-Category Security (MCS), outlining its rationale and design. Since then, work has continued on integrating MCS into Fedora for FC5, along with some other recent developments such as modular policy support and a comprehensive management framework.

We can now take a practical look at MCS, covering basic administration and use. Currently, you’ll need to be running Fedora Core rawhide to ensure that all of the latest libraries and utilities are present on the system. Check that you have at least policycoreutils-1.29.8-4.

As discussed in my previous post on the topic, MCS allows users to assign categories to their own files. These categories are simply text labels, such as “Company_Confidential” or “Medical_Records”. The sysadmin first configures the categories, then assigns users to them as required.

So, jose might be assigned to categories “Marketing” and “Payroll”, while lara is assigned to “Finance”. The names of the categories and their meanings are set by the sysadmin, and can be set to whatever is required for the specific deployment. A system at home may simply have one category of “Private”, and be configured so that only trusted local users are assigned to this category.

Once users are assigned to categories, they may label any of their own files with any of their categories. So, our home user, frobnoz can label all of her secret diary entries “Private”, and no service such as apache or vsftp will ever be able to access such files, as they don’t have access to the “Private” category.

In a corporate environment, categories could be used to identify documents confidential to specific departments, or being covered under certain NDAs. So, when jose prepares a report on payroll statistics for the month, he can label it as “Payroll”, which will not be accessible by lara, who only has access to the “Finance” category.

It’s a very simple system: to access a file, a user needs to be assigned to all of the categories with which the file is labeled.

The MCS check is applied after normal Unix DAC and Type Enforcement rules, so it can only further restrict security.

Before moving onto practical matters, we need to clarify a couple of MCS/SELinux specific terms.

SELinux maintains its own user identity for processes, separately from Unix user identities. With targeted policy (the default for Fedora and RHEL), there are only a few SELinux user identities:

system_u System processes
root System administrator
user_u All login users

SELinux users can be viewed with the semanage(8) utility:

# semanage user -l

                MLS/       MLS/                          
SELinux User    MCS Level  MCS Range                      SELinux Roles

root            s0         SystemLow-SystemHigh           system_r sysadm_r user_r
system_u        s0         SystemLow-SystemHigh           system_r
user_u          s0         SystemLow-SystemHigh           system_r sysadm_r user_r

One of the properties of targeted policy is that login users all run in the same security context. From a TE point of view, in targeted policy, they are security-equivalent. However, for MCS, we need to be able to assign different sets of categories to different Unix users, even though they are all the same SELinux user (user_u above). This is solved by introducing the concept of an SELinux login, which is simply used during the login process to assign MCS categories to Unix users when their shell is launched.

SELinux logins can also be viewed with semanage(8):

# semanage login -l

Login Name                SELinux User              MLS/MCS Range            

__default__               user_u                    s0                       
fred                      user_u                    s0-Marketing,Payroll,NDA_Yoyodyne
jose                      user_u                    s0-Marketing             
lara                      user_u                    s0-Payroll,NDA_Yoyodyne,Company_Confidential,Marketing
root                      root                      SystemLow-SystemHigh

This also shows the mapping of SELinux logins to MCS categories. The “s0” values are MLS sensitivity levels, which we ignore in MCS. In this example, we can see that fred has access to the categories “Marketing”, “Payroll” and “NDA_Yoyodyne”. Unix users with no SELinux login are assigned to the default set of categories, which in this case is empty. root has access to all categories. Rather than display every possible category here, the alias “SystemLow-SystemHigh” is used, which means every possible security level from the lowest to the highest on the system.

Now that we’ve covered SELinux users and SELinux logins, we can really get started.

Configuring Categories
The first thing the sysadmin will want to do with MCS is configure some categories. This is carried out by editing /etc/selinux/targeted/setrans.conf, a file which specifies how the internal MLS sensitivities and categories are to be translated for human use. As discussed in the previous post, SELinux has an internal representation of MLS/MCS labels. For categories, they are of the abstract form c0, c1, … c255. Meaning that up to 256 separate categories can be used on the system.

The setrans.conf file contains mappings from internal labels to external values.

Here’s how the file looks by default:


On the left of the equals sign is the MLS/MCS security level, while the human-readable value is on the right. The “s0” is the dummy MLS sensitivity level. On the first line “s0=” means to simply display nothing when there are no categories. This also hides the dummy “s0”.

The next two lines simply add aliases for some common cases, to suppress displaying all 256 categories if a user (such as root) is assigned to all of them. Note the syntax for specifying a range of categories: “c0.c4” means all categories from “c0” through “c4”. This can also be represented as “c0,c1,c2,c3,c4”.

Now, let’s add a some categories:


This simply maps “c0” to “Company_Confidential”, and so on. Once saved, these categories have been configured for use.

To get a handy listing of categories, use the chcat(8) utility:

# chcat -L
s0-s0:c0.c255                  SystemLow-SystemHigh
s0:c0.c255                     SystemHigh
s0:c0                          Company_Confidential
s0:c1                          Marketing
s0:c2                          Payroll
s0:c3                          NDA_Yoyodyne

Labeling Files
As root, you can now start labeling files with MCS categories (because the SELinux login for root has access to all of them). Start with a file with no MCS category label:

# cd /tmp
# echo "This is a test file" > testfile.txt
# ls -Z testfile.txt 
-rw-r--r--  root     root     root:object_r:tmp_t              testfile.txt

This shows the standard SELinux security context assigned to the file by the kernel upon creation. The setrans.conf file is actually hiding the “s0” sensitivity level. You can disable this translation completely at any time by adding the following line to setrans.conf:


Now, let’s have a look at the file listing again:

# ls -Z testfile.txt 
-rw-r--r--  root     root     root:object_r:tmp_t:s0           testfile.txt

Enable translation again by commenting the “disable=1” line out:


Here’s how to add an MCS category to the file:

# chcat --   +Marketing testfile.txt

(The ‘–‘ is used to indicate that any options to chcat have finished).

Now, look at the file listing:

[root@xeon tmp]# ls -Z testfile.txt 
-rw-r--r--  root     root     root:object_r:tmp_t:Marketing    testfile.txt

The security context now has an extra field, “Marketing”. This is an MCS category. We can add another:

# chcat --   +Payroll testfile.txt

And we should now see the file labeled with both categories:

# ls -Z testfile.txt 
-rw-r--r--  root     root     root:object_r:tmp_t:Marketing,Payroll testfile.txt

You can arbitrarily add and delete category labels:

# chcat --  +NDA_Yoyodyne,-Marketing,-Payroll testfile.txt
# ls -Z testfile.txt
# -rw-r--r--  root     root     root:object_r:tmp_t:NDA_Yoyodyne testfile.txt

To delete all categories (handy if there are more than one), use chcat -d.

Assigning Categories to Users
In these examples, three Unix users have been added to the system: andre, martina and venus. Initially, they’re all associated with the default SELinux login, with root configured for all categories by the installer:

# semanage login -l

Login Name                SELinux User              MLS/MCS Range            

__default__               user_u                    s0                       
root                      root                      SystemLow-SystemHigh

On this system, we’ll say that andre is in the Marketing department, and martina is in the Payroll department. venus is a senior executive with access to all of the important information in the company. To allow these users to be distinguished by MCS, they need to be mapped to SELinux logins:

# semanage login -a andre
# semanage login -a martina
# semanage login -a venus
# semanage login -l

Login Name                SELinux User              MLS/MCS Range            

__default__               user_u                    s0                       
andre                     user_u                    s0                       
martina                   user_u                    s0                       
root                      root                      SystemLow-SystemHigh     
venus                     user_u                    s0

As you can see, these users are now configured with SELinux logins, with no MCS categories assigned.

To assign MCS categories to these logins, use chcat(8), with the ‘-l’ parameter to specify a login object instead of a file:

# chcat -l --  +Marketing andre
# chcat -l --  +Payroll martina
# chcat -l --  +Payroll,+Marketing,+NDA_Yoyodyne venus
# semanage login -l

Login Name                SELinux User              MLS/MCS Range            

__default__               user_u                    s0                       
andre                     user_u                    s0-Marketing             
martina                   user_u                    s0-Payroll               
root                      root                      SystemLow-SystemHigh     
venus                     user_u                    s0-Payroll,Marketing,NDA_Yoyodyne

You can also get a simpler listing of which categories a user has with the ‘-L’ option to chcat(8):

# chcat -L -l andre martina venus
andre: Marketing
martina: Payroll
venus: Payroll,Marketing,NDA_Yoyodyne

Note that as MCS category access is assigned during login, a user will not have access to the categories until they login again. Similarly, if access to a category is revoked, this will only be apparent to the user after the next login.

Using Categories
With MCS categories now configured, and users assigned, we can look at a simple usage example.

andre is working on a new marketing strategy, and due to corporate policy, only members of the marketing department and some executives are allowed to know the details at this stage. He can use MCS to label any files containing information about the new strategy as follows:

$ chcat --  +Marketing andre_strategy.txt
$ ls -Z andre_strategy.txt
-rw-rw-r--  andre    andre    user_u:object_r:tmp_t:Marketing  andre_strategy.txt

This is just an example of how to use MCS: of course, you wouldn’t normally expect someone from marketing to work with such low level tools (then again, who knows). Integrating MCS labeling support into high-level apps such as editors is a near-tearm goal, and should be fairly straightforward. Anyway, now that the file is labeled with this MCS category, only users assigned to that category can access it, assuming that Unix DAC and SELinux TE permissions would already allow the access. Let’s see what happens when martina tries to read the file:

$ cat andre_strategy.txt 
cat: andre_strategy.txt: Permission denied

Note that the unix DAC permissions would have allowed this. But, venus should be able to access the file, as she has access to the category it’s labeled with:

$ cat andre_strategy.txt 
No idea, help...

MCS labeling from a user and sysadmin standpoint is very simple, although as a new technology, there are a few new things to learn. In a nutshell, it’s a matter of configuring a set of categories then assigning users access to them. The users can then use the labels as they see fit, including discretionary compliance with corporate security and other policies, which maps to the way such policies are generally implemented. For example, in a corporate environment, you may be given an NDA-covered document with handling instructions which you are required to follow. Exactly how you comply with such policies is often left up to common sense or fairly general procedural guidelines. MCS should map to this kind of thing much more readily than MLS, which is designed to map to very rigid military and government agency security policies and finely detailed procedures. MCS is more about providing a mechanism for complying with a wide range of policies and procedures, rather than hard-coding these policies into the code or even the defauult configuration.

As you can see, the basic tools and functionality exist, but more work is needed (and being done) on higher level tools and integration. A GUI tool from Dan Walsh should be available soon (it’s in internal testing), which will abstract much of this management away nicely. There’s a huge amount of work going on in the underlying SELinux management and deployment infrastructure, which will continue to bubble up into our management utilities and high-level apps.

Any questions on MCS, or if you want to dive in and work on something, contact the developers via the NSA SELinux mailing list or the Fedora SELinux mailing list.

Russell Coker will be giving a talk on MCS at the SELinux Symposium in Feb/Mar, Baltimore. We’re also hoping to have some form of discussion with users and interested parties, as MCS is a new and evolving technology.