Linux capabilities are special attributes in the Linux kernel that grant processes and binary executables specific privileges that are normally reserved for processes whose effective user ID is 0 (The root user, and only the root user, has UID 0).
This article will explain some of the available capabilities, their uses and how to set and remove them. Please note that setting capabilities on executables has the potential to compromise the security of your system. As such, you should consider testing on a non-production system before implementing capabilities in production.
Essentially, the goal of capabilities is to divide the power of 'root' into specific privileges, so that if a process or binary that has one or more capability is exploited, the potential damage is limited when compared to the same process running as root.
Capabilities can be set on processes and executable files. A process resulting from the execution of a file can gain the capabilities of that file.
The capabilities implemented on Linux are numerous, and many have been added since their original release. Some of them are as follows:
CAP_CHOWN: Make changes to the User ID and Group ID of files
CAP_DAC_OVERRIDE: Override DAC (Discretionary Access Control). For example, vto bypass read/write/execute permission checks.
CAP_KILL: Bypass permission checks for sending signals to processes.
CAP_SYS_NICE: Raise the niceness of processes (An explanation of niceness can be found here)
CAP_SYS_TIME: Set the system and real-time hardware clock
For the full list, run
man 7 capabilities.
Capabilities are assigned in sets, namely "permitted", "inheritable", "effective" and "ambient" for threads, and "permitted", "inheritable" and "effective" for files. These sets define different complex behaviors, their full explanation is beyond the scope of this article.
When setting capabilities on file, we will almost always use "permitted" and "effective", for example
CAP_DAC_OVERRIDE+ep. Notice the
+ep, which denotes the aforementioned sets.
There are two main tools,
setcap which can respectively view and set these attributes.
On Debian and Ubuntu, these tools are provided by the
libcap2-bin package, which can be installed with:
apt install libcap2-bin
On CentOS and Fedora, the
libcap package is needed:
yum install libcap
On Arch Linux, they are provided by
libcap as well:
pacman -S libcap
To view if a file has any capability set, you can simply run
getcap /full/path/to/binary, for example:
root@demo:~# getcap /usr/bin/ping /usr/bin/ping = cap_net_raw+ep root@demo:~# getcap /usr/bin/rcp /usr/bin/rcp = cap_net_bind_service+ep
If you'd like to find out which capabilities are already set on your system, you can search your whole file-system recursively with the following command:
getcap -r /
Due to the fact that virtual file-systems (such as
/proc) do not support these operations, the command above will produce thousands of errors, so for a cleaner output use the following:
getcap -r / 2>/dev/null
To set a particular capability on a file, use
setcap "capability_string" /path/to/file.
To remove all capabilities from a file, use
setcap -r /path/to/file.
For demonstration we'll create a blank file in the current directory, give it a capability, and remove it. Start with the following:
root@demo:~# touch testfile root@demo:~# getcap testfile
The second command produces no output, meaning this file does not have any capability.
Next, set a capability for the file:
root@demo:~# setcap "CAP_CHOWN+ep" testfile root@demo:~# getcap testfile testfile = cap_chown+ep
"CAP_CHOWN+ep" was used as an example, but any other can be assigned in this manner.
Now, remove all capabilities from
root@demo:~# setcap -r testfile root@demo:~# getcap testfile
Again, there will be no output, because "CAP_CHOWN+ep" was removed.
Capabilities have many potential uses and can help to tighten the security of your systems. If you use the SUID bit on your executables, consider replacing it with the specific capability needed.