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

Defining and distributing policies

Enabling SELinux does not automatically start the enforcement of access. If SELinux is enabled and it cannot find a policy, it will refuse to start. That is because the policy defines the behavior of the system (what SELinux should allow). SELinux policies are generally distributed in a compiled form (just like with software) as policy modules. These modules are then aggregated into a single policy store and loaded in memory to allow SELinux to enforce the policy rules on the system.

Note

Gentoo, being a source-based meta-distribution, distributes the SELinux policies as (source) code as well, which is compiled and built at install time, just like it does with other software.

The following diagram shows the relationship between policy rules, policy modules, and a policy package (which is often a one-to-one mapping towards a policy store):

Defining and distributing policies

Relationship between policy rules, policy modules, and policy store

Writing SELinux policies

A SELinux policy writer can (currently) write down the policy rules in three possible languages:

  • In standard SELinux source format--a human-readable and well-established language for writing SELinux policies
  • In reference policy style--this extends the standard SELinux source format with M4 macros to facilitate the development of policies
  • In the SELinux common intermediate language (CIL)--a computer-readable (and with some effort human-readable) format for SELinux policies

Most SELinux supporting distributions base their policy on the reference policy (https://github.com/TresysTechnology/refpolicy/wiki), a fully functional SELinux policy set managed as a free software project. This allows distributions to ship with a functional policy set rather than having to write one themselves. Many project contributors are distribution developers, trying to push changes of their distribution to the reference policy project itself, where the changes are peer-reviewed to make sure no rules are brought into the project that might jeopardize the security of any platform. It easily becomes very troublesome to write reusable policy modules without the extensive set of M4 macros offered by the reference policy project.

The SELinux CIL format is quite recent (RHEL 7.2 does not support it yet), and although it is very much in use already (the recent SELinux user space converts everything in CIL in the background), it is not that common yet for policy writers to use it directly.

As an example, consider the web server rule we discussed earlier, repeated here for your convenience: allow the processes labeled with httpd_t to bind to TCP ports labeled with http_port_t.

In the standard SELinux source format, this is written down as follows:

    allow httpd_t http_port_t : tcp_socket { name_bind }; 

Using reference policy style, this rule is part of the following macro call:

    corenet_tcp_bind_http_port(httpd_t) 

In CIL language, the rule would be expressed as follows:

    (allow httpd_t http_port_t (tcp_socket (name_bind))) 

In most representations, we can see what the rule is about:

  • The subject (who is taking the action); in this case, this is the set of processes labeled with the httpd_t type.
  • The target resource or object (the target for the action); in this case, it is the set of TCP sockets (tcp_socket) labeled with the http_port_t type. In reference policy style, this is implied by the function name.
  • The action or permission; in this case, it is the action of binding to a port (name_bind). In reference policy style, this is implied by the function name.
  • The result that the policy will enforce; in this case, it is that the action is allowed (allow). In reference policy style, this is implied by the function name.

A policy is generally written for an application or set of applications. So the preceding example will be part of the policy written for web servers.

Policy writers will generally create three files per application or application set:

  • A .te file, which contains the type enforcement rules.
  • An .if file, which contains interface and template definitions, allowing policy writers to easily use the newly-generated policy rules to enhance other policies with. You can compare this to header files in other programming languages.
  • An .fc file, which contains file context expressions. These are rules that assign labels to resources on the file system.

A finished policy will then be packaged into a SELinux policy module.

Distributing policies through modules

Initially, SELinux used a single, monolithic policy approach: all possible access control rules were maintained in a single policy file. It quickly became clear that this is not manageable in the long term, and the idea of developing a modular policy approach was born.

Within the modular approach, policy developers can write isolated policy sets for a particular application (or set of applications), roles, and so on. These policies then get built and distributed as policy modules. Platforms that need access controls for a particular application load the SELinux policy module that defines the access rules for that application.

The process of building policy modules is shown in the next diagram. It also shows where CIL comes into play, even when the policy rules themselves are not written in CIL. For distributions that do not yet support CIL, semodule will directly go from the .pp file to the policy.## file.

Distributing policies through modules

Build process from policy rule to policy store

With the recent SELinux user space, the *.pp files (which are the SELinux policy modules) are considered to be written in a high-level language (HLL). Do not assume that this means they are human-readable: these files are binary files. The consideration here is that SELinux wants to support writing SELinux policies in a number of formats, which it calls high-level languages, as long as it has a parser that can convert the files into CIL. Marking the binary module formats as high-level allowed the SELinux project to introduce the distinction between high-level languages and CIL in a backwards-compatible manner.

When distributing SELinux policy modules, most Linux distributions place the *.pp SELinux policy modules inside /usr/share/selinux, usually within a subdirectory named after the policy store (such as targeted). There, these modules are ready for administrators to activate them.

When activating a module, the semodule command (part of the policycoreutils package) will copy those modules into a dedicated directory: /etc/selinux/targeted/modules/active/modules (RHEL) or /var/lib/selinux/mcs/active/modules (Gentoo). This location is defined by the version of the SELinux user space--more recent versions use the /var/lib location. When all modules are aggregated in a single location, the final policy binary is compiled, resulting in /etc/selinux/targeted/policy/policy.30 (or some other number) and loaded in memory.

On RHEL, the SELinux policies are provided by the selinux-policy-targeted (or -minimum or -mls) package. On Gentoo, they are provided by the various sec-policy/selinux-* packages (Gentoo uses separate packages for each module, reducing the number of SELinux policies that are loaded on an average system).

Bundling modules in a policy store

A policy store contains a single comprehensive policy, and only a single policy can be active on a system at any point in time. Administrators can switch policy stores, although this often requires the system to be rebooted and might even require relabeling the entire system (relabeling is the act of resetting the contexts on all files and resources available on that system).

The active policy on the system can be queried using sestatus (SELinux status, provided through the policycoreutils package), as follows:

    # sestatus | grep "Loaded policy name" 
    Loaded policy name:             targeted 

In this example, the currently loaded policy (store) is named targeted. The policy name that SELinux will use upon its next reboot is defined in the /etc/selinux/config configuration file as the SELINUXTYPE parameter.

It is the system's init system (be it a SysV-compatible init system or systemd) that is generally responsible for loading the SELinux policy, effectively activating SELinux support on the system. The init system reads the configuration, locates the policy store, and loads the policy file in memory. If the init system does not support this (in other words, it is not SELinux-aware) then the policy can be loaded through the load_policy command, part of the policycoreutils package.

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