BlogLinux & scripting

Linux capabilities: dropping root the right way

Split root into fine-grained capabilities, drop everything you don't need, and stop running containers as full root.

Dec 30, 2025·9 min readIntermediate

Root is not one thing — since Linux 2.2 it is ~40 separate capabilities. A process that only needs to bind port 80 does not need the power to load kernel modules. Dropping everything and adding back the one or two capabilities a service needs is the single highest-leverage container hardening step.

bash — what a binary needslive
getcap /usr/sbin/nginx
/usr/sbin/nginx cap_net_bind_service=ep
one capability — not full root — to bind :80

Drop all, add back what you need

bash
docker run \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--user 10001 \
myapp:1.4

The same thing in Kubernetes

pod.yaml
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
Blast radius on RCE
Full root
load kernel modules
raw sockets
change any file owner
mount filesystems
Dropped caps
bind a low port
and nothing else
no module loading
no host tampering
CAP_NET_RAW is a common leak
It is on by default in Docker and lets a container craft raw packets for ARP spoofing and scanning. Drop it unless you truly need ping.
Go deeper in a courseAdvanced container securityCapabilities, seccomp, and the runtime flags that stop escapes.View course

Related posts