Linux Capabilities 101
Linux Capabilities 101
Tutorial about how capabilities work in Linux
Even seasoned Linux administrators may not see capabilities a lot in their daily duties, but they are still used all the time. This features was added to Linux 2.2 and gave us new possibilities regarding security. In this guide we have an in-depth look on how can leverage them to increase security.
It is good to know why capabilities were implemented at the first place. Let’s assume we are running a process as a normal user (=non-privileged). At some point of time our process needs a little bit more permissions to fulfill its duties, like opening a network socket once. The problem is that normal users can not open a socket, as this require root permissions. So now we are stuck with a tool having only limited functionality.
One of the solutions is to allow some permissions (by default) to all users. There is however a serious flaw in this approach. Allowing these kind of permissions, for all users, would open up the system for a flood of system abuse. The reason is that every small opportunity is being used for good, but also for bad. Giving away too much privileges by default will result in unauthorized changes of data, backdoors and circumventing access controls, just to name a few.
So the kernel developers had to come up with another solution and they named it “capabilities”.
Capabilities can be compared with privileges. Normally the root user (or any ID with uid of 0) gets an exceptional treatment when running processes. The kernel and applications are usually programmed to skip the restriction of some activities when seeing this user ID. In other words, this user is allowed to do (almost) anything.
Capabilities are created to drop (some) permissions of root
With capabilities we have the access to distinct small units with specific rights. This way we don’t have to hand out full root permissions to some processes.
For example a web server normally runs at port 80. To start listening on one of the lower ports (<1024), you need root permissions. Now this web server daemon needs to be able to listen to port 80, however it does not need access to kernel modules (that would be a serious threat to the integrity of the system!). Instead of giving this daemon all root permissions, we can set a capability on the relate binary, like CAP_NET_BIND_SERVICE. With this specific capability it can open up port 80 (and 443 for HTTPS) and listen to it, like intended.
“Capabilities is a way of splitting up root permissions”
Binaries with setuid bit
Capabilities are a great way to replace binaries with the setuid bit set. This special bit gives users full root permissions under the context of that process. As you can imagine, if the program contains a flaw, the non-privileged user can “break out” and become the equivalent of the root user.
Still many Linux distributions use the setuid on several binaries, while capabilities can replace the bit.
Capabilities are a great way to split up root permissions and hand out some permissions to non-privileged users. Unfortunately still many binaries have the setuid bit set, while they should be replaced with capabilities instead.
Related article: Linux Capabilities: Hardening Linux binaries by removing setuid