Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
SELinux System Administration, Third Edition

You're reading from   SELinux System Administration, Third Edition Implement mandatory access control to secure applications, users, and information flows on Linux

Arrow left icon
Product type Paperback
Published in Dec 2020
Publisher Packt
ISBN-13 9781800201477
Length 458 pages
Edition 3rd 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 (22) Chapters Close

Preface 1. Section 1: Using SELinux
2. Chapter 1: Fundamental SELinux Concepts FREE CHAPTER 3. Chapter 2: Understanding SELinux Decisions and Logging 4. Chapter 3: Managing User Logins 5. Chapter 4: Using File Contexts and Process Domains 6. Chapter 5: Controlling Network Communications 7. Chapter 6: Configuring SELinux through Infrastructure-as-Code Orchestration 8. Section 2: SELinux-Aware Platforms
9. Chapter 7: Configuring Application-Specific SELinux Controls 10. Chapter 8: SEPostgreSQL – Extending PostgreSQL with SELinux 11. Chapter 9: Secure Virtualization 12. Chapter 10: Using Xen Security Modules with FLASK 13. Chapter 11: Enhancing the Security of Containerized Workloads 14. Section 3: Policy Management
15. Chapter 12: Tuning SELinux Policies 16. Chapter 13: Analyzing Policy Behavior 17. Chapter 14: Dealing with New Applications 18. Chapter 15: Using the Reference Policy 19. Chapter 16: Developing Policies with SELinux CIL 20. Assessments 21. Other Books You May Enjoy

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 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.

Important note

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

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

Figure 1.3 – Relationship between policy rules (code), policy modules, and policy store

Figure 1.3 – Relationship between policy rules (code), policy modules, and policy store

As we can see, policies are first written, then compiled in modules, after which they are bundled and distributed. The next few sections describe each of these phases in detail.

Writing SELinux policies

An SELinux policy writer can 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, which 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/SELinuxProject/refpolicy/), 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 ensure no rules are brought into the project that might jeopardize the security of any platform. Writing policies without the extensive set of M4 macros offered by the reference policy project is hard, which is why the reference policy has become the de facto source for policies.

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

To show the differences between these three languages, 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, we write this 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 the CIL language, the rule expression is like so:

(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.
  • A .if file, which contains interface and template definitions, allowing policy writers to easily use the newly-generated policy rules to enhance other policies. You can compare this to header files in other programming languages.
  • A .fc file, which contains file context expressions. These are rules that assign labels to resources on the filesystem.

A finished policy is then packaged into an 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 following diagram shows the building of policy modules. It also shows where CIL comes into play, even when the policy rules themselves are not written in CIL:

Figure 1.4 – Build process from policy rule to policy store

Figure 1.4 – Build process from policy rule to policy store

The binary *.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 (which in previous SELinux versions were the binary blobs loaded in memory) as high-level allows the SELinux project to introduce the distinction between high-level languages and CIL in a backward-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 will copy those modules into a dedicated directory (/var/lib/selinux/mcs/active/modules). When all modules are aggregated in a single location, the final policy binary is compiled, resulting in /etc/selinux/targeted/policy/policy.32 (or some other number) and loaded in memory.

On CentOS, 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 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 rebooting the system 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 (an SELinux status) as follows:

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

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

The system's init system (be it a SysV-compatible init system or systemd) 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 should be loaded through the load_policy command.

As we now have a better view of the flow used in policy development and distribution, let's see how Linux distributions can differentiate their SELinux offering.

You have been reading a chapter from
SELinux System Administration, Third Edition - Third Edition
Published in: Dec 2020
Publisher: Packt
ISBN-13: 9781800201477
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
Banner background image