
SELinux System Administration, Third Edition
By :

The most common SELinux policy store names are strict
, targeted
, mcs
, and mls
. None of the names assigned to policy stores are fixed though, so it is a matter of convention. Hence, we recommend consulting the distribution documentation to verify what the proper name of the policy should be. Still, the name often provides some information about the SELinux options enabled through the policy.
One of the options that can be enabled is MLS support. The SELinux context will not have a fourth field with sensitivity information in it if this option is disabled, making the contexts of processes and files look as follows:
staff_u:sysadm_r:sysadm_t
To check whether MLS is enabled, it is sufficient to see whether a process context doesn't contain such a fourth field. Another way is to check the Policy MLS Status
line in the output of sestatus
:
# sestatus | grep MLS Policy MLS status: enabled
Yet another method would be to look into the pseudo file, /sys/fs/selinux/mls
. A value of 0
means disabled, whereas a value of 1
means enabled:
# cat /sys/fs/selinux/mls 1
Policy stores that have MLS enabled are generally targeted
, mcs
, and mls
, whereas strict
generally has MLS disabled.
Permissions (such as read, open, and lock) are defined both in the Linux kernel and in the policy itself. However, sometimes, newer Linux kernels support permissions that the current policy does not yet understand.
Take the block_suspend
permission (to be able to block system suspension) as an example. If the Linux kernel supports (and checks) this permission but the loaded SELinux policy does not understand that permission yet, then SELinux has to decide how it should deal with the permission. We can configure SELinux to perform one of the following actions:
allow
).deny
).reject
).We configure this through the deny_unknown
value. To see the state for unknown permissions, look for the Policy deny_unknown status
line in sestatus
:
# sestatus | grep deny_unknown Policy deny_unknown status: allowed
Administrators can set this for themselves in the /etc/selinux/semanage.conf
file through the handle-unknown
variable (with allow
, deny
, or reject
).
An SELinux policy can be very strict, limiting applications as close as possible to their actual behavior, but it can also be very liberal in what applications are allowed to do. One of the concepts available in many SELinux policies is the idea of unconfined domains. When enabled, it means that certain SELinux domains (process contexts) are allowed to do almost anything they want (of course, within the boundaries of the regular Linux DAC permissions, which still hold) and only a select number of domains are truly confined (restricted) in their actions.
Unconfined domains are introduced to allow SELinux to be active on desktops and servers where administrators do not want to fully restrict the entire system, but only a few of the applications running on it. Generally, these implementations focus on constraining network-facing services (such as web servers and database management systems) while allowing end users and administrators to roam around unrestricted.
With other MAC systems, such as AppArmor, unconfinement is inherently part of the design of the system as they only restrict actions for well-defined applications or users. However, SELinux is designed to be a full mandatory access control system and thus needs to provide access control rules even for those applications that aren't the security administrator's primary focus. By marking these applications as unconfined, almost no restrictions are imposed by SELinux.
We can see whether unconfined domains are enabled on the system using seinfo
, by querying the policy and asking it whether the unconfined_t
SELinux type is defined. On a system where unconfined domains are supported, this type will be available:
# seinfo -t unconfined_t Types: 1 unconfined_t
For a system where unconfined domains are not supported, the type will not be part of the policy:
# seinfo -t unconfined_t Types: 0
Most distributions that enable unconfined domains call their policy targeted
, but this convention is not always followed. Hence, it is always best to consult the policy using seinfo
. CentOS enables unconfined domains, whereas with Gentoo, this is a configurable setting through the unconfined USE
flag.
When UBAC is enabled, certain SELinux types will be protected by additional constraints. This will ensure that one SELinux user cannot access the files (or other specific resources) of another user, even when those users are sharing their data through the regular Linux permissions. UBAC provides some additional control over information flow between resources, but it is far from perfect. Essentially, it is made to isolate SELinux users from one another.
Important note
A constraint in SELinux is an access control rule that uses all parts of a context to make its decision. Unlike type enforcement rules, which are purely based on the type, constraints can take the SELinux user, SELinux role, or sensitivity label into account. Constraints are generally developed once and left untouched – most policy writers will not touch constraints during their development efforts.
Many Linux distributions, including CentOS, disable UBAC. Gentoo allows users to decide whether they want UBAC through the Gentoo ubac USE
flag (which is enabled by default).
While checking the output of sestatus
, we see that there is also a reference to a policy version:
# sestatus | grep version Max kernel policy version: 32
This version has nothing to do with the versioning of policy rules but with the SELinux features that the currently running kernel supports. In the preceding output, 32 is the highest policy version that the running kernel supports. Every time a new feature is added to SELinux, the version number is increased. We can find the policy file itself (which contains all the SELinux rules loaded at boot time by the system) in /etc/selinux/targeted/policy
(where targeted refers to the policy store used, so if the system uses a policy store named mcs
, then the path will be /etc/selinux/mcs/policy
).
If multiple policy files exist, use seinfo
to discover which policy version file is used:
# seinfo | grep Version Policy version: 31 (MLS enabled)
A list of policy feature enhancements and the Linux kernel version in which that given feature is introduced is provided next. Many of the features are only of concern to policy developers, but knowing the evolution of the features gives us a good idea about the evolution of SELinux:
By default, when an SELinux policy is built, the highest supported version as defined by the Linux kernel and libsepol
(the library responsible for building the SELinux policy binary) is used. Administrators can force a version to be lower using the policy-version
parameter in /etc/selinux/semanage.conf
.
Besides the policy capabilities described in the previous section, the main difference between policies (and distributions) is the policy content itself. We already covered that most distributions base their policy on the reference policy project. Although the reference policy project is considered the master for most distributions, each distribution has its own set of deviations from this main policy set.
Many distributions make extensive additions to the policy without directly passing the policies to the upstream reference policy project. There are several possible reasons why this is not directly done:
This means that SELinux policies can differ between distributions (and even releases of the same distribution).
With this, we can conclude on some of the differentiation that distributions can put into their SELinux policies: they can opt to enable or disable MLS support, allow or deny unknown permissions, add distribution-provided unconfined domains, support user-based access controls, and/or deviate from the reference policy project to suit the distribution's principles.
Change the font size
Change margin width
Change background colour