AppArmor und seccomp in Docker - Systemaufrufe einschränken
AppArmor und seccomp in Docker - Systemaufrufe einschränken
Docker-Container teilen den Host-Kernel – wer den Angriffsfläche minimieren will, schränkt Systemaufrufe und Dateizugriffe mit seccomp und AppArmor ein.
Was sind seccomp und AppArmor?
seccomp (Secure Computing Mode): Filtert Systemaufrufe (syscalls) auf Kernel-Ebene. Ein Container darf nur die explizit erlaubten syscalls ausführen. Alle anderen werden blockiert.
AppArmor: Mandatory Access Control für Linux. Kontrolliert welche Dateien, Netzwerke und Capabilities ein Prozess nutzen darf – per Profil definiert.
seccomp: Docker-Standard-Profil
Docker wendet auf jeden Container automatisch ein Standard-seccomp-Profil an, das ~44 gefährliche Syscalls blockiert:
# Aktives seccomp-Profil eines Containers prüfen
docker inspect mycontainer --format '{{.HostConfig.SecurityOpt}}'
# [seccomp={"defaultAction":"SCMP_ACT_ERRNO",...}]
Das Standard-Profil ist für die meisten Anwendungen ausreichend. Für Container die Untrusted Input verarbeiten (z.B. Code-Execution-Dienste) kann ein restriktiveres Custom-Profil sinnvoll sein.
Eigenes seccomp-Profil erstellen
// /etc/docker/seccomp/strict.json
{
"defaultAction": "SCMP_ACT_ERRNO",
"architectures": ["SCMP_ARCH_X86_64"],
"syscalls": [
{
"names": [
"read", "write", "open", "close",
"stat", "fstat", "mmap", "mprotect",
"brk", "exit_group", "futex",
"accept", "connect", "socket",
"sendto", "recvfrom", "bind", "listen"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
# Profil anwenden
docker run --security-opt seccomp=/etc/docker/seccomp/strict.json myimage
In Compose:
services:
app:
image: myapp
security_opt:
- seccomp:/etc/docker/seccomp/strict.json
seccomp deaktivieren (für Debugging)
# Alle Syscalls erlauben – nur für Debugging, nie in Produktion
docker run --security-opt seccomp=unconfined myimage
AppArmor: Standard-Profil
Docker wendet das docker-default AppArmor-Profil an, wenn AppArmor auf dem Host aktiv ist:
# AppArmor-Status prüfen
aa-status
# Profil eines Containers prüfen
docker inspect mycontainer --format '{{.AppArmorProfile}}'
Eigenes AppArmor-Profil
# /etc/apparmor.d/docker-myapp
#include <tunables/global>
profile docker-myapp flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
# Netzwerk erlauben
network inet tcp,
network inet udp,
# Nur bestimmte Verzeichnisse beschreibbar
/app/uploads/** rw,
/tmp/** rw,
# Rest der Filesystem nur lesend
/** r,
# Bestimmte Capabilities verbieten
deny capability mknod,
deny capability net_admin,
}
# Profil laden
apparmor_parser -r /etc/apparmor.d/docker-myapp
# Container mit Profil starten
docker run --security-opt apparmor=docker-myapp myimage
Praktische Anwendungsfälle
Code-Execution-Container (z.B. online Code-Judge): seccomp-Profil das nur Lese-/Schreib-Syscalls und keine Netzwerk-Syscalls erlaubt.
Web-Scraper: AppArmor-Profil das nur HTTP/HTTPS-Zugriff erlaubt, keine Dateisystemzugriffe außer /tmp.
Datenbank: seccomp-Profil ohne ptrace, process_vm_readv, kexec_load.
Capabilities ergänzend einschränken
Zusammen mit seccomp und AppArmor:
# Alle Capabilities entfernen, nur die nötigsten erlauben
docker run \
--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--security-opt seccomp=/etc/docker/seccomp/strict.json \
myimage
Diese Kombination aus --cap-drop ALL, einem restriktiven seccomp-Profil und einem AppArmor-Profil liefert maximale Isolation für Container mit Untrusted Input.
Weiterführend
AppArmor und seccomp sind Linux-Kernfunktionen, die unabhängig von Docker existieren. Weiterführendes zu Linux-Sicherheit und Systemhärtung findet sich auf nolr.nexon.cyou.