Home / Alt manpages / setcap(8)

  • setcap(8)
  • Admin command
  • linux

Set and Verify Linux File Capabilities with setcap

Stop making network daemons run as root just so they can bind port 443: setcap hands out the one privilege they actually need. You will give an executable a narrowly defined file capability, check that the kernel stored it, and remove it again without touching the original program. Examples use setcap from Ubuntu's libcap2-bin package, version 1:2.66-5ubuntu2.4.

Allow about fifteen minutes. You need a shell, the libcap2-bin package, a regular executable file you can copy, and elevated privileges for the capability change. The reference container used here lacks the kernel capability needed to write file capabilities, so its attempted write returns an error. That is a useful boundary to recognise, not a reason to weaken the example.

1. Check the command and choose a disposable copy

Start with read-only checks. The package binary lives under /usr/sbin on this system; use the path command -v gives you on your own host rather than assuming a locally built copy matches.

$ command -v setcap
/usr/sbin/setcap
$ dpkg-query -W -f='${Package} ${Version}\n' libcap2-bin
libcap2-bin 1:2.66-5ubuntu2.4
$ setcap -h
usage: setcap [-h] [-q] [-v] [-n <rootid>] (-r|-|<caps>) <filename> [ ... ]

Copy a harmless executable so the first experiment cannot touch a system-owned file. This is an ordinary, unprivileged file operation:

$ DEMO=/tmp/setcap-demo
$ cp --preserve=mode /usr/bin/true "$DEMO"
$ file "$DEMO"
/tmp/setcap-demo: ELF ... executable ...

The exact file wording varies by architecture. What matters is that the path exists, is a regular file, and is not a symbolic link. Leave the original executable alone.

2. Understand the capability string

setcap accepts the capability text format documented by cap_text_formats(7). A useful example is cap_net_bind_service=ep: it names the capability that lets a program bind privileged TCP or UDP ports, then requests the effective and permitted file sets. That is a specific privilege, not a general replacement for root.

  • Do not copy a capability just because the name sounds related. File capabilities change what a program can gain at execution time. Review the program, its arguments, its writable files and its update path before applying one, and grant the smallest set it genuinely needs.
  • The = operator resets the named capability's flags before applying what follows.
  • The letters are case-sensitive: e is effective, p is permitted, i is inheritable.
  • A malformed or unsupported string is rejected.

3. Apply one capability

This is the first security-sensitive step. It changes extended file metadata and normally needs an administrator account with the kernel's file-capability privilege. Run it only against the disposable copy until you have reviewed the result:

$ sudo setcap cap_net_bind_service=ep "$DEMO"
$ printf 'setcap status: %s\n' "$?"
setcap status: 0

A successful setcap normally prints nothing; the status belongs to the command right before printf. If you see Operation not permitted, the account or container lacks permission to write file capabilities. Do not work around that by granting a broader capability or making the file setuid: check the host's security policy and container restrictions instead.

Checkpoint

If the status was not zero, stop here. There is nothing useful to verify, and the next command should not be taken as proof the change succeeded.

4. Inspect and verify the stored value

Use getcap to display the metadata. This is a separate command and safe to run without elevated privileges when the file and directory are readable:

$ getcap "$DEMO"
/tmp/setcap-demo cap_net_bind_service=ep

The path and capability text should match your command. Now ask setcap to verify the value rather than set it:

$ sudo setcap -v cap_net_bind_service=ep "$DEMO"
$ printf 'verification status: %s\n' "$?"
verification status: 0

Verification status zero means the requested capability is associated with the file. A non-zero result means the stored value differs or the file cannot be inspected. Re-run getcap, check you named the same file, and inspect permissions before changing anything else.

5. Know the difference between empty and removed

setcap = file sets an explicitly empty capability set. That is not the same as having no file capability at all: an empty set can suppress privilege that would otherwise arrive through ambient and inheritable capability rules when the file executes. Treat it as an intentional security control, not a tidy-up command.

To remove the file capability metadata entirely, use -r:

$ sudo setcap -r "$DEMO"
$ getcap "$DEMO"
$ printf 'remove status: %s\n' "$?"
remove status: 0

Nothing displayed means the removal is complete. If you had deliberately set an empty set and now need to remove that suppression, -r is the right undo. Do not replace it with setcap =, which recreates the state you meant to remove.

6. Handle common failure modes

  • Operation not permitted: the process cannot write file capabilities. This can happen even when sudo succeeds, particularly in a restricted container without CAP_SETFCAP.
  • Symbolic link or non-regular file: the command requires a regular, non-symlink target. Resolve the path and operate on the intended file, not a link in a service directory.
  • Verification differs: compare the exact capability text and filename. A zero status from a different command is not proof the intended file changed.
  • Unexpected service behaviour: remove the capability with sudo setcap -r /path/to/file, then restart the service only if its manager requires one. Keep a copy of the original metadata and record the change before production work.

Use -q when a script needs less diagnostic output, but still test the exit status. Use -n ROOTUID only when you understand user-namespace ownership: the capability is then limited to a user namespace with that root user ID, not a general way to dodge host permission checks.

Done means

  • Target is a disposable or reviewed regular file, not a system binary chosen by guesswork.
  • The capability string names only the privilege the program needs.
  • getcap shows the expected value and setcap -v returns status 0.
  • You can explain the state: a capability, an explicitly empty set, or no capability metadata at all.
  • The rollback command is known: sudo setcap -r FILE.