Difference between revisions of "Linux capability-based security"
(→Scenario) |
m |
||
(2 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
+ | [[Category:Projects]] | ||
+ | |||
= Background = | = Background = | ||
Line 34: | Line 36: | ||
= Scenario = | = Scenario = | ||
− | Let's say you are running Ubuntu 10.04 and you have a user named andrew that needs to be able to run ifconfig commands in order to bring interfaces up and down. Historically the normal way to do this is somehow end up allowing andrew to run ifconfig as root, either with sudo or just setting the ifconfig executable setuid root. A much safer way to do this is to grant andrew the CAP_NET_ADMIN capability and set up the system to honor it. This way andrew never runs anything as root but he still gets to run his interface configuration commands. Here's how we do it: | + | Let's say you are running Ubuntu 10.04 and you have a user named andrew that needs to be able to run ifconfig commands in order to bring interfaces up and down. Historically the normal way to do this is somehow end up allowing andrew to run ifconfig as root, either with sudo or just setting the ifconfig executable setuid root. A much safer way to do this is to grant andrew the CAP_NET_ADMIN capability and set up the system to honor it. This way andrew never runs anything as root but he still gets to run his interface configuration commands. |
+ | |||
+ | The reason this is safer is because if there is ever an arbitrary code execution vulnerability discovered in the ifconfig program, the only thing andrew will be able to do is configure arbitrary network interfaces as he pleases. If he were running ifconfig via sudo or setuid root, he would instead be given root access and could do anything he wanted on the system. | ||
+ | |||
+ | Here's how we do it: | ||
== Granting the user the capabilities == | == Granting the user the capabilities == | ||
Line 72: | Line 78: | ||
* Change "auth optional pam_cap.so" in /etc/pam.d/common-auth to "auth required pam_cap.so". | * Change "auth optional pam_cap.so" in /etc/pam.d/common-auth to "auth required pam_cap.so". | ||
* Run "setcap cap_net_admin=ei /sbin/ifconfig". | * Run "setcap cap_net_admin=ei /sbin/ifconfig". | ||
+ | |||
+ | = References = | ||
+ | [http://www.linuxjournal.com/magazine/making-root-unprivileged?page=0,1 http://www.linuxjournal.com/magazine/making-root-unprivileged?page=0,1] |
Latest revision as of 16:04, 4 October 2017
Contents
Background
Capability-based security is basically the idea that instead of requiring a user be given root access to do certain tasks they need to do, they are instead given the capability to do those tasks without involving root at all. This can be built in to any modern Linux kernel (since kernel 2.2) and is the preferred method of giving normal users the ability to perform tasks that have historically required sudo or setuid root. The problem with setuid root and sudo is that this can lead to privilege escalation and the execution of arbitrary commands as the root user if it is not done carefully (and sometimes even when it is).
List of capabilities in Linux
Here's some of the most useful capabilities in Linux:
CAP_CHOWN | Make arbitrary changes to file UIDs and GIDs. |
CAP_NET_ADMIN | Perform various network-related operations. |
CAP_NET_BIND_SERVICE | Bind a socket to Internet domain privileged ports (port numbers less than 1024). |
CAP_NET_RAW | Use RAW and PACKET sockets. |
CAP_SYS_MODULE | Load and unload kernel modules. |
CAP_KILL | Bypass permission checks for sending signals. |
CAP_DAC_OVERRIDE | Bypass file read, write, and execute permission checks. |
An exhaustive list can be found at http://kernel.org/doc/man-pages/online/pages/man7/capabilities.7.html.
Scenario
Let's say you are running Ubuntu 10.04 and you have a user named andrew that needs to be able to run ifconfig commands in order to bring interfaces up and down. Historically the normal way to do this is somehow end up allowing andrew to run ifconfig as root, either with sudo or just setting the ifconfig executable setuid root. A much safer way to do this is to grant andrew the CAP_NET_ADMIN capability and set up the system to honor it. This way andrew never runs anything as root but he still gets to run his interface configuration commands.
The reason this is safer is because if there is ever an arbitrary code execution vulnerability discovered in the ifconfig program, the only thing andrew will be able to do is configure arbitrary network interfaces as he pleases. If he were running ifconfig via sudo or setuid root, he would instead be given root access and could do anything he wanted on the system.
Here's how we do it:
Granting the user the capabilities
First we have to grant andrew the cap_net_admin capability by adding this line to /etc/security/capabilities.conf:
cap_net_admin andrew
Note that this cannot be added at the end of the file, it must appear before the "none *" line or this won't work.
Configuring the system to grant capabilities on authentication
Now that we've given andrew the cap_net_admin capabilities we should make sure our system is set up to grant those abilities when andrew gets authenticated, so we edit /etc/pam.d/common-auth and make sure the line
auth required pam_cap.so
is in there somewhere. On a default ubuntu install this will say optional instead of required, find that line and change it to required.
Adding the capability flag to the executable
Finally we have to add the cap_net_admin capability flag to the ifconfig executable, like so:
setcap cap_net_admin=ei /sbin/ifconfig
This adds the cap_net_admin capability to the effective and inheritable sets of the ifconfig executable. Effective means it is enabled and inheritable means any program ifconfig calls will also have this capability.
Once all that is done and we re-log in as andrew, this user can now run the ifconfig command and change network configuration without having to sudo to root.
TL;DR
- Add "cap_net_admin andrew" to /etc/security/capabilites.conf before the "none *" line.
- Change "auth optional pam_cap.so" in /etc/pam.d/common-auth to "auth required pam_cap.so".
- Run "setcap cap_net_admin=ei /sbin/ifconfig".
References
http://www.linuxjournal.com/magazine/making-root-unprivileged?page=0,1