POSIX Capabilities & File POSIX Capabilities

来源:互联网 发布:博奥软件多少钱 编辑:程序博客网 时间:2024/05/16 17:44

http://www.friedhoff.org/posixfilecaps.html

+++++++++++++++++++++++++++++++++++++++++++

POSIX Capabilities & File POSIX Capabilities

!!! I'm about to rewrite this page. Hence I haven't finished so, the old page is still availablehere. !!!


With the inclusion of File POSIX Capabilities in Kernel 2.6.24 has Linux finally reached a stage, where POSIX Capabilities are usable and useful. Although POSIX Capabilities arrived at Kernel 2.2, the File part waited up to 2.6.24 to make its appearance. Now Linux is closing its gap to other systems in regards of POSIX Capabilities.
Well, from far above, thats true and even closer its not wrong. But there were plans and patches for file support of PCaps for 2.3. Later different patches were also available. Due to a bug called the sendmail bug, they hadn't had enough support. And further an open question was, where actually store the File POSIX Capabilities.
Now the dark age is over and the bright future of POSIX Capabilities in Linux is awaiting us.POSIX Capabilities are Privileges. They are called POSIX Capabilities because the POSIX document 1003.1e describes the idea of having a system of privileges - called capabilities -, which are taken into account in the decision of granting a process access to certain actions. As Capabilities are something different - a subject-object-right relationship - these privileges following the idea of the POSIX document 1003.1e are dubbed for Linux POSIX Capabilities.
Practically speaking, the sum of all POSIX Capabilities forms the Root power or the other way around the root power is split up in discrete privileges - POSIX Capabilities.
POSIX Capabilities break with the root model. The everything or nothing principle in regards of privileges is not necessary and not justified. Neither is it adequate to give a program the whole power of root to just open a socket (-> ping) nor to give the user with the back up role this whole power, when he or his tools shall only read all files of all user to back them up. Depending of the set-up, a program itself might hold the necessary privilege to fulfill his task. Not the user credentials are decisive, but the programs privileges are now. The idea of ACLs is in the same POSIX document developed. Combining the shift of granting privileges from users to programs with access control to these programs opens new possibilities in creating privilege distribution models and role models.
The technique of Inheritance opens for the POSIX Capabilities infrastructure further fascinating solutions. Granting users and applications PCaps in a form, where only the adequate user-application PCaps combination results in actually effective privileges.
  • Types of usage of POSIX Capabilities - Substitution of suid-0 privilege with POSIX Capabilities privilege
  • Types of usage of POSIX Capabilities - Server running as a distinct unprivileged user
  • Types of usage of POSIX Capabilities - Different privilege levels for different user rolls
  • Types of usage of POSIX Capabilities - On the code level application inside
  • POSIX Capabilities - Capability Flag, Set and State
  • POSIX Capabilities - Permitted Flag, Permitted Set
  • POSIX Capabilities - Effective Flag, Effective Set
  • POSIX Capabilities - Inheritable Flag, Inheritable Set
  • POSIX Capabilities - Capability Rules
  • Motivation
  • HowTo - Requirements - Check your system
  • HowTo - Kernelspace - Compile and Install
  • HowTo - Userspace - Compile and Install
  • HowTo - Configuring and Using PCaps
  • HowTo - Detection of needed capabilities - Intro
  • HowTo - Detection of needed capabilities - strace
  • HowTo - Detection of needed capabilities - capable_probe module
  • HowTo - Removing capabilities
  • File system operations - updating distro packages
  • File system operations - mv and cp (coreutils)
  • File system operations - Back up and restore with tar
  • File system operations - back up and restore with rsync
  • Examples - Substitution of suid-0 privilege with POSIX Capabilities privilege
  • Examples - Server running as a distinct unprivileged user - Apache
  • Examples - Server running as a distinct unprivileged user - Bind
  • Examples - Server running as a distinct unprivileged user - Cupsd
  • Examples - Server running as a distinct unprivileged user - DHCPD
  • Examples - Server running as a distinct unprivileged user - SAMBA
  • Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - Intro
  • Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - Installing the bits
  • Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - Exploring Inheritance
  • Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - SUID-BIT 0 reloaded
  • Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - Convenience
  • Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - Different Administration Rolls
  • Lectures, Talks and Presentations
 Types of usage of POSIX Capabilities - Substitution of suid-0 privilege with POSIX Capabilities privilegeA program runs in the privilege context of the user, who has started the process. For some tasks the privilege level of the user is insufficient to achieve the task. To solve this limit, it is possible to run an program in the context of the file owner, which is signified by the suid-bit. Hence referring to the privilege level there are only two user types, the super user aka root and the unprivileged user, the file owner is to overcome the lack-of-privilege-problem obviously root. Resolving the lack of privilege problem by using suid-bit technique results therefore in processes running in the right context and on the power level of root.

A famous example is /usr/bin/passwd which changes the password depending on your configuration in /etc/passwd or /etc/shadow. Whereas world is allowed to read /etc/passwd only user root is allowed to change /etc/passwd or /etc/shadow. To offer nevertheless the unprivileged user the possibility of changing his password, he has to start an application with the required privilege. Because his credential is insufficient the suid bit offers the way to use the credential of the file owner aka root. The file ownership of root in combination with the suid bit and the right to execute this file for the group owner or even world makes it possible for members of the mentioned group or even world to perform an action, where the own level of privileges is not adequate.

The idea of joining the necessary privilege to perform successful a certain action with the executable to call instead of deriving the privileges from the calling user, the idea of the suid bit, is one way of using POSIX Capabilities. The difference is, root is equivalent to granting all for the system available PCaps, whereas with PCaps you can grant just the minimal necessary privileges. Substituting the suid bit root technique with PCaps follows the 'principle of least privilege'.

More technically speaking, a further difference is, that the suid-bit-root privilege handling derives its privileges from the user root, again a user-privileges combination. Where the real user stays the calling unprivileged user, the effective user of the resulting process changes to root.
With PCaps, the through PCaps granted privileges to the binary are connected directly to the binary and in executing the binary the real and effective user don't change.

In the examples section, you will find different suid-0 binaries with their respective PCaps.top  Types of usage of POSIX Capabilities - Server running as a distinct unprivileged userServer in the sense of software are started either by in the root context running programs or have to be started as root. They are running in the privilege level of root because they are requesting or performing action for which special privileges are necessary. Because with PCaps it is possible to grant individual privileges to binaries, there is no need to give a server process the full set of privileges through running in the root context.
A conceivable server occupies a privilege port, accesses its configuration files and writes log data. We create a user and group solely reserved to this server. We change user and group ownership of the file the server has to write to, his log files, to his user and group. We grant this server the privilege to open privilege ports. We start this server in the context of his user and group. Now we have a server, running as a distinct but unprivileged user, which has just the needed minimal privileges and still protected from other user. If this server goes wild, all the server can do now is in the limit of his granted privileges to his binary, here opening privileges port, and further in the limit of his unprivileged user, for example changing his file. Getting the root level of privileges is through problems in the server software not possible anymore.top  Types of usage of POSIX Capabilities - Different privilege levels for different user rollsThe everything or nothing of the privilege root model can be substituted. Now we can grant users certain privileges, which are only becoming effective with binaries, which are expect to be called by a process, and a logged in user is system intern one or more processes, who has also this privileges. The sets of PCaps of the calling process and the called binary have to match to be effective. Effective in the sense that only by matching the PCap will be granted the Permitted (p) Flag.
A PAM based login process grants according to the configuration a user a set of POSIX Capabilities to his Inheritance Set. Now this user can start a process of which the corresponding binary expect through his Inheritance Set to be called by a process with the same POSIX Capabilities in his Inheritance Set. Unprivileged user, without the required PCaps in their Inheritance Set, won't be able to start the binary successful. The resulting process will lack the needed privileges and because of this will bail out or fail.
Applicable is this concept in two directions. Granting additional privileges to user and preparing the corresponding applications will enables this user to call and execute that application successful. Imaginable are back up roles in combination with back up tools, the user is allowed to cross ownership limits for reading files, or time changing roles, module loading roles or network interface configuration roles.
The other direction looks at former suid-0 binaries. Not enabling them for every user but only for adequate empowered user, results in user roles without these privilege. This users will not even allowed to call and execute programs, which are today through suid-0 accessible.top  Types of usage of POSIX Capabilities - On the code level application insideThe easiest way of handling privileges is ignoring them. Just execute. If the level of privilege is not sufficient, the system gives a permission denied. By checking the return code, the program is more friendly in stopping instead remaining in an undefined state.
Checking for being called as root, if the program needs privileges is another way. If not executed as root exit with an error message.
Using PCaps without relying on granted PCaps means expecting to be started as root, decreasing into an unprivileged user and keeping the PCaps, that are necessary.
PCaps aware means checking on program start for the needed PCaps in the Permitted Set and clearing the Effective Sate. Setting needed PCaps around the adequate code Effective and leave them otherwise only in the Permitted Set. Further remove PCaps from the Permitted Set if not needed anymore.top  POSIX Capabilities - Capability Flag, Set and StateThe Capability Flag is a per-capability attribute. The Capability Flags are named Permitted (p), Effective (e) and Inheritable (i). These flags apply to each capability separately.
All POSIX Capabilities, which have a certain Flag form the respective Set. So there exists the Permitted (P), Effective (E) and Inheritable (I) Set.
All POSIX Capabilities with all their Flags form the POSIX Capability State. The POSIX Capability State contains therefor all three Sets (obviously).top  POSIX Capabilities - Permitted Flag, Permitted SetThe Permitted Flag (p) marks a PCap as available. The Permitted Set (P) is the sum of all PCaps with the Permitted Flag.

The File Permitted Set (fP) forces the PCap into the Permitted Set of the resulting process. The File Permitted Set is also called the Forced Set.

The Permitted Set of a process, the Process Permitted Set (pP), contains all PCaps a process can use. The Process Permitted Set marks also the maximum set of all usable PCaps for a process. For processes only PCaps in the Permitted Set may have the Effective and / or Inheritable Flag rsp be part of the Effective Set and / or Inheritable Set.
To enhance the security, process may also irrevocable delete PCaps out of his Permitted Set, if the process doesn't need them anymore.top  POSIX Capabilities - Effective Flag, Effective SetThe Effective Flag (e) marks a PCap as armed, in effect and direct usable for a process. The Effective Set (E) is the sum of all PCaps with the Effective Flag.

PCaps of the File Effective Set (fE) must also have the Permitted Flag or the Inheritable Flag. The File Effective Set (fE) populates the Process Effective Set of the resulting process if and only if the PCaps is also in the Process Permitted Set of the resulting process.
PCaps unaware programs are not capable of populating their Effective Set them self. This has to be done through the File Effective Set of their respective executable.

PCaps of the Process Effective Set (pE) give the associated privilege to the now running process respectively to the sequence of the now executed code. PCaps of the Process Effective Set must also be part of the Process Permitted Set. A PCaps aware program will raise and lower itself his PCaps into and out of his Effective Set on a as-needed basis.top  POSIX Capabilities - Inheritable Flag, Inheritable SetThe Inheritable Flag (i) marks a Pcap as hereditary/heritable (erbbar) for file or inheritable (vererbbar) for processes. The Inheritable Set (I)is the sum of all PCaps with the Inheritable Flag.

The File Inheritable Set (fI) contains PCaps which go only into the per exec() resulting Process Permitted Set (pP') if the calling process has the same PCaps in his Process Inheritable Set (pI).
The File Inheritable Set migrates not in the new Process Inheritable Set (pI'). The calling Process Inheritable Set (pI) becomes unchanged the new Process Inheritable Set.

PCaps aware applications may change, clear or populate their own Process Inheritance Set. PCaps unaware applications pass the Process Inheritance Set unchanged to a new per exec() created process.

By using PCaps Inheritance, only selected processes with the adequate Process Inheritance Set may call and execute successful applications with accordingly prepared File Inheritance Sets.top  POSIX Capabilities - Capability RulesThe POSIX Capability State is calculated upon an exec(). A forc() or clone() doesn't change the PCaps State.
As defined in 1003.1e p. 17Definition:

p{I,P,E}' = post-exec() POSIX Capability Sets aka the PCaps State of the new process
X = was not specified by 1003.1e and has subsequently become cap_bset - /proc/sys/kernel/cap-bound for Linux
fP = File Permitted Set of the called executable, also Minimal Forced Set called
fE = File Effective Set of the called executable
fI = File Inheritance Set of the called executables
pP = Process Permitted Set (here of the calling process)
pE = Process Effective Set (here of the calling process)
pI = Process Inheritable Set (here of the calling process)
& --> Intersection
| --> Union


Rules:

    1)  pI' = pI    2)  pP' = (X & fP) | (pI & fI)    3)  pE' = fE & pP'



Explanation:

1) The Process Inheritable Set (pI) of the calling process becomes unchanged the Process Inheritable Set (pI') of the newly created process. So exec() is not changing the Process Inheritable Set.

2) The Process Permitted Set (pP') of the per exec() newly created process is the union of two intersections. The first is the intersection of the system upper limit of possible PCaps (X) with the File Permitted Set (fP). The second is the intersection of the calling Process Inheritable Set (pI) with the File Inheritable Set (fI). In one sentence explained is the Process Permitted Set of the per exec() created process the union of the intersection of the system upper limit with the File Permitted Set and the intersection of the Process Inheritable set with the File Inheritable Set.

3) The Process Effective Set (pE') of the newly created process per exec() is the intersection of the File Effective Set (fE) with the Process Permitted Set (pP') of the newly created process.


Discussion:

1) Through the transmission of the unchanged Process Inheritable Set (pI), as far as no PCaps aware application changes this set for them self and the following processes, is it possible for a user with his Inheritabtle Set to kick off and execute successful a chain of applications if his Inheritable Set meets the File Inheritable Sets (fI) of the called applications.

2) The effect of the File Permitted Set (fP), also called Minimal Forced Set, is limited through the System Wide Upper Limit (X).
A process gains its PCaps with Permitted Flags either through File Permitted Set (fP) (Minimal Forced Set) limited by the System Upper Level (X), or through the intersection of the calling Process Inheritable Set (pI) with the called File Inheritable Set (fI). By relying totally on inheritance a program can only be successfully executed, when both the caller and called have the same necessary PCaps in their Inheritable Set. Hence its possible to selectively allow only certain processes the succesful execution of adequately configured executables.

3) After computing the new Process Permitted Set (pP'), only the PCaps which are in both the File Effective Set (fE) and the Process Permitted Set (pP') can be in the initial Process Effective Set (pE'). Initial because if the application is PCaps aware it will clear and populate himself his Process Effective Set. For PCaps unaware application it is evidently crucial, that the needed PCaps have to be in the Process Effective Set (pE) and therefor in the Process Permitted Set (pP).


Remark: Dependencies of Sets

PCaps of File Effective Set have either to be part of the File Permitted Set or the File Inheritable Set.
Only PCaps of the Process Permitted Set can be part of the Process Effective Set or the Process Inheritable Set.top  MotivationThe kernel version 2.6.18 introduced the privilege requirement to have the CAP_NET_ADMIN capability to create a tuntap interface. I was using qemu (www.qemu.org). To interact with a virtual machine you need a lan connectivity through a tuntap interface. Qemu needed from now on this privilege and through lack of alternatives root privilege. I was uneasy having a not so trusty os running in an suid-0 container. First I patched the three lines out of the kernel
diff -ruN linux-2.6.18-orig/drivers/net/tun.c linux-2.6.18/drivers/net/tun.c--- linux-2.6.18-orig/drivers/net/tun.c 2006-09-20 05:42:06.000000000 +0200+++ linux-2.6.18/drivers/net/tun.c      2006-10-02 09:21:52.000000000 +0200@@ -489,9 +489,6 @@                err = -EINVAL;-               if (!capable(CAP_NET_ADMIN))-                       return -EPERM;-                /* Set dev type */                if (ifr->ifr_flags & IFF_TUN) {                        /* TUN device */

and I was back where I was before 2.6.18, but this was not super elegant. In the process of understanding capabilities I found Serges Hallyn's fscaps patch and applied it. I accompanied this patch with tests and documentation. It made it into 2.6.19-rc5-mm2 and stayed for one year in the -mm tree to mature. With 2.6.24-rc2 entered the patch now named 'posix file capabilities' mainline to form the option 'File POSIX Capabilities' under security. KaiGai Kohei was from the end of 2006 to the end of 2007 (11?) providing the user space tools by adding different patches to the libcap1 package. At the end of 2007 Andrew Morgan was again taking care of his libcap packages and with the changes from KaiGai it became the libcap2 package.

The initial reception of the first version summer 2006 of fscaps patch was friendly but reserved. The second version in 10/2006 hadn't gained more attention. It was like asking "who needs this what for". I was the one who had a real use of this patch and was happy about it. And I started again the discussion on LKML. I gave test comments and wrote a documentation to help others to use the patch. Slowly the train started to move and a 'give it a round in -mm' brought it into the -mm tree. For a patch being in -mm, it got more attention, but it has taken one year.

The coincidence chain was qemu-tuntap-2.6.18-cap_net_admin-me. I thought after File POSIX Capabilities went mainline everyone would be happy to substitute suid-0 binaries through File POSIX Capabilities. But nothing happens. So I do my part in spreading the news and promise of this technique through writing documentation, giving talks and coding conversion tools.top  HowTo - Requirements - Check your systemYou will need
- a kernel >= 2.6.24
- a filesystem that supports extended attributes like ext3
- File POSIX Capabilities enabled
- libcap2 package >=2.08Check the Kernel with
$ uname -r


Check your Kernel Config by
$ grep '\(XATTR\|CAPA\)' /boot/config-`uname -r`$ zgrep '\(XATTR\|CAPA\)' /proc/config.gzCONFIG_EXT3_FS_XATTR=yCONFIG_SECURITY_CAPABILITIES=yCONFIG_SECURITY_FILE_CAPABILITIES=y


Check your libcap package
$ ls -l /lib/libcap.so*lrwxrwxrwx 1 root root    11 Mar  9 10:58 /lib/libcap.so -> libcap.so.2lrwxrwxrwx 1 root root    14 Mar  9 10:58 /lib/libcap.so.2 -> libcap.so.2.08-rw-r--r-- 1 root root 14660 Mar  9 10:54 /lib/libcap.so.2.08
top  HowTo - Kernelspace - Compile and InstallIf your distribution repository has not an adequate configured kernel, you have to build your own kernel.Since 2.6.24-rc2 the file system support for POSIX Capabilities is part of mainline. So there is no kernel patching needed. Because the PCaps for files are stored in the extended attributes of that file, a further prerequisite is a file system, that supports extended attributes like ext3.

kernel make menuconfig

Security options  --->    Enable different security models        Default Linux Capabilities    File POSIX Capabilities (EXPERIMENTAL)File systems  --->    Ext3 journalling file system support        Ext3 extended attributes


If you are working with "different security model" option, than check for "Default Linux Capabilities"
Security options  --->    Enable different security models        Default Linux Capabilities


After you finished your kernel configuration, call make, make modules_install, copy your new kernel to /boot, update your boot loader and reboot.top  HowTo - Userspace - Compile and InstallIf your distribution repository has not an adequate libcap2 package, you have to build your own libcap2 package.Since version 2.03 Andrew Morgan's libcap2 package supports 32-bit (mainline -rc of 2.6.24) and 64-bit (-mm of 2.6.24) capabilities. KaiGai Kohei's developments are integrated into the libcap2 package. You will find the tools setcap to set File PCaps State, getcap to read File PCaps State and getpcap to get the Process PCaps State.
Note: As a discussion on LKML revealed, SUSE's libcap-1.92 package in SuSE-9.1 to SUSE-10-1 is not compatible to kernel >= 2.6.25 (24?) and might break apps. Replace this package with the old and original libcap-1.97, if you don't want to use PCaps or libcap-2.08, if you want to use PCaps.
[http://lkml.org/lkml/2008/4/22/18]

Andrew Morgan's libcap2

Get the libcap2 package, extract, compile and install it.

$ tar xjf libcap-2.xx.tar.bz2$ cd libcap-2.xx$ make$ sudo make install


Its a good idea to test your configuration by executing quicktest.sh in root context.

$ cd progs$ sudo ./quicktest.sh
top  HowTo - Configuring and Using PCapsAfter building, installing and rebooting the new kernel with extended attributes and File POSIX Capabilities and compiling and installing the userspace tools, we use setcap and getcap to do the work.To get an idea of the available capabilities have a look at

less /usr/include/linux/capability.hman capabilities


This will clarify the complete set of capability the root power consist of. It is not justified to arm a binary or process with all these capabilities, when its just shopping for a raw socket. Only the lack of mean to adequately equip a binary with the appropriate set of capabilities has leaded to suid-0 binaries.

Granting a PCap is as simple as
$ sudo setcap cap_net_admin=ep /bin/ping


Reading granted capabilities is as simple as
$ getcap /bin/ping/bin/ping: = cap_net_raw+ep


Checking the extended attribute
$ attr -l /bin/pingAttribute "capability" has a 12 byte value for /bin/ping


Removing PCaps
$ sudo setcap -r /bin/ping
top  HowTo - Detection of needed capabilities - Introping is a nice tool to exercise the hunt for the necessary capabilities. It is a root owned suid-bit-0 binary. All the commands will be executed by an unprivileged user. If we need root power, we will use sudo.By checking ping with ls -l we see the suid-bit (s) and that it is root owned. By executing, we see it works.
$ ls -l /bin/ping-rws--x--x 1 root root 29364 2006-08-14 00:20 /bin/ping$ ping -c 1 localhostPING localhost (127.0.0.1) 56(84) bytes of data.64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.111 ms--- localhost ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.111/0.111/0.111/0.000 ms


Now by removing the suid-bit, ping - as expected - can't do it's work by lack of the needed capability.
$ sudo chmod u-s /bin/ping$ ping -c 1 localhostping: icmp open socket: Operation not permitted


Hence the error message is not very explicative, we try strace.top  HowTo - Detection of needed capabilities - stracestrace is a diagnostic tool, which intercepts and records called system calls by a process and the signals which are received by this process by giving the name of each system call, its arguments and its return value. The EPERM error signifies that the caller was not privileged to call a certain function or resource.
$ strace ping localhost 2>&1 | grep EPERMsocket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = -1 EPERM (Operation not permitted)


The caller ping lacks the privilege to create a socket of type SOCK_RAW. /usr/include/linux/capability.h shows

/* Allow use of RAW sockets *//* Allow use of PACKET sockets */#define CAP_NET_RAW          13


This well chosen example showed us easily the needed PCap. You can expect programs that got denied different stuff with -EPERM, which they actually don't need to do. Here to deduce the needed PCaps will be far more complex. But we have another tool at hand.top  HowTo - Detection of needed capabilities - capable_probe moduleSerge E. Hallyn provides in his article 'POSIX file capabilities: Parceling the power of root' the source for the module capable_probe. This module helps us to see the requested PCaps by replacing any calls to cap_capable() by a call to cr_capable(). This function prints out the name of the program together with the requested PCaps. Afterwards it calls the cap_capable() function.Under Tools and Patches you will find a link for the package from this site. The included Makefile is expanded for an install target for the running kernel.

Kprobes allows the insertion of probes. It allows to write small kernel modules to run code at the start of a function (jprobe), the end of a function (kretprobe) or at any address (kprobe). Enabling kprobes and the loading of the module capable_probe will allow us to see the PCaps which are required by the kernel to run the program successful.

kernel make menuconfig
Instrumentation Support  --->    Kprobes


capable_probe
tar capable_probe.tar.bz2cd capable_probemakesudo make install


After inserting the capable_probe module, /var/log/messages will contain the program name with the requested capabilities, when the program is executed. Don't forget to unload the module afterwards. Otherwise your /var/log/messages log file gets flooded.
Here we will work with 2 console. The first to observe /var/log/messages and the second to issue the commands.

console1
$ tail -f /var/log/messages/ | grep ping


console2
$ sudo modprobe capable_probe$ ping localhostping: icmp open socket: Operation not permitted$ sudo modprobe -r capable_probe


console1
...Dec 26 14:57:21 apollo kernel: cr_capable: asking for capability 21 for pingDec 26 14:57:21 apollo kernel: cr_capable: asking for capability 13 for pingDec 26 14:57:21 apollo kernel: cr_capable: asking for capability 7 for pingDec 26 14:57:21 apollo kernel: cr_capable: asking for capability 21 for ping


Again /usr/include/linux/capability.h clarifies the capabilities 7, 13 and 21.
The capability "7: CAP_SETUID" is not what we want ping to do. We need no setuid manipulation.
The catch-all capability "21: CAP_SYS_ADMIN" is better never granted to any program. We are talking about hardening a system by following the principle of least privilege and not about punching holes in.
Common sens helped us to arrive again at capability "13: CAP_NET_RAW.

Granting capabilities - Ping
After the long way around we arrived where we started, but now we know, that ping just needs the CAP_NET_RAW capability to send ICMP packets to a host. There is no need to have and run ping anymore as a suid-0 binary.

$ sudo setcap cap_net_raw=ep /bin/pingtop  HowTo - Removing capabilitiesIf for some reason it is necessary or desirable to get rid of File PCaps ...Our favorite binary ping will serve us again as an example.
ping is now a non-suid-0-bit binary and has the cap_net_raw file capability granted.
In restoring the original state we have to remove the cap_net_raw capability and restore the suid-0-bit.

before we restore, we check the point of departure ...
$ getcap /bin/ping/bin/ping = cap_net_raw+ep$ ls -l /bin/ping-rwx--x--x 1 root root 28992 May  9  2007 /bin/ping$ attr -l /bin/pingAttribute "capability" has a 12 byte value for /bin/ping


... and here we go back to the original state
$ sudo setcap -r /bin/ping
$ sudo chmod u+s /bin/ping
$ ping -c 1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.090 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.090/0.090/0.090/0.000 ms

So, that was not very dramatic ...top  File system operations - updating distro packagesA system is never static. At least security updates have to be applied, to keep the system as secure as possible.
This maintenance of updating distro packages will unfortunately remove the system hardening with File PCaps as long as distro packages don't support PCaps. Updating a binary results in a new inode of the new binary. So the update of the old binary with his old inode will remove the granted capabilities.top  File system operations - mv and cp (coreutils)The cli tools mv and cp are part of the coreutils package (http://www.gnu.org/software/coreutils/). As of version coreutils-6.9, the package is except for ACLs not supporting extended attributes. Thanks to the coreutils-xattr.diff patch external support is available.Before the patched coreutils package compiles sucessfully, the required attr package (ftp://oss.sgi.com/projects/xfs/cmd_tars) has to be expanded by the xattr_conf.diff patch. This patch provides the needed attr_copy_action function. With this patch, the config file /etc/xattr.conf defines, which xattr are respected and which xattrs are ignored by file system operations.

mv

For moving file, we have to differentiate between moving inside a file system and moving from one file system to another.

Moving inside one file system is just a renaming the file system table entry and not touching inodes. Hence moving inside a file system doesn't require xattr support.
Observing this operation with strace shows, that moving the binary myping from the current working directory to the sub folder testdir calls just rename.

$ strace mv myping testdir/execve("/usr/bin/mv", ["mv", "myping", "testdir/"], [/* 53 vars */]) = 0...stat64("testdir/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0lstat64("myping", {st_mode=S_IFREG|0711, st_size=28992, ...}) = 0lstat64("testdir/myping", 0xbf97a664)   = -1 ENOENT (No such file or directory)rename("myping", "testdir/myping")      = 0...Process 28411 detached



Moving from one file system to another on a different partition is actually writing the file to the new file system and unlinking the old file. The extended attributes have to be assigned new. As a bonus I'm showing here the calls for libacl and libattr and the permisssion error. The permission error shows, that calling fsetxattr is only sucessful, when the process has the required priviledge. So beside allowing the file system operation binary to transport xattr through /etc/xattr.conf, the binary needs the PCap cap_set_fcap. Here in this example, as a consequence the xattr capability is lost.


$ strace mv myping /var/testdir/execve("/usr/bin/mv", ["mv", "myping", "/var/testdir/"], [/* 53 vars */]) = 0...open("/lib/libacl.so.1", O_RDONLY)      = 3...open("/lib/libattr.so.1", O_RDONLY)     = 3...stat64("/var/testdir/", {st_mode=S_IFDIR|0755, st_size=1024, ...}) = 0lstat64("myping", {st_mode=S_IFREG|0711, st_size=28992, ...}) = 0lstat64("/var/testdir/myping", 0xbfb36824) = -1 ENOENT (No such file or directory)rename("myping", "/var/testdir/myping") = -1 EXDEV (Invalid cross-device link)unlink("/var/testdir/myping")           = -1 ENOENT (No such file or directory)open("myping", O_RDONLY|O_LARGEFILE)    = 3...open("/var/testdir/myping", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0700) = 4...read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\2\0\3\0\1\0\0\0\340\216"..., 8192) = 8192write(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\2\0\3\0\1\0\0\0\340\216"..., 8192) = 8192read(3, "\204\355\2\0\0\201=T\373\4\10\347\3\0\0\17\216\33\n\0\0"..., 8192) = 8192write(4, "\204\355\2\0\0\201=T\373\4\10\347\3\0\0\17\216\33\n\0\0"..., 8192) = 8192read(3, "\300\17\204\351\2\0\0P\215E\360Ph\264\342\4\10S\350a\316"..., 8192) = 8192write(4, "\300\17\204\351\2\0\0P\215E\360Ph\264\342\4\10S\350a\316"..., 8192) = 8192read(3, "SUM)\0!E\0!EC\0From %s: \0ping: loca"..., 8192) = 4416write(4, "SUM)\0!E\0!EC\0From %s: \0ping: loca"..., 4416) = 4416...flistxattr(3, (nil), 0)                 = 20flistxattr(3, 0xbfb365d0, 20)           = 20open("/etc/xattr.conf", O_RDONLY|O_LARGEFILE) = 5...fgetxattr(3, "security.capability", 0x0, 0) = 12fgetxattr(3, "security.capability", "\x01\x00\x00\x01\x00 \x00\x00\x00\x00\x00", 12) = 12fsetxattr(4, "security.capability", "\x01\x00\x00\x01\x00 \x00\x00\x00\x00\x00", 12, 0) = -1 EPERM (Operation not permitted)...unlinkat(AT_FDCWD, "myping", 0)         = 0...Process 28422 detached


Without strace we have a nice error message:

mv myping /var/testdir/mv: setting attribute `security.capability' for `/var/testdir/myping': Operation not permitted




cp

The cli tool cp provides the option --preserve. With cp --preserve=xattrs the copy operation dublicates also the extended attributes. In contrast to the example above with the nessecary privilege. As we can see, the PCap is copied.

$ strace cp --preserve=xattr myping testdir/execve("/bin/cp", ["cp", "--preserve=xattr", "myping", "testdir/"], [/* 55 vars */]) = 0...open("/lib/libacl.so.1", O_RDONLY)      = 3...open("/lib/libattr.so.1", O_RDONLY)     = 3...stat64("testdir/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0stat64("myping", {st_mode=S_IFREG|0711, st_size=28992, ...}) = 0stat64("testdir/myping", {st_mode=S_IFREG|0711, st_size=28992, ...}) = 0open("myping", O_RDONLY|O_LARGEFILE)    = 3...open("testdir/myping", O_WRONLY|O_TRUNC|O_LARGEFILE) = 4...read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\2\0\3\0\1\0\0\0\340\216"..., 8192) = 8192write(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\2\0\3\0\1\0\0\0\340\216"..., 8192) = 8192read(3, "\204\355\2\0\0\201=T\373\4\10\347\3\0\0\17\216\33\n\0\0"..., 8192) = 8192write(4, "\204\355\2\0\0\201=T\373\4\10\347\3\0\0\17\216\33\n\0\0"..., 8192) = 8192read(3, "\300\17\204\351\2\0\0P\215E\360Ph\264\342\4\10S\350a\316"..., 8192) = 8192write(4, "\300\17\204\351\2\0\0P\215E\360Ph\264\342\4\10S\350a\316"..., 8192) = 8192read(3, "SUM)\0!E\0!EC\0From %s: \0ping: loca"..., 8192) = 4416write(4, "SUM)\0!E\0!EC\0From %s: \0ping: loca"..., 4416) = 4416flistxattr(3, (nil), 0)                 = 20flistxattr(3, 0xbfc78410, 20)           = 20open("/etc/xattr.conf", O_RDONLY|O_LARGEFILE) = 5...fgetxattr(3, "security.capability", 0x0, 0) = 12fgetxattr(3, "security.capability", "\x01\x00\x00\x01\x00 \x00\x00\x00\x00\x00", 12) = 12fsetxattr(4, "security.capability", "\x01\x00\x00\x01\x00 \x00\x00\x00\x00\x00", 12, 0) = 0...Process 15337 detached
top  File system operations - Back up and restore with tarThe back up tool tar up to version 1.20 from http://www.gnu.org/software/tar/ doesn't support extended attributes. Thanks to the external xattr patch, tar supports the saving and restoring of the extended attributes security.selinux, acl.access, acl.default, user.* and trusted.* with the flag --xattr. The patch I provide here adds support for the extended attribute security.capability.When we create the tarball and observe this with strace, we can see, that the PCaps are read and stored:

$ strace tar --xattr -cf tarball mypingexecve("/usr/bin/tar", ["tar", "--xattr", "-cf", "tarball", "myping"], [/* 53 vars */]) = 0...open("/lib/libacl.so.1", O_RDONLY)      = 3...open("/lib/libattr.so.1", O_RDONLY)     = 3...open("tarball", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3...open("myping", O_RDONLY|O_LARGEFILE)    = 4...flistxattr(4, 0x8086130, 1024)          = 20fgetxattr(4, "security.capability", "\x01\x00\x00\x01\x00 \x00\x00\x00\x00\x00", 1024) = 12...write(3, "./PaxHeaders.16524/myping\0\0\0\0\0\0\0"..., 10240) = 10240read(4, "}]\213\r\350,\6\10\205\311u\7=\370\377\0\0v7RPht\332\4"..., 10240) = 10240write(3, "}]\213\r\350,\6\10\205\311u\7=\370\377\0\0v7RPht\332\4"..., 10240) = 10240read(4, "\213\3+E\354\211\3\215\4\200\215\4\200\215\4\200\215\4"..., 10048) = 10048...write(3, "\213\3+E\354\211\3\215\4\200\215\4\200\215\4\200\215\4"..., 10240) = 10240write(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240...Process 16524 detached



When we extract the created tarball and observe this with strace, we can see, that the PCaps are restored. For restoring the xattr, tar needs the necessary privilege.

$ strace tar --xattr -xf ../tarballexecve("/bin/tar", ["tar", "--xattr", "-xf", "../tarball"], [/* 55 vars */]) = 0...open("/lib/libacl.so.1", O_RDONLY)      = 3...open("/lib/libattr.so.1", O_RDONLY)     = 3...open("../tarball", O_RDONLY|O_LARGEFILE) = 3read(3, "./PaxHeaders.16524/myping\0\0\0\0\0\0\0"..., 10240) = 10240...open("myping", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0700) = 4write(4, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\2\0\3\0\1\0\0\0\340\216"..., 8704) = 8704read(3, "}]\213\r\350,\6\10\205\311u\7=\370\377\0\0v7RPht\332\4"..., 10240) = 10240write(4, "}]\213\r\350,\6\10\205\311u\7=\370\377\0\0v7RPht\332\4"..., 10240) = 10240read(3, "\213\3+E\354\211\3\215\4\200\215\4\200\215\4\200\215\4"..., 10240) = 10240write(4, "\213\3+E\354\211\3\215\4\200\215\4\200\215\4\200\215\4"..., 10048) = 10048...chown32("myping", 1000, 100)            = 0...setxattr("myping", "security.capability", "\x01\x00\x00\x01\x00 \x00\x00\x00\x00\x00", 12, 0) = 0chmod("myping", 0711)                   = 0...Process 16751 detached
top  File system operations - back up and restore with rsyncThe back up tool rsync supports since 3.x xattr. Just look for the string xattr in the output of 'rsync --version'.The flag {-X|--xattrs} preseves extended attributes. Executed in the context of root, rsync will copy all namespaces except system.*. Called by an unprivileged user, rsync will only copy the user* namespace.
To sync files with PCaps, the files have to be owned by root and rsync has to be executed as root.

$ strace -f rsync -a --xattrs testdir1/ testdir2/execve("/usr/bin/rsync", ["rsync", "-a", "--xattrs", "testdir1/", "testdir2/"], [/* 54 vars */]) = 0...open("/lib/libacl.so.1", O_RDONLY)      = 3...open("/lib/libattr.so.1", O_RDONLY)     = 3...getuid32()                              = 0geteuid32()                             = 0...getcwd("/home/chris/pcaps-testdir", 4095) = 26...clone(Process 13937 attached...[pid 13936] chdir("/home/chris/pcaps-testdir/testdir1") = 0...[pid 13936] llistxattr(".", 0x80c8eb8, 1024) = 0...[pid 13936] llistxattr("./myping", 0x80c8eb8, 1024) = 44[pid 13936] lgetxattr("./myping", "security.capability", 0x0, 0) = 12[pid 13936] lgetxattr("./myping", "security.capability", "\x01\x00\x00\x01\x00 \x00\x00\x00\x00\x00", 12) = 12...[pid 13937] chdir("/home/chris/pcaps-testdir/testdir2/") = 0...[pid 13937] clone(Process 13938 attached...[pid 13936] open("myping", O_RDONLY|O_LARGEFILE) = 3...[pid 13938] open("myping", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)...[pid 13938] open(".myping.MvDXAT", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 1[pid 13938] fchmod(1, 0700)             = 0...[pid 13938] llistxattr(".myping.MvDXAT", 0x80ba538, 1024) = 0[pid 13938] lsetxattr(".myping.MvDXAT", "security.capability", "\x01\x00\x00\x01\x00 \x00\x00\x00\x00\x00", 12, 0) = 0...[pid 13938] chmod(".myping.MvDXAT", 0755) = 0[pid 13938] rename(".myping.MvDXAT", "myping") = 0......Process 13938 detached...Process 13937 detached...Process 13936 detached
top  Examples - Substitution of suid-0 privilege with POSIX Capabilities privilegeHere we keep sticking to the idea of connecting the needed privileges to the binary. But instead of giving the binary all the privileges the root power consist of, we just grant the needed privileges in form of POSIX Capabilities as File POSIX Capabilities. Following the 'principle of least privilege', we reduce the amount of privileges.There is are reasons for suid-0 binaries to be usable for the unprivileged user. Here we don't doubt this decision, we just reduce the level of power.
To have the binaries just ready to execute with their privileges without expecting them to be PCaps aware, we have to grant the PCaps with the Permitted (p) and Effective (e) Flag.


To find the binaries with suid-0 we use find. Here the result from my installation

$ find {,/usr}/{,s}bin -user root -perm -4000 -exec ls -l {} \;-rwsr-xr-x 1 root root 26352 Mar  9 03:54 /bin/su-rws--x--x 1 root root 28992 May  9  2007 /bin/ping-rwsr-xr-x 1 root root 49120 Mar 31 23:56 /bin/mount-rwsr-xr-x 1 root root 32208 Mar 31 23:56 /bin/umount-rwsr-xr-x 1 root root 19836 Mar  8 02:52 /bin/fusermount-rws--x--x 1 root root 26804 May  9  2007 /bin/ping6-rwsr-xr-x 1 root root 23344 Mar  9 02:42 /sbin/unix_chkpwd-r-s--x--x 1 root root 65048 Apr  1 05:09 /sbin/mount.nfs-rwsr-xr-x 1 root root 38464 Mar  9 03:54 /usr/bin/chage-rwsr-xr-x 1 root root 29196 Mar  9 03:54 /usr/bin/chfn-rwsr-xr-x 1 root root 24612 Mar  9 03:54 /usr/bin/chsh-rws--x--x 1 root root 10480 Dec 13  2006 /usr/bin/crontab-rwsr-xr-x 1 root root 18152 Mar  9 03:54 /usr/bin/expiry-rwsr-xr-x 1 root root 42956 Mar  9 03:54 /usr/bin/gpasswd-rwsr-xr-x 1 root root 22600 Mar  9 03:54 /usr/bin/newgrp-rwsr-xr-x 1 root root 30176 Mar  9 03:54 /usr/bin/passwd-rws--x--x 1 root root 14828 Apr 30  2007 /usr/bin/rcp-rws--x--x 1 root root 10764 Apr 30  2007 /usr/bin/rlogin-rws--x--x 1 root root 7944 Apr 30  2007 /usr/bin/rsh-rws--x--x 1 root bin 90400 Feb  6  2006 /usr/bin/sudo-rws--x--x 1 root bin 16100 Mar  3  2003 /usr/bin/traceroute-rws--x--x 1 root root 11484 May  9  2007 /usr/bin/traceroute6-rwsr-xr-x 1 root root 10104 Feb 26 21:40 /usr/bin/kcheckpass-rwsr-xr-x 1 root root 5412 Mar  8 05:49 /usr/bin/start_kdeinit-rwsr-xr-x 1 root root 11003 Oct  1  2006 /usr/bin/fileshareset-rwsr-xr-x 1 root root 5824 Mar  8 05:49 /usr/bin/kgrantpty-rwsr-xr-x 1 root root 6132 Mar  8 05:49 /usr/bin/kpac_dhcp_helper-rwsr-x--- 1 root floppy 19076 May  1  2002 /usr/bin/fdmount-rwsr-xr-x 1 root root 572008 Feb 26 03:52 /usr/bin/kppp-rwsr-sr-x 1 root mail 65368 Sep 19  2006 /usr/bin/procmail-rwsr-xr-x 1 root root 1651720 Dec 14 19:42 /usr/bin/Xorg



Out of this list have I substituted for the following binaries the suid-0 bit with PCaps.

ping - CAP_NET_RAW (13)traceroute - CAP_NET_RAW (13)chsh - CAP_CHOWN (0), CAP_DAC_READ_SEARCH (2), CAP_FSETID (4), CAP_SETUID (7)chfn - CAP_CHOWN (0), CAP_DAC_READ_SEARCH (2), CAP_FSETID (4), CAP_SETUID (7)chage - CAP_DAC_READ_SEARCH (2)passwd - CAP_CHOWN (0), CAP_DAC_OVERRIDE (1), CAP_FOWNER (3)unix_chkpwd - CAP_DAC_OVERRIDE (1)mount - CAP_DAC_OVERRIDE (1), CAP_SYS_ADMIN (21)umount - CAP_DAC_OVERRIDE (1), CAP_SYS_ADMIN (21)



First you have to remove the suid-0 bit

sudo chmod u-s /usr/bin/chsh


then grant the necessary PCaps

sudo setcap 0,2,4,7=ep /usr/bin/chsh


and at last test the binary.

I provide the conversion tool pcaps4suid0 to do conversion and reversion for suid0 to PCaps and back.top  Examples - Server running as a distinct unprivileged user - ApacheServer software is usually executed as root. It might degrade itself to an unprivileged user, when the privileges the root power consist of are not necessary anymore or only a few privileges are needed further. But as so many suid-0 bit software these server software usually needs only a fraction of the privileges the root provides.The typical server software opens one or more privileged ports, accesses his files in his directories and might handle files of local users (might not be complete). So there is no need to load modules, change system time or kill processes of other users.
To protect the process and files of the server from other users, the server will run with his own user and group.

Apache is started with root privilege to bind itself to the privileged port 80 and 443 and open its usually only root owned config file, certificate, log files and pid file.
I choose for the apache httpd daemon the newly created user id and group id apache. I will change the installation and configuration of apache to start and run as user:group apache:apache.

This changes the configuration to be able to start apache as an unprivileged user and run apache as user:group apache:apache.


First we add user apache and group apache to the system

$$ sudo groupadd apache$ sudo useradd -g apache -d / apache$



Than we make sure apache stays apache:apache by changing the User and Group directive in the configuration file /etc/httpd/httpd.conf

$ sudo sed -i -e "{s|^\(User\).*|\1 apache|; s|^\(Group\) .*|\1 apache|}" /etc/httpd/httpd.conf


If we like to have written a pid file, we create the private directory httpd under /var/run and adjust the reference in the httpd.conf.

$$ sudo mkdir /var/run/httpd$ sudo sed -i "s|\(^PidFile\).*|\1 /var/run/httpd|" /etc/httpd/httpd.conf$



Now we change ownership to apacha:apache of various directories and its content belonging to the httpd server

$$ sudo chown -R apache:apache /var/run/httpd/$ sudo chown -R apache:apache /etc/httpd/$ sudo chown -R apache:apache /var/log/httpd/$ sudo chown -R apache:apache /PATH/TO/YOUR/HTTPD-DOCDIR$



To ensure, that only the file owner apache or root may start the httpd binary, we change the permissions and ownership

$$ ls -l /usr/sbin/httpd-rwxr-xr-x 1 root root 332996 Feb 14 22:39 /usr/sbin/httpd$ sudo chown apache:apache /usr/sbin/httpd$ sudo chmod g-x,o-x /usr/sbin/httpd$ ls -l /usr/sbin/httpd-rwxr--r-- 1 apache apache 332996 Feb 14 22:39 /usr/sbin/httpd/$



Because the apache server doesn't need now any privileges accept for opening and binding to privileged ports we just have to grant CAP_NET_BIND_SERVICE to the httpd binary. Assuming, that the httpd binary can't populate its Effective PCaps Set, we grant beside the Permitted Flag (p) also the Effective Flag (e) for the PCap.

$ sudo setcap cap_net_bind_service=ep /usr/sbin/httpd



For not messing up the file permissions and to prevent excessive privilege granting, root shall start the httpd daemon as user apache with something like

$ su -c /usr/sbin/httpd apache



As an unprivileged user you may, if your sudo configuration allows this, start apache just by typing

$ sudo -u apache /usr/sbin/httpd



See how its running

$$ pidof httpd15259 15258 15257 15256$$ ps -o cmd,pid,ppid,stime,time,euser,ruser -H f -U apache -u apacheCMD                           PID  PPID STIME     TIME EUSER    RUSER/usr/sbin/httpd             15256     1 09:55 00:00:00 apache   apache \_ /usr/sbin/httpd         15257 15256 09:55 00:00:00 apache   apache \_ /usr/sbin/httpd         15258 15256 09:55 00:00:00 apache   apache \_ /usr/sbin/httpd         15259 15256 09:55 00:00:00 apache   apache$



An other way to ensure, that httpd runs only as (effective user) apache is granting the suid-0 bit. In the combination with the execute right only for the owner, still no other unprivileged user may start this binary.

$ sudo chmod u+s /usr/sbin/httpd



We simulate a root call per sudo and check again how it is running with euser and ruser. The real user stays root but as intended by the suid-0 bit the effective user changes to apache

$$ sudo /usr/sbin/httpdchris@apollo ~ $ ps -o cmd,pid,ppid,stime,time,euser,ruser -H f -U apache -u apacheCMD                           PID  PPID STIME     TIME EUSER    RUSER/usr/sbin/httpd             15320     1 11:37 00:00:00 apache   root \_ /usr/sbin/httpd         15321 15320 11:37 00:00:00 apache   root \_ /usr/sbin/httpd         15322 15320 11:37 00:00:00 apache   root \_ /usr/sbin/httpd         15323 15320 11:37 00:00:00 apache   root$



To push it a little further, if we like to allow members of the apache group to start the httpd daemon, we first add this user to the group and change the permission accordingly to allow group members to execute the binary. Now members of the group apache may start the daemon. Non members are still not capable of starting the daemon. Here we use also the suid-0 bit to ensure, that the effective user of the httpd processes is apache.

$$ ls -l /usr/sbin/httpd-rwsr--r-- 1 apache apache 332996 Feb 14 22:39 /usr/sbin/httpd$ /usr/sbin/httpdbash: /usr/sbin/httpd: Permission denied$$ iduid=1000(chris) gid=100(users) groups=100(users)$$ sudo usermod -a -G apache chris$ sudo chmod g+x /usr/sbin/httpd$ sudo su - chris$ iduid=1000(chris) gid=100(users) groups=60(apache),100(users)$$ /usr/sbin/httpd$ ps -o cmd,pid,ppid,stime,time,euser,ruser -H f -U apache -u apacheCMD                           PID  PPID STIME     TIME EUSER    RUSER/usr/sbin/httpd             15490     1 12:00 00:00:00 apache   chris \_ /usr/sbin/httpd         15491 15490 12:00 00:00:00 apache   chris \_ /usr/sbin/httpd         15492 15490 12:00 00:00:00 apache   chris \_ /usr/sbin/httpd         15493 15490 12:00 00:00:00 apache   chris$



I provide the conversion tool pcaps4server to do conversion and reversion for the apache daemon to PCaps and back.top  Examples - Server running as a distinct unprivileged user - BindThe name server bind provides name resolution to network clients. Instead of running as root, this daemon will run in the context of an unprivileged user.We will expand the level of privilege just to open and bind itself to privileged ports. Privileged ports are ports up to 1024.


Here we choose as name for the user and group bind. First we have to add the user and the group
$$ sudo groupadd bind$ sudo useradd -g bind -d / bind$



Then we change the ownership of the directories and files belonging to the daemon.
$$ sudo chown -R bind:bind /var/run/named$ sudo chown -R bind:bind /var/named$ sudo chown bind:bind /etc/namend.conf$ sudo chown bind:bind /etc/rndc.key$



We make sure, that only the file owner bind (and root per definition) is allowed to start the daemon.
$$ ls -l /usr/sbin/named-rwxr-xr-x 1 root root 338920 Apr 14 00:07 /usr/sbin/named*$ sudo chown bind:bind /usr/sbin/named$ sudo chmod g-x,o-x /usr/sbin/namedls -l /usr/sbin/named-rwxr--r-- 1 bind bind 338920 Apr 14 00:07 /usr/sbin/named$



By not running as the privileged user root the binary named now misses the needed privilege of opening and binding to privileged ports. So we grant the CAP_NET_BIND PCap.
$ sudo setcap cap_net_bind_service=ep /usr/sbin/named



To keep the installation clean and to prevent granting an excessive privilege level root shall execute named by
$ su -c /usr/sbin/named bind



If an unprivileged user is allowed through the configuration of sudo, he may execute
$ sudo -u bind /usr/sbin/namend



Instead of specifying the user we may also use the suid-bit and the effective user will be bind
$ sudo chmod u+s /usr/sbin/namend



With named we also may populate the group bind by user, who are allowed to start named.
$$ ls -l /usr/sbin/named-rwsr--r-- 1 bind bind 338920 Apr 14 00:07 /usr/sbin/named*$ /usr/sbin/namedbash: /usr/sbin/named: Permission denied$ iduid=1000(chris) gid=100(users) groups=100(users)$$ sudo usermod -a -G bind chris$ sudo chmod g+x /usr/sbin/named $ ls -l /usr/sbin/named-rwsr-xr-- 1 bind bind 338920 2008-04-14 00:07 /usr/sbin/named$$ sudo su - chris$ iduid=1000(chris) gid=100(users) groups=62(bind),100(users)$ /usr/sbin/named$ ps -o cmd,pid,ppid,stime,time,euser,ruser -H f -U bind -u bindCMD                           PID  PPID STIME     TIME EUSER    RUSER/usr/sbin/named             19354     1 14:09 00:00:00 bind     chris$



The pcaps4server tool also covers bind/named.top  Examples - Server running as a distinct unprivileged user - CupsdReducing the privilege level of the common unix printing system daemon follows the same principle. We create a special user and group which we will call cupsd. We will adjust the ownership of files and directories. And we will grant the needed privileges as PCaps.

We create the user cupsd and the group cupsd
$$ sudo groupadd cupsd$ sudo useradd -g cupsd -d / cupsd$



We make sure, that cupsd will stay with his uid and gid.
$ sudo sed -i -e "{s|^\(User\).*|\1 cupsd|; s|^\(Group\) .*|\1 cupsd|}" /etc/cups/cupsd.conf



We change the ownership to cupsd:cupsd of various directories and its content
$$ sudo chown -R cupsd:cupsd /etc/cups$ sudo chown -R cupsd:cupsd /var/cache/cups$ sudo chown -R cupsd:cupsd /var/log/cups$ sudo chown -R cupsd:cupsd /var/run/cups$ sudo chown -R cupsd:cupsd /var/spool/cups$



To ensure, that only the file owner bind or root may start the cupsd binary, we change the permissions and ownership
$$ ls -l /usr/sbin/cupsd-rwxr-xr-x 1 root root 296800 Apr 30 14:37 /usr/sbin/cupsd*$ sudo chown cupsd:cupsd /usr/sbin/cupsd$ sudo chmod g-x,o-x /usr/sbin/cupsd$ ls -l /usr/sbin/cupsd-rwxr--r-- 1 cupsd cupsd 296800 Apr 30 14:37 /usr/sbin/cupsd$



So all cupsd needs is the privilege to open and bind to privileged ports
$ sudo setcap cap_net_bind_service=ep /usr/sbin/cupsd



To prevent messing up ownership and an excessive privilege level root, shall start the cupsd daemon like
$ su -c /usr/sbin/cupsd cupsd



If allowed by the sudo configuration, an unprivileged user may start cupsd by
$ sudo -u cupsd /usr/sbin/cupsd



Instead of specifying the user we may also use the suid-bit and the effective user will be cupsd
$ sudo chmod u+s /usr/sbin/cupsd



To allow unprivileged user the execution of cupsd they might be added to the group cupsd. We adapt the file system configuration of cupsd to ensure, that the effective user will be cupsd.
$$ ls -l /usr/sbin/cupsd-rwsr--r-- 1 cupsd cupsd 296800 Apr 30 14:37 /usr/sbin/cupsd*$ /usr/sbin/cupsdbash: /usr/sbin/cupsd: Permission denied$ iduid=1000(chris) gid=100(users) groups=100(users)$$ sudo usermod -a -G cupsd chris$ sudo chmod g+x /usr/sbin/cupsd$ ls -l /usr/sbin/cupsd-rwsr-xr-- 1 cupsd cupsd 296800 Apr 30 14:37 /usr/sbin/cupsd*$$ sudo su - chris$ iduid=1000(chris) gid=100(users) groups=64(cupsd),100(users)$ /usr/sbin/cupsd$ ps -o cmd,pid,ppid,stime,time,euser,ruser -H f -U cupsd -u cupsdCMD                           PID  PPID STIME     TIME EUSER    RUSER/usr/sbin/cupsd             14346     1 15:46 00:00:00 cupsd    chris$



I provide the conversion tool pcaps4server to do conversion and reversion for the cupsd daemon to PCaps and back.top  Examples - Server running as a distinct unprivileged user - DHCPDWe are changing the set up and configuration of the Dynamic Host Configuration Protocol Server to run with the just needed privileges. The Dynamic Host Configuration Protocol allows hosts on a TCP/IP network to request and be assigned IP addresses, and also to discover information about the network to which they are attached.DHCPD requires CAP_NET_BIND_SERVICE and CAP_NET_RAW as PCaps. As the DHCPD is not PCaps aware, we provide legacy support by assigning the needed PCaps beside the Permitted (p) Flag also the Effective (e) Flag. The private user and group will be called dhcpd.

We create the user dhcpd and the group dhcpd
$$ sudo groupadd dhcpd$ sudo useradd -g dhcpd -d / dhcpd$



To be able to write his pid file, we create a private directory, which will be owned by dhcpd:dhcpd
$ sudo mkdir /var/run/dhcpd



We adjust the config file accordingly to use the new pid directory
$ sudo sed -i 's|^\(pid-file-name\).*|\1 "/var/run/dhcpd/dhcpd.pid"|' /etc/dhcpd.conf




We change ownership to dhcpd:dhcpd of various files, directories and its content
$$ sudo chown dhcpd:dhcpd /etc/dhcpd.conf$ sudo chown dhcpd:dhcpd /var/run/dhcpd$ sudo chown -R dhcpd:dhcpd /var/state/dhcp/$




The dhcpd binary shall only be executable by the file owner dhcpd or root. We change the permissions and ownership accordingly.
$$ ls -l /usr/sbin/dhcpd-rwxr-xr-x 1 dhcpd dhcpd 507648 Apr  9 04:16 /usr/sbin/dhcpd*$ sudo chown dhcpd:dhcpd /usr/sbin/dhcpd$ sudo chmod g-x,o-x /usr/sbin/dhcpdchris@apollo ~ $ ls -l /usr/sbin/dhcpd-rwxr--r-- 1 dhcpd dhcpd 507648 Apr  9 04:16 /usr/sbin/dhcpd*$



We grant the needed PCaps to the dhcpd binary
sudo setcap cap_net_bind_service,cap_net_raw=ep /usr/sbin/dhcpd



When started out of the context of root, as in start scripts, dhcpd shall be called to prevent messing up of file ownership and an excessive privilege level by
$ su -c /usr/sbin/dhcpd dhcpd



If the system security policy and therefore the sudo configuration allows it, an unprivileged user may start the dhcpd daemon by typing
$ sudo -u dhcpd /usr/sbin/dhcpd



By using the suid-bit, the user doesn't have to be specified. The effective user will change to the file owner.
$ sudo chmod u+s /usr/sbin/dhcpd



By using the technique of group membership and the right to execute the binary for group members and the suid-bit technique, these group members may also execute dhcpd
$$$ ls -l /usr/sbin/dhcpd-rwsr--r-- 1 dhcpd dhcpd 507648 Apr  9 04:16 /usr/sbin/dhcpd*$ /usr/sbin/dhcpdbash: /usr/sbin/dhcpd: Permission denied$ iduid=1000(chris) gid=100(users) groups=100(users)$$ sudo usermod -a -G dhcpd chris$ sudo chmod g+x /usr/sbin/dhcpd$ ls -l /usr/sbin/dhcpd-rwsr-xr-- 1 dhcpd dhcpd 507648 Apr  9 04:16 /usr/sbin/dhcpd*$$ sudo su - chris$ iduid=1000(chris) gid=100(users) groups=63(dhcpd),100(users)$ /usr/sbin/dhcpdInternet Systems Consortium DHCP Server V3.0.6Copyright 2004-2007 Internet Systems Consortium.All rights reserved.For info, please visit http://www.isc.org/sw/dhcp/Wrote 25 leases to leases file.Listening on LPF/eth1/00:0b:5d:29:73:3b/192.168.4/24Sending on   LPF/eth1/00:0b:5d:29:73:3b/192.168.4/24Sending on   Socket/fallback/fallback-net$$ ps -o cmd,pid,ppid,stime,time,euser,ruser -H f -U dhcpd -u dhcpdCMD                           PID  PPID STIME     TIME EUSER    RUSER/usr/sbin/dhcpd             32674     1 09:59 00:00:00 dhcpd    chris$



The pcaps4server tool also covers dhcpd.top  Examples - Server running as a distinct unprivileged user - SAMBAWe will following here also the principle of least privilege to reduce the amount of privileges of the SMB/CIFS fileserver SAMBA.Of the SAMBA package SMBD requires CAP_NET_BIND_SERVICE, CAP_SYS_RESOURCE and CAP_DAC_OVERRIDE as PCaps. NMBD just requires CAP_NET_BIND_SERVICE. Here we provide also legacy support, because we grant beside the Permitted (p) Flag also the Effective (e) Flag to the PCaps. The user and private group will be called samba.


We start by creating the privat group samba and the user samba, whose primary and only group is samba
$$ sudo groupadd samba$ sudo useradd -g samba -d / samba$



To be able to write his pid files, we create a private directory, which will be owned his user:group
$ sudo mkdir /var/run/samba



We adjust the configuration file accordingly to use the new pid directory
$ sudo sed -i 's|\(pid directory =\).*|\1 "/var/run/samba"|' /etc/samba/smb.conf



To be able to write his log file, we create a private directory, which will be owned his user:group
$ sudo mkdir /var/log/samba



We adjust the config file accordingly to use the new log directory. Adjust it to your log scheme like for example /var/log/samba/samba.%m .
$ sudo sed -i 's|\(log file =\).*|\1 "/var/log/samba/samba.log"|' /etc/samba/smb.conf



We adjust the ownership of various directories and file, which are belonging to SAMBA
$$ sudo chown -R samba:samba /etc/samba$ sudo chown -R samba:samba /var/cache/samba$ sudo chown -R samba:samba /var/log/samba$ sudo chown -R samba:samba /var/run/samba$



Only the file owner samba shall be allowed to start the daemon smbd and nmbd. We change the mode bits and ownership.
$$ ls -l /usr/sbin/nmbd /usr/sbin/smbd-rwxr-xr-x 1 root root 1021704 Mar 15 21:52 /usr/sbin/nmbd*-rwxr-xr-x 1 root root 3677972 Mar 15 21:52 /usr/sbin/smbd*$ sudo chown samba:samba /usr/sbin/nmbd /usr/sbin/smbd$ sudo chmod g-x,o-x /usr/sbin/nmbd /usr/sbin/smbd$ ls -l /usr/sbin/nmbd /usr/sbin/smbd-rwxr--r-- 1 samba samba 1021704 Mar 15 21:52 /usr/sbin/nmbd*-rwxr--r-- 1 samba samba 3677972 Mar 15 21:52 /usr/sbin/smbd*$



We grant the needed privileges as PCaps to the Permitted and Effective Set
$$ sudo setcap cap_net_bind_service=ep /usr/sbin/nmbd$ sudo setcap cap_net_bind_service,cap_sys_resource,cap_dac_override=ep /usr/sbin/smbd$



Out of a root context the daemons should be started as
$$su -c /usr/sbin/nmbd samba$su -c /usr/sbin/smbd samba$



Per sudo, if the configuration allows it, an unprivileged user might start it by using
$$ sudo -u samba /usr/sbin/nmbd$ sudo -u samba /usr/sbin/smbd$



By using the suid-bit technique we ensure that the effective user will be the file owner without specifying this user
$ sudo chmod u+s /usr/sbin/nmbd /usr/sbin/smbd



If we want other users to allow the SAMBA daemons, they might be added to the samba group, which will also granted the execute bit. With the suid-bit we assure that the effective user will still be samba.
$$ ls -l /usr/sbin/nmbd /usr/sbin/smbd-rwsr--r-- 1 samba samba 1021704 Mar 15 21:52 /usr/sbin/nmbd*-rwsr--r-- 1 samba samba 3677972 Mar 15 21:52 /usr/sbin/smbd*$ /usr/sbin/nmbd; /usr/sbin/smbdbash: /usr/sbin/nmbd: Permission deniedbash: /usr/sbin/smbd: Permission denied$ iduid=1000(chris) gid=100(users) groups=100(users)$$ sudo usermod -a -G samba chris$ sudo chmod g+x /usr/sbin/nmbd /usr/sbin/smbd$ ls -l /usr/sbin/nmbd /usr/sbin/smbd-rwxr-xr-- 1 samba samba 1021704 Mar 15 21:52 /usr/sbin/nmbd*-rwxr-xr-- 1 samba samba 3677972 Mar 15 21:52 /usr/sbin/smbd*$$ sudo su - chris$ iduid=1000(chris) gid=100(users) groups=61(samba),100(users)$ /usr/sbin/nmbd; /usr/sbin/smbd$$ /usr/sbin/nmbd; /usr/sbin/smbdchris@apollo ~ $ ps -o cmd,pid,ppid,stime,time,euser,ruser -H f -U samba -u sambaCMD                           PID  PPID STIME     TIME EUSER    RUSER/usr/sbin/smbd                786     1 13:23 00:00:00 samba    samba \_ /usr/sbin/smbd            787   786 13:23 00:00:00 samba    samba/usr/sbin/nmbd                783     1 13:23 00:00:00 samba    chris \_ /usr/sbin/nmbd            784   783 13:23 00:00:00 samba    chris$



The pcaps4server tool also covers SAMBA.top  Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - IntroPOSIX Capability Inheritance allows to control who might successful execute a binary, when this binary needs for successful execution a privilege level above of an unprivileged user. Only when both the calling process - and a logged in user is system intern a process - and the called binary have the - for successful execution necessary - PCaps in their Inheritance Set, this PCaps will get the Permitted (p) Flag for the resulting process.Up to here all examples were using the Permitted (p) and Effective (e) Flag. Permitted Flag signifies "you can use it - it is in your toolbox". Effective Flag says "you are using it - you have taken it out of your toolbox, it is in your hand". The Permitted (P) Set, the sum of all PCaps with the Permitted (p) Flag is also called the Minimal Forced Set. Independent of the calling process, the resulting process will have the PCaps of the File Permitted Set in his Process Permitted Set (limited by the System Upper Limit X /proc/sys/kernel/cap-bound or since 2.6.25 by the Inherited Per-Process Upper Limit X). The Effective Flag is only granted to binaries, who are not capable to populate their Effective Set on their own. Not PCaps aware applications are seen as legacy applications and their support through the use of the File Effective Set is called legacy support. So the use of the Effective Flag is actually legacy support.
The Inheritance (i) Flag stays in contrast to the Permitted (p) Flag. Instead of granting the needed PCap the Permitted (p) Flag we might grant the Inheritance (i) Flag.

To illustrate this, we use our beloved ping. Instead running in the context of root as suid-0, and so be able to load modules, change the system time and delete everyones file, we changed the file configuration by eliminating the suid-0 and by granting the needed PCap CAP_NET_RAW the Permitted (p) Flag. Because ping is PCaps unaware we also granted CAP_NET_RAW the Effective (e) Flag.

Just for repetition - the whole story
$$ ls -l /bin/ping-rws--x--x 1 root root 28992 2007-05-09 19:59 /bin/ping*$ ping -c 1 localhostPING localhost (127.0.0.1) 56(84) bytes of data.64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.108 ms--- localhost ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.108/0.108/0.108/0.000 ms$$ sudo chmod u-s /bin/ping$ ls -l /bin/ping-rwx--x--x 1 root root 28992 2007-05-09 19:59 /bin/ping*$ ping -c 1 localhostping: icmp open socket: Operation not permitted$$ sudo setcap cap_net_raw=ep /bin/ping$ getcap /bin/ping/bin/ping = cap_net_raw+ep$ ping -c 1 localhostPING localhost (127.0.0.1) 56(84) bytes of data.64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.120 ms--- localhost ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.120/0.120/0.120/0.000 ms$


Now we have a binary which might be successfully executed by everyone (as before with the suid-0 but with less privilege - but that's not the point here).

But for example our security policy might say, only certain users are allowed to execute applications with the privilege level of the PCap CAP_NET_RAW. These application in question needs for successful execution the CAP_NET_RAW PCap. We grant for the user and for the application this PCap CAP_NET_RAW a special flag, the Inheritable (i) Flag. For the calling process, here the logged in user, having a PCap in his Inheritable Set (pI) means to say, "I have a PCap (in my Inheritable Set), that may go into your Permitted Set (pP'), if you are allowed to receive it". For the called application, having a PCap in his Inheritable Set (fI) is like stating, "I have a PCap (in my Inheritable Set), that may go into my Process Permitted Set (pP') if you, who executes me, have the same PCap in your Process Inheritable Set (pI)". So caller and callee, both of them, have to have the PCap in question in their Inheritable Set, for this PCap to be in the Process Permitted Set (pP') of the new process.

We change the PCap configuration of ping, to expect be called by a process, who is allowed to execute an application with this PCap.
$$ ls -l /bin/ping-rwx--x--x 1 root root 28992 2007-05-09 19:59 /bin/ping$ getcap /bin/ping/bin/ping = cap_net_raw+ep$ sudo setcap cap_net_raw=ei /bin/ping$ getcap /bin/ping/bin/ping = cap_net_raw+ei$


Now we check the PCaps of our logged in session with getpcaps, its as expected empty
$$ /sbin/getpcaps $$Capabilities for `2545': =$


And executing ping fails
$$ ping -c 1 localhostping: icmp open socket: Operation not permitted$


Now with a proper configured pam based log in process, our logged in process gains the necessary PCap in his Inheritable Set
$$ grep chris /etc/security/capability.conf13    chris$$ su - chrisPassword:$$ getpcaps $$Capabilities for `3610': = cap_net_raw+i$$ ping -c 1 localhostPING localhost (127.0.0.1) 56(84) bytes of data.64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.123 ms--- localhost ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.123/0.123/0.123/0.000 ms$


Looking at the appropriate line of the Capability Rules, we see how the Process Permitted Set (pP') of the new process is influenced by the Inheritable Sets. The Intersection of the Caller Process Inheritable Set (pI) and the Called File Inheritable Set (fI) populate (also) the new Process Permitted Set (pP').
2)  pP' = (X & fP) | (pI & fI)



So instead of just granting the needed PCap the Permitted Flag and so allow every process (and user) to execute this application successful, we can create a link between a process/user and an application through the Inheritable Set. Only matching PCaps will go into the Permitted Set of the new process and only by this the application will be executed successful.top  Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - Installing the bitsTo be able to use PCaps, we have had already to install the libcap package. This package also installs since version 2.09 the needed PAM Module pam_cap.so into /lib/security and comes with an example configuration file capability.conf, which has to go into /etc/security.
$$ tar xjf libcap-2.09$ cd libcap-2.09$ make$ sudo make install$ sudo mkdir /etc/security$ sudo cp pam_cap/capability.conf /etc/security$ cd progs$ ./quicktest$


The configuration file /etc/security/capability.conf tells the pam_cap.so PAM Module which PCaps a user may get in his Process Inheritable Set.
You may name the PCaps by their name or by their number. Just have a look at /usr/include/linux/capability.h .
Example of capability.h for the ping exercise
$$ cat /etc/security/capability.conf## /etc/security/capability.conf## this is a sample capability file (to be used in conjunction with# the pam_cap.so module)## In order to use this module, it must have been linked with libcap# and thus you'll know about Linux's capability support.# [If you don't know about libcap, the sources for it are here:##   http://linux.kernel.org/pub/linux/libs/security/linux-privs/## .]## Here are some sample lines (remove the preceding '#' if you want to# use them## user 'morgan' gets the CAP_SETFCAP inheritable capability#cap_setfcap        morgan## user 'luser' just inherits two capabilities (CAP_NET_RAW and CAP_FOWNER)# cap_net_raw,cap_fownerluser13    chris## 'everyone else' gets no inheritable capabilitiesnone  *## if there is no '*' entry, all users not explicitly mentioned will## get all available capabilities. This is a permissive default, and## probably not what you want...$


Naturally you must have a PAM based authentication process. The PAM configuration files are in /etc/pam.d.
If you like to get the Inheritable Set populated through the login process, your login file may look like
$$ cat /etc/pam.d/login#%PAM-1.0auth        required    pam_securetty.soauth        include     system-authauth        required    pam_cap.soaccount     required    pam_nologin.soaccount     include     system-authpassword    include     system-authsession     include     system-authsession     required    pam_loginuid.so$
top  Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - Exploring InheritanceSo if and only if /etc/pam.d/login contains the call of the pam_cap.so PAM Module, we may see the following in exploring the effect of Inheritance.
If we log in as user chris, we will got the CAP_NET_RAW PCap in our Inheritance Set. If we simulate a log in from this shell, the Inheritable Set will go unchanged over to the new process. If we log in per SSH from this shell, we have a new subprocess from init and hence /etc/pam.d/sshd contains no reference to pam_cap, the user will have no PCaps in his Inheritance Set. A simulated log in from here per su leaves obviously the Inheritable Set empty because /etc/pam.d/su also contains no reference to pam_cap.
$Welcome to Linux 2.6.25-a (tty2)apollo login: chrisPassword:$ getpcaps $$Capabilities for `32168': = cap_net_raw+i$ su - chrisPassword:$ getpcaps $$Capabilities for `32183': = cap_net_raw+i$$ ssh apolloLast login: Mon May  5 14:36:55 2008 from apollo.friedhoff.locHave a nice Day ....$ getpcaps $$Capabilities for `32230': =$ su - chrisPassword:$ getpcaps $$Capabilities for `32245': =$$ pstree -upinit(1)-+-acpid(2422)        |-agetty(2441)        |-agetty(2443)        |-agetty(2445)        |-agetty(2447)        |-crond(2417)        |-dbus-daemon(2403,messagebus)        |-gpm(32142)        |-inetd(2390)        |-klogd(2160)        |-login(2437)---bash(2461,chris)---vim(32197)        |-login(31451)---bash(32168,chris)---su(32182)---bash(32183)---ssh(32222)        |-sleepd(2435)        |-smartd(2414)        |-spamd(2429)---spamd(333)        |-sshd(2394)---sshd(32223)---sshd(32228,chris)---bash(32230)---su(32244)---bash(32245)---pstree(32261)        |-syslogd(2158)        |-udevd(1053)        `-wpa_supplicant(2178)$$ getpcaps 31451 32168 32182 32183 32222 2394 32223 32228 32230 32244 32245Capabilities for `31451': =ep cap_net_raw+iCapabilities for `32168': = cap_net_raw+iCapabilities for `32182': = cap_net_raw+iCapabilities for `32183': = cap_net_raw+iCapabilities for `32222': = cap_net_raw+iCapabilities for `2394': =epCapabilities for `32223': =epCapabilities for `32228': =Capabilities for `32230': =Capabilities for `32244': =Capabilities for `32245': =


A process running in the context of root is kernel intern a process, whose all available PCaps are having the Effective (e) and Permitted (p) Flag. Root has the complete Effective and Permitted Set. The root runned login process 31451 has beside beside the fully equiped EP-Sets also the PCap CAP_NET_RAW with the Inheritable (i) Flag. This Inheritable Set goes unchanged over to the chris owned bash session 32168. According to the Inheritance part of the Capability Rule, this Inheritable Set goes unchanged over from 32168 -> 32182 -> 32183 to finally 32222. Because the configuration of /etc/pam.d/sshd does not populate the Inheritance Set, all the subsequence processes have also an empty Inheritance Set.top  Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - SUID-BIT 0 reloadedIn the process of substituting the suid-bit-0 configuration with PCaps, we just reduced the amount of privilege these former suid-0 applications are now executed with. We granted the Permitted (p) Flag - Forced Flag - so for every calling process we ensured, that the resulting process will have the needed PCaps available. Due to legacy support, we also granted the Effective (e) Flag.

Now we look again at these applications and their needed PCaps
ping - CAP_NET_RAW (13)traceroute - CAP_NET_RAW (13)chsh - CAP_CHOWN (0), CAP_DAC_READ_SEARCH (2), CAP_FSETID (4), CAP_SETUID (7)chfn - CAP_CHOWN (0), CAP_DAC_READ_SEARCH (2), CAP_FSETID (4), CAP_SETUID (7)chage - CAP_DAC_READ_SEARCH (2)passwd - CAP_CHOWN (0), CAP_DAC_OVERRIDE (1), CAP_FOWNER (3)unix_chkpwd - CAP_DAC_OVERRIDE (1)


We will change the configuration from the Permitted Set toward the Inheritable Set
$$ sudo setcap 13=ei /bin/ping$ sudo setcap 13=ei /usr/bin/traceroute$ sudo setcap 0,2,4,7=ei /ust/bin/chsh$ sudo setcap 0,2,4,7=ei /usr/bin/chfn$ sudo setcap 2=ei /usr/bin/chage$ sudo setcap 0,1,3=ei /usr/bin/passwd$ sudo setcap 1=ei= /sbin/unix_chkpwd$


We will grant user chris these PCaps into his Inheritable Set by changing /etc/security/capability.conf
$sudo sed -i 's|.*\(chris\)|0,1,2,3,4,7,13   \1|' /etc/security/capability.conf


and check the configuration, that chris receives an Inheritable Set and anyone else has an empty Inheritable Set (none clause)
$$ egrep -v "(#|^$)" /etc/security/capability.conf0,1,2,3,4,7,13   chrisnone  *$


Now we have a configuration, where luser want be able anymore to execute the former suid-bit-0 applications. He is now even less powerful than before. With his Inheritable Set and the applications having also an Inheritable Set, chris is still able to execute these former suid-bit-0 applications.top  Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - ConvenienceTo show what is possible, as a proof of concept, I was showing in the past, how to raise the convenience by granting several applications the PCaps to execute successful. But contrary to the former suid-0 applications, these applications where formerly not accessible by the unprivileged user. So the net effect was, that suddenly other unprivileged user might come into the position to do things, they were not allowed before.
So, do your risk analysis and weight up between convenience and a possible security problem before following the examples - you have been warned.
In fact the multi user system Linux is very often used as a single user system and this user also performs some administration tasks. Some applications need only one or a few privileges to execute successful. Through the usage of the technique of Inheritance Sets, we can grant the elected user and the elected applications the needed PCaps in their Inheritance Set, so we can execute these applications without the need of 'sudo' or 'su -c'.

For the following applications I have detected the needed PCaps
eject = CAP_DAC_READ_SEARCH (2), CAP_SYS_RAWIO (17)ifconfig = CAP_NET_ADMIN (12)killall = CAP_KILL (5)modprobe = CAP_SYS_MODULE (16)ntpdate = CAP_NET_BIND (10), CAP_SYS_TIME (25)qemu = CAP_NET_ADMIN (12)route = CAP_NET_ADMIN (12)


Again, we configure the needed PCaps for the applications
$setcap 2,17=ei /usr/bin/ejectsetcap 12=ei /sbin/ifconfigsetcap 5=ei /bin/killallsetcap 16=ei /sbin/modprobesetcap 10,25=ei /usr/sbin/ntpdatesetcap 12=ei /usr/bin/qemusetcap 12=ei /sbin/route$


We will grant user chris also these PCaps into his Inheritable Set by changing /etc/security/capability.conf
$sudo sed -i 's|.*\(chris\)|0,1,2,3,4,5,7,10,12,13,16,17   \1|' /etc/security/capability.conf


and check the configuration, that chris receives an Inheritable Set and anyone else has an empty Inheritable Set (none clause)
$$ egrep -v "(#|^$)" /etc/security/capability.conf0,1,2,3,4,5,7,10,12,13,16,17   chrisnone  *$


Here we reached a point, where we are able to provide users with a privilege level below than with suid-0 applications to as far as being able to do some administration task. I believe, that system user - user accounts without real persons behind them - are examples to refuse the ability to - lets say - change account data like passwords and login shells or edit the crontab or do mount and umount operations. On the other hand, a trusted user, who regularly performs administration tasks might be granted some privileges in combination with the appropriate application to perform necessary tasks, without executing them with the privilege level of root trough 'sudo' or 'su -c'.top  Examples - Types of usage of POSIX Capabilities - Different privilege levels for different user rolls - Different Administration RollsA nice example is the roll of a back-up administrator. By using the tool - for example tar - the backup process needs privileges above the level of an unprivileged user. We will grant this back-up administrator the privilege of reading root owned system files and files of other user by granting him CAP_READ_SEARCH in his Process Inheritance Set. The back-up tool tar on the other hand will also have these PCaps in his File Inheritance Set. Only a user and here our back-up administrator with the matching PCaps in his Process Inheritance Set will by executing tar populating the Process Permitted Set of this tar process with the privilege to read these files.

A network roll is an other imaginable position. Granting this user and the adequate applications the needed privileges as PCaps with the Inheritable Flag allows only him to execute these applications with the necessary privileges.

Further rolls might be something like a user account administrator or a reboot administrator.top  Lectures, Talks and PresentationsI have presented 'POSIX File Capabilities' at the Chemnitzer Linux-Tage 2008 in the security track Saturday March the first.

I have presented 'POSIX {,File} Capabilities - killall suid-0 binaries and far beyond' at the Linuxtag 2008 in Berlin Friday May 30th.

You will find the presentations and papers on the download page.top 

Licence


The content of this page is published under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Licence.

0 0
原创粉丝点击