Capabilities
A Helpless Ping
Enough theory for now – let's go play. As a systems administrator, you are mostly concerned with file capabilities. These are also the most natural way to assign thread capabilities: The kernel does this for you during an execve(2)
call, following the rules above. In fact, there are only so many ways to change thread capabilities beyond this, even if you are a developer.
Two tools help us here. setcap sets file capabilities, while getcap reads them back. This is pretty simple. However, capabilities are somewhat convoluted, and so is the syntax of these tools.
setcap and getcap come via the libcap-something package and are likely already installed on your system, even if it doesn't use capabilities. Among distributions I have on my boxes, Fedora and Arch Linux employ capabilities while Ubuntu doesn't. Yet most distribution kernels now come with capabilities support enabled, so nothing prevents you from "deploying" capabilities on your own.
Consider a simple experiment (Figure 3). I open a terminal on my Kubuntu 16.04 LTS box and type:
$ ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.095 ms
Of course, it works. ping is setuid-root binary, so it has no troubles opening raw network sockets:
$ ls -l /bin/ping -rwsr-xr-x 1 root root 44168 May 8 2014 /bin/ping
Now, I do the following:
$ sudo setcap cap_net_raw-pe /bin/ping
Note that this requires root, as changing file capabilities is obviously a privileged operation. The CAP_SET_FCAP
capability controls who can do it, but as Ubuntu doesn't use capabilities system-wide, the most straightforward way to get CAP_SET_FCAP
in the thread effective set is sudo. Now, ping becomes hopelessly useless, even if it's still setuid-root:
$ ping 127.0.0.1 ping: icmp open socket: Operation not permitted
What's happened here? I've withdrawn CAP_NET_RAW
from the permitted file capabilities and effective capabilities set. The latter is a single bit on file level, so if you tell setcap to change effective capabilities, both permitted and inheritable are adjusted accordingly. A companion getcap tool will now show file capabilities as empty (Figure 1 again), but it's not the same as no capabilities at all.
Mixing capabilities with setuid/setgid bits isn't a good idea, and you can watch the kernel complaining about it in the logs:
$ dmesg | tail [39034.641585] warning: `/bin/ping' has both setuid-root and effective capabilities. Therefore not raising all capabilities
You only get a single instance of this warning regardless of how many times you execute the command. Note, however, that the root user still has all capabilities assigned, even if we've removed one from the file set:
$ sudo ping 127.0.0.1 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.095 ms
The comments in the kernel says it is done "just to cause the least surprise to an admin."
So, how do you make ping
operable again? There are two options. The first option is to grant the ping
command the capability you previously revoked:
$ setcap cap_net_raw+ep /bin/ping
Now, getcap shows it really worked as expected:
sudo getcap /bin/ping /bin/ping = cap_net_raw+ep
The second option is to rip /bin/ping
off file capabilities, just as it was before this experiment. setcap -r /bin/ping
does just this.
Now you may be wondering what these "cap_net_raw+ep" things are all about. This syntax comes from the cap_from_text(3)
function, which is a part of the libcap library (not to be confused with libpcap). Each expression starts with a case-insensitive capability name (or "all"), which is followed by a so-called action list. Each action is a combination of the operator (=
, +
, or -
) and a flag (e
, p
, i
for effective, permitted, and inheritable capabilities, respectively). The =
operator resets the capability in all three sets, whereas two others raise or lower it in a set denoted by the flag. So, cap_net_raw=
would also do the trick in our experiment, and cap_net_raw=+i
resets the capability in the permitted and effective set while raising it in the inheritable one. You can find further details in the cap_from_text(3)
man page [5].
Command of the Month: chattr
Capabilities are all about making root a less powerful user. However, there are other ways to limit what root can do on a Linux system.
You probably know how to write-protect a file. Do chmod ogu-w foo, and no one will be able to write to it. Do the same for the containing directory, and no one will be able to remove the file. Well, except the root user, obviously.
Is there a way to really write-protect a file? Yes, and it comes through a file-attributes mechanism. This mechanism is similar to capabilities in the sense that it's always there, but few people seem to know or care about it. Yet, it makes tricky things possible (Figure 4). Do you want a file you can only append, not overwrite?
$ sudo chattr +a foo $ echo bar >foo bash: foo: Operation not permitted $ echo baz >>foo $ cat foo baz
In a similar fashion, you can make a file immutable with chattr +i. Immutable files can't be modified or deleted, and it's impossible to create links to them. This is true even for the root user:
$ sudo chattr +i foo $ sudo rm foo rm: cannot remove 'foo': Operation not permitted
Of course, root or anyone else with CAP_LINUX_IMMUTABLE can remove these attributes with chattr -a and chattr -i, but they are still great to guard against accidental modifications.
Infos
- Linux capabilities list: http://lxr.free-electrons.com/source/include/uapi/linux/capability.h
- capabilities(7) man page: http://man7.org/linux/man-pages/man7/capabilities.7.html
- "Core Technology: Extended Attributes & POSIX ACLs" by V. Sinitsyn. Linux Voice, Issue 30 (September 2016), pp. 94-97.
cap_bprm_set_creds()
kernel function: http://lxr.free-electrons.com/source/security/commoncap.c#L492- cap_from_text(3) man page: https://linux.die.net/man/3/cap_from_text
- Valentine Sinitsyn develops high-loaded services and teaches students completely unrelated subjects. He also has a KDE developer account that he's never really used.
« Previous 1 2
Buy this article as PDF
(incl. VAT)