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.
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.
getcap /usr/sbin/nginx/usr/sbin/nginx cap_net_bind_service=epone capability — not full root — to bind :80Drop 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: trueallowPrivilegeEscalation: falsecapabilities:drop: ["ALL"]add: ["NET_BIND_SERVICE"]
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.