In this lesson, you will learn how to transition away from full root privileges by assigning only the specific POSIX capabilities a service needs to function, directly within your systemd unit files.
The Problem with "All-or-Nothing" Root
Traditionally, system services often ran as the root user, granting them every possible privilege on the system. This violates the principle of least privilege: if a service is compromised, the attacker inherits the ability to do anything, from loading kernel modules to shutting down the network. POSIX capabilities break the monolithic "root" power into smaller, discrete chunks (like CAP_NET_BIND_SERVICE for binding to ports below 1024 or CAP_SYS_CHROOT for changing root directories).
Applying Capabilities via Systemd
Instead of managing these at the binary level using setcap, you can define these requirements declaratively in your service unit files. This is cleaner, audit-friendly, and ensures the service starts with exactly what it needs and nothing more.
To apply this, you use the CapabilityBoundingSet directive. Here is a simple example for a web service that only needs to bind to a low-numbered port:
[Service]
# Drop all capabilities first
CapabilityBoundingSet=
# Add back only the specific capability required
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
# Run as a non-privileged user
User=webuser
By setting CapabilityBoundingSet= (empty), you start from a clean slate where the process has zero privileges. You then explicitly add only the required capability. If the process is compromised, the attacker cannot perform other administrative tasks because the kernel will block any attempt to use a capability not in that set.
This approach integrates perfectly with your existing workflow of hardening system services. It acts as an effective firewall for your process's interaction with the kernel, ensuring that even if an application has a vulnerability, its blast radius is strictly limited to the specific tasks it is authorized to perform.
Key Takeaway: Use CapabilityBoundingSet in your systemd service files to explicitly whitelist only the POSIX capabilities your service requires, effectively preventing a compromised process from gaining full system control.