Unix Capabilities: A More Granular Approach To Privileges

What are Capabilities and Why Do We Need Them?

The traditional Unix security model grants full privileged access to the root user. This “all or nothing” approach means that any program running as root or setuid root can access all files and perform any system modification. However, many programs do not need full root access to function properly.

Capabilities split privileges into discrete units that can be independently granted to running programs. This allows for precision control over what level of access a particular executable requires. Instead of acting as root, programs can run with a subset of root’s privileges granted only as needed.

The Problem of “All or Nothing” Root Permissions

Granting full root privileges provides any piece of software extreme amounts of access and control over the system. This access exceeds requirements for most regular programs. When an vulnerability is exploited, attackers instantly gain the full authority over the environment.

Additionally, all processes interacting with the software now must have elevated privileges themselves and inherit increased risks as collateral damage. Having a single point of failure with system-level consequences violates the principles of least privilege and separation of privilege in computer security.

Capabilities as a Solution for Fine-Grained Privilege Control

Capabilities divide up the permissions typically only available to the root account into logical groups of related privileges. This allows assigning only the bare minimum set of capabilities a program needs to function. So rather than acting as root, processes can have granular privileges matching their requirements.

The capability mechanism allows for delegating only the necessary authority to processes. This greatly reduces the blast radius from potential vulnerabilities by limiting any exploitation to precisely what is accessible within the capability set assigned.

Capability Sets – The Building Blocks

Definition and Overview of Capability Sets

At the core of capabilities are distinct sets that each map to specific privileged operations. The full set of capabilities covers all the powers typically accessible through root or setuid root programs. Each capability set can be independently enabled or disabled for running processes.

There are over 35 defined capabilities grouped roughly into categories such as process/user interactions, system administration access, network usage, device handling, resource limits, and more. Capabilities can be granted individually or combined together based on an executable’s particular needs.

Mapping Between Privileges and Capability Sets

Traditionally privileged operations map to requiring a capability set to allow its usage. This includes actions like binding to lower network ports, loading kernel modules, raw access to devices, mounting filesystems, task prioritization, adjusting resource limits, impersonating users, altering system time, and many more.

So rather than providing full access and control over the system, capabilities allow only enabling exactly what features a program legitimately requires. All other privileged aspects remain blocked off with no permissions granted.

Example Capability Sets

CAP_CHOWN – Allows arbitrary changing of file user and group ownership. This allows overriding system restrictions on who may alter ownership of objects.

CAP_NET_BIND_SERVICE – Permits binding to TCP/UDP sockets below 1024. This is typically reserved for establishing listening connections on privileged ports.

CAP_SYS_TIME – Provides direct access to adjusting the system clock and real-time clock. This overrides system protections on the system time.

Managing Capabilities

Viewing Capabilities of a Process

The capabilities sets assigned to a currently running process can be viewed through the /proc file system. Specifically the /proc/[pid]/status file details the Activatable, Permitted, Effective, and Inheritable capability sets available to a process.

This allows inspecting what capabilities a particular process has access to either independently or inherited from its parent process. These capability sets dictate what enhanced privileged operations are available.

Adding/Dropping Capabilities with capsh

The capsh program allows manually setting capabilities on a running process. After targeting a specific program, capabilities can be added or dropped as desired to grant or restrict access.

This allows initially launching a program with no capabilities, then opening up minimal specific capabilities only as needed for functionality. Granular capabilities can be deliberately assigned rather than just inheriting default sets.

Setting Capabilities on Executables

Capabilities can also be configured directly on program executables themselves by using the setcap command. This permanently assigns capability sets that apply every time that executable launches.

By adding capabilities only to programs that explicitly need elevated permissions, all other processes run by default in an unprivileged restricted state. This prevents inherited capabilities granting unexpected access between software components.

Use Cases and Practical Examples

Running an HTTP Server as Non-Root

A common scenario is needing to open a listening socket on one of the lower numbered privileged ports in order to run an HTTP server process. Typically this requires the executable to run with root privileges in order to bind port 80 or 443.

With capabilities, only the CAP_NET_BIND_SERVICE set is required rather than full root access. This allows the HTTP server software to bind the ports it requires but retains no other elevated permissions for potential exploitation.

Allowing Ping But Restricting Network Access

System administrators often want a host to respond to ping requests over ICMP for monitoring, but wish to block other network access for security. Capabilities can provide this functionality without needing dedicated firewall rules.

By granting the CAP_NET_RAW capability while restricting CAP_NET_ADMIN, processes can send ping replies but cannot open regular TCP/UDP sockets for connectivity. This achieves the desired responses for monitoring tools without permitting general network communications.

Implementing Least Privilege for Container Workloads

Container platforms use capabilities to enforce least privilege principles by avoiding running images as root by default. Containers only hold capabilities truly required for their expected functionality through purpose-built images.

Both Docker and Podman leverage capabilities to run containers with minimal privileges set only as necessary. Kubernetes also incorporated capabilities to automate dropping unneeded elevated access across container deployments at scale.

Alternatives and Tradeoffs

SELinux, AppArmor, and other MAC Systems

Other mandatory access control (MAC) systems also aim to increase security by limiting process access and resources. Capabilities provide fine-grained privileges, while MACs impose restrictions on broader information flow between objects and subjects.

SELinux and AppArmor allow setting policies to protect sensitive files, network usage, raw hardware access, and other operations. Capabilities can provide lower-level process authorities below these controls.

Overhead and Complexity Considerations

Capabilities add additional complexity when configuring programs and environments by requiring administrators learn the available sets and map their privileges accordingly. Capability use also increases a bit of run-time overhead during syscall checks.

However, capabilities shine by enabling far more security hardening and least privilege access benefits compared to marginal additional resource tradeoffs modern hardware can easily sustain.

Summary – Capabilities for More Secure and Flexible Systems

Capabilities enable precision privilege management instead of an all-or-nothing superuser model. Granular capabilities allow processes to hold only bare essential access explicitly needed for functionality and data, rather than blank check authority inherited from root.

Capabilities transform unix security by opening implementations aligned with least privilege principles for far stronger system integrity and attack resistance.

Leave a Reply

Your email address will not be published. Required fields are marked *