Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
SELinux System Administration

You're reading from   SELinux System Administration Effectively secure your Linux systems with SELinux

Arrow left icon
Product type Paperback
Published in Dec 2016
Publisher Packt
ISBN-13 9781787126954
Length 300 pages
Edition 2nd Edition
Tools
Arrow right icon
Author (1):
Arrow left icon
Sven Vermeulen Sven Vermeulen
Author Profile Icon Sven Vermeulen
Sven Vermeulen
Arrow right icon
View More author details
Toc

Table of Contents (11) Chapters Close

Preface 1. Fundamental SELinux Concepts FREE CHAPTER 2. Understanding SELinux Decisions and Logging 3. Managing User Logins 4. Process Domains and File-Level Access Controls 5. Controlling Network Communications 6. sVirt and Docker Support 7. D-Bus and systemd 8. Working with SELinux Policies 9. Analyzing Policy Behavior 10. SELinux Use Cases

Distinguishing between policies

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, it is recommended to consult 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 that are enabled through the policy.

Supporting MLS

One of the options that can be enabled is MLS support. If it is disabled, then the SELinux context will not have a fourth field with sensitivity information in it, making the contexts of processes and files look as follows:

    staff_u:sysadm_r:sysadm_t 

To check whether or not MLS is enabled, it is sufficient to see if the context, indeed, doesn't contain such a fourth field, but it can also be acquired from the Policy MLS status line in the output of sestatus:

    # sestatus | grep MLS 
    Policy MLS Status:            disabled 

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 
    0 

Policy stores that have MLS enabled are generally targeted, mcs, and mls, whereas strict generally has MLS disabled.

Dealing with unknown permissions

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. SELinux can be configured to do one of the following actions:

  • allow: Assume everything that is not understood is allowed
  • deny: Assume no one is allowed to perform this action
  • reject: Stop and halt the system

This is configured 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:   denied 

Administrators can set this for themselves in the /etc/selinux/semanage.conf file through the handle-unknown variable (with allow, deny, or reject).

RHEL by default allows unknown permissions, whereas Gentoo by default denies them.

Supporting unconfined domains

A 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 have been brought forward 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 was designed to be a full mandatory access control system and thus needs to provide access control rules even for those applications that shouldn't need any. By marking these applications as unconfined, almost no additional restrictions are imposed by SELinux.

We can see whether or not unconfined domains are enabled on the system through seinfo, which we use to query the policy for the unconfined_t SELinux type. On a system where unconfined domains are supported, this type will be available:

    # seinfo -tunconfined_t 
      unconfined_t 

For a system where unconfined domains are not supported, the type will not be part of the policy:

    # seinfo -tunconfined_t 
    ERROR: could not find datum for type unconfined_t 

Most distributions that enable unconfined domains call their policy targeted, but this is just a convention that is not always followed. Hence, it is always best to consult the policy using seinfo. RHEL enables unconfined domains, whereas with Gentoo, this is a configurable setting through the unconfined USE flag.

Limiting cross-user sharing

When UBAC is enabled, certain SELinux types will be protected by additional constraints. This will ensure that one SELinux user cannot access 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. In essence, it is made to isolate SELinux users from one another.

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, otherwise--most policy writers will not touch constraints during their development efforts.

Many Linux distributions, including RHEL, disable UBAC. Gentoo allows users to select whether or not they want UBAC through the Gentoo ubac USE flag (which is enabled by default).

Incrementing policy versions

While checking the output of sestatus, we see that there is also a notion of policy versions:

    # sestatus | grep version 
    Max kernel policy version:      28 

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, 28 is the highest policy version the kernel supports. Every time a new feature is added to SELinux, the version number is increased. The policy file itself (which contains all the SELinux rules loaded at boot time by the system) can be found in /etc/selinux/targeted/policy (where targeted refers to the policy store used, so if the system uses a policy store named strict, then the path would be /etc/selinux/strict/policy).

If multiple policy files exist, we can use the output of seinfo to find out which policy file is used:

    # seinfo 
    Statistics for policy file: /etc/selinux/targeted/policy/policy.30 
    Policy Version & Type: v.30 (binary, mls) 
    ... 

The next table provides the current list of policy feature enhancements and the Linux kernel version in which that feature is introduced. Many of the features are only of concern to the policy developers, but knowing the evolution of the features gives us a good idea about the evolution of SELinux:

Version

Linux kernel

Description

12

The "old API" for SELinux, now deprecated.

15

2.6.0

Introduced the new API for SELinux.

16

2.6.5

Added support for conditional policy extensions.

17

2.6.6

Added support for IPv6.

18

2.6.8

Added support for fine-grained netlink socket permissions.

19

2.6.12

Added support for MLS.

20

2.6.14

Reduced the size of the access vector table.

21

2.6.19

Added support for MLS range transitions.

22

2.6.25

Introduced policy capabilities.

23

2.6.26

Added support for per-domain permissive mode.

24

2.6.28

Added support for explicit hierarchy (type bounds).

25

2.6.39

Added support for filename-based transitions.

26

3.0

Added support for role transitions for non-process classes.

Added support for role attributes.

27

3.5

Added support for flexible inheritance of user and role for newly-created objects.

28

3.5

Added support for flexible inheritance of type for newly-created objects.

29

3.14

Added support for attributes within SELinux constraints.

30

4.3

Added support for extended permissions and implemented first on IOCTL controls.

Enhanced SELinux XEN support.

History of SELinux feature evolution

By default, when a 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.

Different policy content

Besides the policy capabilities described above, 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. But although that project is considered the master for most distributions, each distribution has its own deviation from the 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:

  • The policy enhancements or additions are still immature: Red Hat initially starts with policies being active but permissive, meaning the policies are not enforced. Instead, SELinux logs what it would have prevented and, based on those logs, the policies are then enhanced. This means that a policy is only ready after a few releases.
  • The policy enhancements or additions are too specific to the distribution: If a policy set is not reusable for other distributions, then some distributions will opt to keep those policies to themselves as the act of pushing changes to upstream projects takes quite some effort.
  • The policy enhancements or additions haven't followed the upstream rules and guidelines: The reference policy has a set of guidelines that policies need to adhere to. If a policy set does not comply with these rules, then it will not be accepted.
  • The policy enhancements or additions are not implementing the same security model as the reference policy project wants: As SELinux is a very extensive mandatory access control system, it is possible to write completely different policies.
  • The distribution does not have the time or resources to push changes upstream.

This means that SELinux policies between distributions (and even releases of the same distribution) can, content-wise, be quite different. Gentoo for instance aims to follow the reference policy project closely, with changes being merged within a matter of weeks.

You have been reading a chapter from
SELinux System Administration - Second Edition
Published in: Dec 2016
Publisher: Packt
ISBN-13: 9781787126954
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime