Beyond SELinux: Enforcing Confidentiality and Integrity for Applications and Data
One question we frequently get is “Why would I use something like Titanium Technology Protection, instead of other Linux Security Modules (LSMs) like SELinux or AppArmor?”.
In short, there’s no reason you can’t use both.
SELinux and Titanium Technology Protection primarily differ in their threat model, concept of operations (CONOPS), and flexibility.
SELinux is the primary LSM used by RedHat-based Linux distributions including CentOS and Fedora whereas Ubuntu-based distributions primarily use AppArmor, generally to the same end goal. There are some philosophical, design, and technical differences between both of the previously mentioned LSMs. In relation to something like Titanium Technology Protection, we can consider them the same, so we’ll refer to them collectively as SELinux for the rest of this post.
Titanium Technology Protection is a suite of related capabilities, including an LSM and several overlay filesystems, which provide integrity and confidentiality for specific applications and use cases. It also provides a mechanism for enforcing full-system application and library whitelisting.
Before we dig into the similarities and differences, we need to highlight one important point. Namely that, in most cases, it isn’t necessary to make an either/or decision; with the advent of LSM stacking it is possible for SELinux and Titanium to coexist. In most situations, including kernel-based security definition and enforcement, it’s more beneficial to have security in-depth and multiple levels of protection/enforcement. In other words, capabilities such as SELinux and Titanium Technology Protection may coexist and be used together. SELinux and Titanium Technology Protection use similar mechanisms to address different threats to a system including its applications.
SELinux and Titanium Technology Protection both provide an LSM and provide the ability to enforce various levels of mandatory access control on the running system. In addition to the core LSM functionality, both solutions provide tooling and auditing to complement the core LSM.
A Brief Review of LSMs and seccomp
As we’ve previously covered in A Brief Tour of Linux Security Modules and seccomp, there are a wide variety of Linux Security Modules (both mainline in the Linux kernel and standalone) and security features with different use cases, threat vectors, and levels of security.
There has been limited support for LSM Stacking (i.e. using multiple LSMs concurrently on the same system) since December 2004, with kernel version 2.6.9. In the early days of LSM stacking, LSMs were divided into major and minor LSMs (largely dependent on the LSM’s design and/or use of opaque, binary data or “blobs” for internal bookkeeping and storage). The Linux kernel provides only a single pointer to this binary data effectively limiting the use of multiple LSMs to one major (i.e. user or owner of opaque, binary data) and one minor LSM (i.e. an LSM that does not make use of this binary data).
Over the years, the dependence on this binary data has been decreasing in an effort to better support more system-level use cases, including containerization. As of Kernel Version 5.5, where AppArmor was transitioned away from utilizing this binary data, most of the earlier distinctions between major and minor LSMs have vanished.
Fundamentally, an LSM provides a kernel-based mechanism to hook system calls (i.e. read, write, open, etc.). This enables LSMs to control access to key kernel data and make access control decisions on these system calls. This is different from seccomp, which can be used to restrict which system calls can be used by an application. Said differently, LSMs enable the kernel to decide how a system call can be used, whereas seccomp enables the kernel to restrict what system calls can be used.
LSM stacking enables these hooks to be chained, such that multiple LSMs can make access control decisions for each system control.
One of the finer and less obvious points of LSM stacking is that all LSMs must agree for a successful access control decision, and any LSM can reject the access control decision.
SELinux - A Primer
SELinux was originally intended to support multi-level security (MLS) requirements, and it has since been extended and used as a general-purpose access control mechanism. You can see SELinux’s roots in its use of “subjects” and “objects” in terms of access control mechanisms. Though rarely used, SELinux also provides provisions for accessing a central policy server.
As a general rule, SELinux assumes that there is always a privileged (i.e. root) user to establish, control and set policy. As a result, most of the controls enforced by SELinux are intended to prevent applications and/or data from becoming root, elevating system privileges, or accessing data they shouldn’t.
Using SELinux by itself, it is theoretically possible to achieve a configuration where the root user is partially or fully de-privileged. This would effectively enforce a static policy at runtime (similar to how Titanium Technology Protection enforces a static configuration), and not enable the root user to update or modify policies on a running system. In order to fully realize these policies, however, you would have to tweak SELinux’s design assumptions and likely switch to separate provisioning/production environments; you would no longer have a general-purpose solution as it would be difficult to enable this level of control on a common Linux distribution while having it apply universally to most services and operational use cases.
SELinux is both extremely powerful and complex, making it hard to configure and difficult to use. It’s not uncommon to require small teams to establish and maintain SELinux policy for a system or group of systems. As a result, most (Linux) distributions provide several general-purpose policies to cover many common scenarios. As an example, the targeted policy commonly used on RedHat-based systems provides a general-purpose configuration that isolates most services and daemons on the system.
The targeted policy provides contexts for system services (i.e. HTTP, DHCP, DNS, etc.). These (execution) contexts restrict the respective services to their configuration files, limit system capabilities, and prevent services like the webserver from accessing the system’s password file (e.g. /etc/passwd or /etc/shadow). These default policies provide a level of protection for standard functions of general-purpose Linux environments. However, they do very little to protect or address user-applications and non-default applications or services.
SELinux policy combines and makes use of several kernel interfaces including:
Linux Capabilities - Reduce capabilities for an application
NetLabel / secmark - Enable application-level socket and network firewalls
Linux capabilities provide a mechanism for applications and services to access and use protected interfaces without requiring root-level access. As an example, a web service may need to bind to port 80 or 443, which is a privileged service. Using the Linux capability CAP_NET_BIND_SERVICE, a web server could be granted (by an administrator) the ability to bind to privileged ports without needing to execute as root. The full list of capabilities provided by the Linux kernel can be found in capabilities.h.
While not explicitly stated, SELinux is primarily focused on preventing a user from becoming root, elevating privileges, and accessing data they shouldn’t.
For a variety of reasons, SELinux usually depends on extended attributes and POSIX acls in order to function. This has the side effect of limiting what filesystems can be used since not all filesystems support extended attributes and/or POSIX ACLs. As an example, NFS has not traditionally supported the use of SELinux. However, starting with RFC 8275 in 2017 and NFS version 4, there is now limited
support for extended attributes (including SELinux acls) in NFS. SELinux uses the extended attributes to store a context/label for the object, which is then verified at runtime. Reading into this a bit more, SELinux requires all objects (filesystem entries, sockets, IPCs, character and block devices, etc.) to have a label. SELinux provides several mechanisms to make the labeling process easier for an administrator. Some of these mechanisms include the ability to relabel (based on an external label/context database) a filesystem during boot/mount, setting a default label for the filesystem (i.e. as a filesystem option), and storing labels/context in a separate database (i.e. separate location on disk).
While not immediately obvious, most existing Linux utilities are aware of extended attributes and preserve them when objects are copied, moved, etc. Some utilities like tar may require explicit options to support preserving labels.
Various cyber security controls and secure technical implementation guides (STIG) require the use of SELinux. In these scenarios, SELinux is used to provide a base-level of protection for the underlying system. This is primarily achieved through the targeted policies and the assumption that most systems operate using known services or roles (i.e. web server, database server, file server, etc.). In this scenario, SELinux also provides a layer of protection from users (or services) becoming root and/or being able to pivot to a higher privilege execution context.
Titanium Technology Protection
Titanium Technology Protection’s threat model assumes root-level access to the system and effectively ignores user-level discretionary access controls (i.e. user, group, world). With that said, user-level DAC is still required for standard Linux operation. While Titanium Technology Protection provides an LSM that enforces mandatory access control policies, the LSM is generally useless without the Titanium Technology Protection overlay filesystems. Given the threat model of root-level access, Titanium Technology Protection enables static deployment configurations and inhibits the disabling, lessening, or removal of protections at runtime.
Unlike an LSM such as SELinux which operates largely independent of other system components, Titanium Technology Protection integrates an LSM, kernel configuration, multiple overlay filesystems, and secure boot functionality. This integration is used to address the threat model and provide holistic system-security. The Titanium Technology Protection components address a broad array of threat vectors and provide both confidentiality and integrity to user-developed applications, libraries, and data. The product is focused on providing technology protection and anti-tamper protections for user-developed applications and, as a result, enables an additional layer of protection on the larger system. While Titanium Technology Protection can be used on general Linux services (i.e. web server, DNS, etc.), it’s better suited to specific applications and use cases. More specifically, it is targeted at applications, libraries, and data that have explicit confidentiality and integrity requirements.
The Titanium Technology Protection LSM enforces two distinct levels of policy. The first level is implicit based on the system threat model and can not be modified by the user or system integrator. These implicit protections depend on the availability of the Titanium filesystems. The second level is user or system-integrator established policies and is used to provide core protections to user applications and data.
Similar to SELinux, Titanium Technology Protection denials are logged using AVC messages in the auditd subsystem.
Exploring Titanum Technology Protection
Kernel Configuration
The kernel configuration is similar to the Lockdown LSM in that it enforces various system-level constraints to reduce the overall attack surface. As a simple example, Titanium Technology Protection enables kernel module driver signing and limits where the public signing keys can be loaded from. This removes one possible attack vector (i.e. loading a malicious kernel module), and continues to enforce the separation of user and kernel space while helping to preserve the confidentiality and integrity of targeted applications, libraries, and data.
If you assume an attacker has root-level access, you can reason over what that enables an attacker to do and how that may compromise system integrity. Normally, root-level access would enable an attacker to load kernel modules, alter boot configuration (including the kernel command-line), load additional module driver signing keys, remount file systems, and more. Titanium Technology Protection’s kernel configuration and holistic approach to security addresses all of these threats.
Implicit MAC policies
Relative to Titanium Technology Protection’s transparent, overlay filesystems, several implicit restrictions are enforced by the LSM. It’s overlay filesystems are collectively called vaults.
FortiFS filesystems marked as executable (during provisioning) can not be written to at runtime. The LSM is used to prevent writing to an executable FortiFS vault, regardless of how the vault is actually mounted on the system.
Applications executed from an executable FortiFS vault require that any page mapped into the process with the execute page bit set (i.e. it contains executable code) must have come from an authenticated source. This restriction applies to applications and libraries, including system-level libraries. Titanium considers an authenticated source to be either a FortiFS or AuthFS vault.
Applications executed from an executable FortiFS vault can not be debugged or traced. This is enforced by the LSM.
Executable Whitelisting prevents executables and libraries from being used on the system unless they are backed by an authenticated source (i.e. FortiFS or AuthFS vaults).
Titanium Technology Protection’s implicit policy enforcement is intended to require system integrators and users to develop only explicit policies for their specific applications and data without forcing them to deploy policies for every component on the system.
Titanium Technology Protection Filesystems
Titanium Technology Protection provides two overlay filesystems that are collectively used in the application of MAC policies. The use of an overlay filesystem enables Titanium to support any Linux filesystem, including NFS and flash-based filesystems, as the backing store. This removes the dependence on extended attributes or POSIX acls, and is more conducive to the threat model of an attacker having root-level access.
FortiFS is an overlay filesystem that provides for both authentication and encryption of data (applications, libraries, configuration, data). FortiFS is the only Titanium filesystem that provides explicit policy development and enforcement. FortiFS provides protection of data at rest and enforcement of policy at runtime.
There are two types of FortiFS vaults that can be defined using the Titanium Policy Editor, executable and storage. Executable vaults enable several implicit restrictions at runtime related to how executables are handled. Additionally, executable vaults have the concept of incoming and outgoing policies, whereas storage vaults only support incoming policy requests.
Incoming restrictions primarily relate to how non-FortiFS vaults (i.e. the rest of the system) interact with a FortiFS vault. As a simple example, incoming restrictions can be used to prevent the rest of the system from reading the contents of a FortiFS vault. In the case of an executable, DAC policies for rx are still required, however, everything except for the ELF loader will be prevented from reading the application. This prevents applications and data from being read, debugged, or removed from the running system. The Titanium Technology Protection LSM will prevent any read or mmap of the protected vault, by unprotected applications. This prevents protected applications, libraries or data from being removed from the system, introspected, debugged, or analyzed.
Outgoing restrictions are only applicable to executable vaults and used to limit where protected applications can read and write. This enables you to define exactly where your application(s) can load configuration data, media, etc. from. The use of outgoing restrictions will also prohibit your application from reading or writing to other areas of the system. The outgoing restrictions are similar to those applied with the targeted SELinux policies.
AuthFS is an overlay filesystem that provides authentication of data (including applications and libraries). The primary use case of AuthFS is to enable system libraries to be used by applications running from a FortiFS vault. Additionally, AuthFS vaults provide the basis for executable whitelisting/allowlisting with Titanium Technology Protection. AuthFS vaults are generally mounted and accessed in place (i.e. the /lib64 authfs vault is mounted over itself at /lib64).
Summary
SELinux and Titanium Technology Protection have different threat and deployment models. It is often required by CONOPS that Titanium Technology Protection and SELinux are used concurrently, to address different aspects of system security. Titanium Technology Protection is mostly focused on providing confidentiality and integrity for specific applications, libraries, and data stores.
Titanium Technology Protection is best-suited for user-developed applications (vs. the full system), that require additional controls regarding confidentiality and integrity. It also provides a mechanism for enforcing executable whitelisting/allowlisting on systems with more static deployment considerations.
This blog is part of a multi-part series that explores various security features in-depth. Additional blogs in this series will address system-level security architectural concerns (i.e. combining all of the components we’ve covered) as well as exploring similarities and differences of IMA vs. AuthFS for whitelisting and application/library integrity.
Titanium Linux
GUIDELINES FOR SECURING COMBAT SYSTEMS
Star Lab’s Titanium Technology Protection offers the most robust Linux system hardening and security capabilities available on the market today for operationally-deployed Linux systems. Designed using a threat model that assumes an attacker will gain root (admin) access to your system, Titanium Technology Protection maintains the integrity and confidentiality of critical applications, data, and configurations while assuring operations. Titanium is compatible with RedHat,CentOS, Ubuntu, RedHawk, and other embedded Linux distributions.