Linux Capabilities in Docker begrenzen - cap-drop und cap-add
Linux Capabilities in Docker begrenzen - cap-drop und cap-add
Docker-Container laufen mit einem reduzierten, aber immer noch signifikanten Set an Linux-Capabilities — wer wirklich absichern will, muss aktiv kürzen.
Was sind Linux Capabilities?
Linux teilt Root-Privilegien in granulare Einheiten auf. Statt "alles oder nichts" (root vs. kein root) gibt es über 40 Capabilities:
| Capability | Erlaubt |
|---|---|
| NET_BIND_SERVICE | Ports unter 1024 binden |
| NET_ADMIN | Netzwerk-Interfaces konfigurieren |
| SYS_ADMIN | Systemadministration (sehr mächtig) |
| SYS_PTRACE | Prozesse tracen (strace, gdb) |
| CHOWN | Datei-Eigentümer ändern |
| KILL | Signale an Prozesse senden |
| SETUID | User-ID wechseln |
Standard-Capabilities in Docker
Docker gewährt Containern standardmäßig ca. 14 Capabilities, u.a. CHOWN, DAC_OVERRIDE, FOWNER, KILL, NET_BIND_SERVICE, SETGID, SETUID.
# Aktive Capabilities im Container prüfen
docker run --rm alpine sh -c 'apk add -q libcap && capsh --print'
Alle Capabilities entfernen, gezielt hinzufügen
Das sicherste Pattern: alles entfernen, nur das Notwendige zurückgeben:
docker run --cap-drop ALL --cap-add NET_BIND_SERVICE nginx
In Compose:
services:
app:
image: myapp
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE # App bindet Port 80
Einzelne Capabilities entfernen
Ohne ALL zu droppen können spezifische Capabilities entfernt werden:
docker run --cap-drop SYS_ADMIN --cap-drop NET_ADMIN myapp
services:
app:
image: myapp
cap_drop:
- SYS_ADMIN
- NET_ADMIN
- SYS_PTRACE
Welche Capabilities braucht eine typische Web-App?
- Eine einfache Web-Anwendung, die:
- Intern auf Port 3000+ lauscht (kein NET_BIND_SERVICE nötig)
- Keine Prozesse ptracet
- Keine Netzwerk-Interfaces konfiguriert
- Nicht als verschiedene User laufen muss
...braucht fast keine Capabilities:
services:
app:
image: myapp
cap_drop:
- ALL # Für die meisten Web-Apps ausreichend
Privilegierter Modus: der Worst Case
docker run --privileged myapp # Container hat ALLE Capabilities + Device-Zugriff
Privileged-Mode gibt dem Container so gut wie vollen Host-Zugriff. Nur für sehr spezifische Fälle notwendig (Docker-in-Docker, bestimmte Kernel-Module). In Produktions-Web-Services niemals.
Typische Anwendungsfälle
Webserver (Nginx auf Port 80):
cap_drop: [ALL]
cap_add: [NET_BIND_SERVICE, CHOWN, SETGID, SETUID]
Datenbank (PostgreSQL):
cap_drop: [ALL]
cap_add: [CHOWN, DAC_OVERRIDE, FOWNER, SETGID, SETUID]
Monitoring-Agent (braucht Prozess-Informationen):
cap_drop: [ALL]
cap_add: [SYS_PTRACE, DAC_READ_SEARCH]
Capabilities und Seccomp
Capabilities und Seccomp-Profile sind komplementäre Sicherheits-Layer:
- Capabilities: Steuern welche privilegierten Aktionen erlaubt sind
- Seccomp: Filtert System Calls auf Kernel-Ebene
# Standard-Seccomp-Profil ist bereits aktiv
docker run --security-opt seccomp=/path/to/profile.json myapp
Effekt prüfen
# Capabilities vor und nach dem Entfernen vergleichen
docker run --rm alpine capsh --print
docker run --rm --cap-drop ALL alpine capsh --print
Das Entfernen aller nicht benötigten Capabilities ist eine der effektivsten Härtungsmaßnahmen — sie begrenzt, was ein kompromittierter Prozess überhaupt tun kann, selbst wenn er root im Container ist.
Weiterführend
Linux-Capabilities sind ein Kernthema der allgemeinen Linux-Systemhärtung — Hintergrundwissen zu Linux-Sicherheit, Rechteverwaltung und Netzwerken gibt es auf nolr.nexon.cyou.