seccomp: Syscall-Filter für gehärtete Container und Prozesse
AI generated
$
/etc
Linux
seccomp: Syscall-Filter für gehärtete Container und Prozesse
BPF basierte Syscall Filterung zwischen Sicherheit und Kompatibilität

Namespaces isolieren, was ein Prozess sieht, seccomp begrenzt, was ein Prozess überhaupt tun darf. Wer Container Härtung ausschließlich über Capabilities und Namespaces denkt, übersieht damit eine der wirkungsvollsten Verteidigungslinien gegen Kernel Exploits: die gezielte Sperrung von Systemaufrufen, die eine Anwendung im Normalbetrieb schlicht nie benötigt.

10 Min. Lesezeit Linux Sicherheit Container

1. Was seccomp ist und wofür es entwickelt wurde

seccomp, kurz für Secure Computing Mode, ist ein Kernel Feature, das die Menge der Systemaufrufe einschränkt, die ein Prozess ausführen darf. Ursprünglich 2005 als extrem restriktiver Modus eingeführt, der nur noch read, write, exit und sigreturn erlaubte, entwickelte sich seccomp mit dem 2012 hinzugekommenen seccomp-bpf Modus zu einem deutlich flexibleren Werkzeug, das komplexe, programmierbare Filterregeln statt eines starren Alles oder Nichts Modells erlaubt.

Der grundlegende Gedanke ist simpel: Ein Webserver Prozess wird niemals reboot aufrufen, ein PHP FPM Worker wird niemals ein neues Kernel Modul laden, und ein Datenbank Prozess wird niemals die Systemzeit manipulieren. Jeder dieser Syscalls, die eine Anwendung im Normalbetrieb nie benötigt, aber ein Angreifer nach einem erfolgreichen Exploit potenziell missbrauchen könnte, lässt sich mit seccomp präventiv blockieren, lange bevor eine Anwendungslogik überhaupt zum Tragen kommt.

2. Wie die BPF basierte Filterung technisch funktioniert

seccomp-bpf nutzt dieselbe Berkeley Packet Filter Technologie, die ursprünglich für Netzwerkpaket Filterung entwickelt wurde, jetzt aber auf Syscall Nummern und deren Argumente angewendet wird. Bei jedem Systemaufruf durchläuft der Kernel das geladene BPF Programm, das anhand der Syscall Nummer und optional einzelner Argumente entscheidet, ob der Aufruf erlaubt, verweigert, protokolliert oder mit einem Fehlercode simuliert wird, alles innerhalb weniger Kernel Zyklen ohne spürbaren Performance Einfluss.

Ein seccomp Filter wird als kleines BPF Bytecode Programm über den Systemaufruf seccomp() beziehungsweise das ältere prctl(PR_SET_SECCOMP) geladen und ist danach unumkehrbar an den Prozess und alle seine Kindprozesse gebunden: Ein einmal gesetzter Filter lässt sich niemals lockern, nur durch zusätzliche, restriktivere Filter weiter verschärfen. Diese Einwegrichtung ist ein bewusstes Sicherheitsdesign, das verhindert, dass ein kompromittierter Prozess seine eigenen Beschränkungen nachträglich aufhebt.


# Aktuellen seccomp Status eines Prozesses pruefen (0=disabled, 2=filter aktiv)
grep Seccomp /proc/$$/status

# Verfuegbare seccomp Aktionen des laufenden Kernels anzeigen
cat /proc/sys/kernel/seccomp/actions_avail

3. Filter-Aktionen: von ALLOW bis KILL

Ein seccomp Filter kann für jeden Syscall eine von mehreren Aktionen zurückgeben: SCMP_ACT_ALLOW lässt den Aufruf unverändert durch, SCMP_ACT_ERRNO lässt den Syscall fehlschlagen und liefert einen definierten Fehlercode zurück, ohne den Prozess zu beenden, SCMP_ACT_TRAP löst ein SIGSYS Signal aus, das der Prozess selbst behandeln kann, und SCMP_ACT_KILL beendet den aufrufenden Thread oder gleich den gesamten Prozess sofort.

Für Produktivumgebungen ist SCMP_ACT_ERRNO meist die pragmatischere Wahl gegenüber SCMP_ACT_KILL: Ein Prozess, der einen blockierten Syscall mit einem sauberen Fehlercode wie EPERM zurückerhält, kann diesen Fehler oft abfangen und weiterlaufen, während ein hartes Kill die gesamte Anwendung sofort beendet und im schlimmsten Fall unerwartete Downtime verursacht, nur weil ein selten genutzter, aber legitimer Syscall übersehen wurde.

4. Das Docker-Default-Profil im Detail

Docker aktiviert seit Version 1.10 standardmäßig ein vordefiniertes seccomp Profil für jeden neu gestarteten Container, das von den über 300 verfügbaren Linux Syscalls etwa 44 explizit blockiert, während der weitaus größere Rest erlaubt bleibt. Blockiert werden unter anderem reboot, swapon, mount außerhalb spezifischer, erlaubter Ausnahmen, kexec_load, sowie Syscalls zum Manipulieren von Kernel Modulen und zur Kontrolle der Systemzeit, allesamt Operationen, die für einen normalen Applikations Container niemals legitim gebraucht werden.

Wichtig ist die Abgrenzung zu Capabilities: Ein blockierter Syscall im seccomp Profil bleibt blockiert, selbst wenn der Prozess theoretisch die passende Capability besäße, denn seccomp arbeitet als zusätzliche, unabhängige Schutzschicht auf Syscall Ebene, die vor und unabhängig von der Capability Prüfung greift. Docker deaktiviert das Default Profil vollständig über --security-opt seccomp=unconfined, was in produktiven Umgebungen praktisch niemals angebracht ist und ausschließlich für sehr spezifisches Debugging reserviert bleiben sollte.


# Aktives seccomp Profil eines laufenden Containers inspizieren
docker inspect shop-php --format '{{.HostConfig.SecurityOpt}}'

# Default Profil bewusst deaktivieren (nur für isoliertes Debugging!)
docker run --rm -it --security-opt seccomp=unconfined alpine sh

5. Ein eigenes seccomp-Profil erstellen

Ein eigenes seccomp Profil beginnt üblicherweise als restriktive Basis, die eine Whitelist erlaubter Syscalls definiert, statt vom permissiveren Default Profil auszugehen und einzelne zusätzliche Syscalls zu blockieren. Für Docker ist ein Profil eine JSON Datei mit einer defaultAction, die für alle nicht explizit aufgeführten Syscalls gilt, sowie einer Liste von syscalls Einträgen, die davon abweichende Aktionen definieren.

Die größte praktische Herausforderung beim Erstellen eines eigenen, restriktiven Profils ist die vollständige Ermittlung aller tatsächlich benötigten Syscalls einer Anwendung, weil selbst einfache PHP oder Node.js Prozesse überraschend viele, teils selten genutzte Syscalls für Edge Cases wie Signal Handling oder bestimmte Speicherverwaltungsoperationen benötigen. In der Praxis empfiehlt sich deshalb ein iterativer Ansatz: Mit einem sehr restriktiven Profil starten, systematisch blockierte Syscalls über Audit Logs identifizieren, und das Profil schrittweise um die tatsächlich benötigten Syscalls erweitern.


{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": [
        "read", "write", "open", "openat", "close", "stat", "fstat",
        "mmap", "munmap", "brk", "rt_sigaction", "rt_sigprocmask",
        "access", "socket", "connect", "accept4", "epoll_wait",
        "exit", "exit_group", "futex", "clone", "execve"
      ],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

6. Ein eigenes Profil auf einen Container anwenden

Ein fertiges Profil wird bei Docker über --security-opt seccomp=/pfad/zum/profil.json beim Container Start eingebunden und ersetzt dabei das Default Profil vollständig, statt es zu ergänzen. Podman verwendet dieselbe Syntax mit identischer JSON Struktur, was den Wechsel zwischen beiden Runtimes für dieses spezifische Feature reibungslos macht.

Für Kubernetes existiert seit Version 1.19 ein dedizierter SeccompProfile Abschnitt in der Security Context Definition, der entweder auf das Runtime Default Profil, ein am Node lokal vorhandenes Profil, oder seit 1.27 alternativ auf einen inline definierten Localhost Pfad verweisen kann. Dieser deklarative Ansatz erlaubt es, seccomp Profile als Teil des Deployment Manifests zu versionieren, statt sie manuell auf jedem Node zu pflegen.


# Eigenes Profil beim Container Start einbinden
docker run -d --name shop-php \
  --security-opt seccomp=/etc/docker/seccomp/php-restrictive.json \
  magento-php-fpm:8.4

7. Abwägung zwischen Sicherheit und Kompatibilität

Ein zu restriktives Profil führt zu Anwendungsabstürzen oder mysteriösen Fehlern, die auf den ersten Blick nichts mit Sicherheit zu tun haben, etwa ein PHP Prozess, der bei bestimmten Filesystem Operationen unerklärlich hängen bleibt, weil ein selten aufgerufener, aber notwendiger Syscall blockiert wurde. Ein zu permissives Profil dagegen verliert genau den Schutz, den seccomp eigentlich bieten soll, und degeneriert im Extremfall zu einer reinen Formalität ohne echten Sicherheitsgewinn.

Die pragmatische Faustregel für Produktivumgebungen lautet, mit dem Docker Default Profil zu starten, das bereits einen sinnvollen Kompromiss zwischen breiter Kompatibilität und dem Blockieren offensichtlich gefährlicher Syscalls darstellt, und ein eigenes, restriktiveres Profil nur für hochsensible Workloads zu entwickeln, bei denen der zusätzliche Pflegeaufwand durch das tatsächliche Risikoprofil gerechtfertigt ist, etwa Container mit direktem Zugriff auf sensible Kundendaten oder Zahlungsinformationen.

8. Debugging bei blockierten Syscalls

Ein durch seccomp blockierter Syscall äußert sich je nach konfigurierter Aktion unterschiedlich: Bei SCMP_ACT_ERRNO meldet die Anwendung meist einen scheinbar harmlosen Permission denied oder Function not implemented Fehler, ohne dass der eigentliche Auslöser sofort ersichtlich wird. Der zuverlässigste Weg, den blockierten Syscall konkret zu identifizieren, führt über strace, das jeden Systemaufruf samt Rückgabewert protokolliert und damit exakt zeigt, an welcher Stelle der Prozess auf eine seccomp Blockade läuft.

Für eine systematischere Analyse eignet sich der Audit Modus über SCMP_ACT_LOG statt SCMP_ACT_ERRNO als default Aktion: Blockierte Syscalls werden dann protokolliert statt tatsächlich verweigert, sodass sich über einen repräsentativen Testlauf hinweg alle tatsächlich benötigten Syscalls im Kernel Audit Log oder über journalctl -k sammeln lassen, bevor das Profil im produktiven Modus scharf geschaltet wird.


# Syscalls eines Prozesses live mitschneiden, um blockierte Aufrufe zu finden
strace -f -e trace=all -o /tmp/trace.log php-fpm8.4 -F

# Seccomp bezogene Kernel Audit Meldungen filtern
journalctl -k | grep -i seccomp

9. Praxisrelevanz für Magento-Container

Für einen typischen Magento PHP FPM Container ist das Docker Default Profil in aller Regel ausreichend und deckt sämtliche für die Ausführung von PHP, Composer und die üblichen Filesystem und Netzwerkoperationen benötigten Syscalls bereits ab, ohne dass ein eigenes Profil notwendig wäre. Ein eigenes, restriktiveres Profil lohnt sich vor allem für spezialisierte Hilfscontainer mit stark eingeschränktem Aufgabenbereich, etwa einen dedizierten Cron Container, der ausschließlich planmäßige Magento Indexer Läufe ausführt und keinerlei Netzwerk oder Datei Operationen jenseits dessen benötigt.

Bei allen Härtungsmaßnahmen gilt: seccomp ersetzt keine der übrigen Schutzschichten wie Namespaces, Capabilities oder Read Only Root Filesystems, sondern ergänzt sie um eine zusätzliche, orthogonale Verteidigungslinie. Erst das Zusammenspiel mehrerer unabhängiger Mechanismen macht einen Container Escape für einen Angreifer tatsächlich signifikant schwerer, weil jede einzelne Schicht für sich genommen umgangen werden könnte, während alle gemeinsam einen deutlich robusteren Schutz bilden.

Filter-Aktion Verhalten bei blockiertem Syscall Prozess läuft weiter Typischer Einsatz
SCMP_ACT_ALLOW Syscall wird normal ausgefuehrt ja Whitelist erlaubter Syscalls
SCMP_ACT_ERRNO Syscall schlaegt mit definiertem Fehlercode fehl ja, sofern Anwendung Fehler abfaengt Produktivumgebungen, sanftes Blockieren
SCMP_ACT_TRAP SIGSYS Signal an den Prozess ausgeloest abhaengig vom eigenen Signal Handler spezialisiertes Fehler Handling
SCMP_ACT_KILL Prozess oder Thread wird sofort beendet nein maximale Haertung, hohes Risiko für Fehlalarme
SCMP_ACT_LOG Syscall wird ausgefuehrt und protokolliert ja Audit Modus zur Profilentwicklung

Mironsoft

Server-Administration, Docker-Hosts und Performance-Tuning

Linux-Server, die niemand im Team richtig versteht?

Wir übernehmen Setup, Absicherung und Performance-Tuning von Linux-Servern und Docker-Hosts für Magento-Deployments, dokumentiert und nachvollziehbar statt gewachsen und unklar.

Server-Audit

Bestehende Server-Konfiguration auf Sicherheitslücken und Performance-Bremsen prüfen.

Docker-Host-Setup

Produktionsreife Docker-Umgebungen für Magento sauber aufsetzen und absichern.

Monitoring & Tuning

Ressourcenverbrauch messen und Systemd, Kernel und Dienste gezielt optimieren.

10. Zusammenfassung

seccomp

Grundprinzip

BPF basierte Filterung erlaubter und blockierter Syscalls pro Prozess

Docker Default

Etwa 44 von über 300 Syscalls blockiert, breite Kompatibilitaet

Eigenes Profil

Whitelist Ansatz, iterativ über Audit Logs entwickelt

Debugging Werkzeug

strace für akute Fälle, SCMP_ACT_LOG für systematischen Audit

11. FAQ: seccomp

1Was ist der Unterschied zwischen seccomp und Capabilities?
Capabilities steuern, welche privilegierten Operationen ein Prozess ausführen darf, seccomp dagegen begrenzt direkt, welche Systemaufrufe überhaupt möglich sind. Ein Syscall bleibt seccomp blockiert, selbst wenn die passende Capability vorhanden wäre, weil beide Mechanismen unabhaengig voneinander greifen.
2Blockiert das Docker Default Profil viele Syscalls?
Von den über 300 verfügbaren Linux Syscalls blockiert das Docker Default Profil etwa 44, darunter reboot, swapon und Syscalls zur Kernel Modul Verwaltung. Der weitaus größere Rest bleibt erlaubt, um breite Anwendungskompatibilitaet sicherzustellen.
3Kann ein seccomp Filter nachtraeglich gelockert werden?
Nein, ein einmal gesetzter seccomp Filter kann nur durch zusätzliche, restriktivere Filter verschaerft, aber nie wieder gelockert werden. Dieses Einwegdesign verhindert, dass ein kompromittierter Prozess seine eigenen Beschraenkungen aufhebt.
4Wie erkenne ich, dass ein Fehler durch seccomp verursacht wird?
Typische Symptome sind scheinbar unmotivierte Permission denied oder Function not implemented Fehler. Der zuverlaessigste Weg zur Bestaetigung ist strace, das jeden Systemaufruf mit Rueckgabewert protokolliert und die genaue Fehlstelle sichtbar macht.
5Sollte ich seccomp für Produktivcontainer deaktivieren, wenn Probleme auftreten?
Nein, das vollstaendige Deaktivieren über unconfined sollte ausschliesslich für isoliertes, kurzzeitiges Debugging reserviert bleiben. Für produktive Fälle ist die gezielte Erweiterung des Profils um den tatsaechlich benoetigten Syscall die richtige Lösung.
6Wie entwickle ich ein eigenes seccomp Profil ohne Anwendungsabstuerze zu riskieren?
Am sichersten ist ein iterativer Ansatz mit SCMP_ACT_LOG als Default Aktion statt SCMP_ACT_ERRNO: Blockierte Syscalls werden dann protokolliert statt tatsaechlich verweigert, sodass sich alle benoetigten Syscalls über einen Testlauf hinweg sammeln lassen.
7Funktioniert seccomp genauso bei Podman wie bei Docker?
Ja, Podman verwendet dieselbe JSON Profilstruktur und dieselbe security-opt Syntax wie Docker, wodurch bestehende seccomp Profile ohne Anpassung zwischen beiden Runtimes übertragbar sind.
8Ist SCMP_ACT_KILL für Produktivumgebungen empfehlenswert?
Meist nicht, weil ein übersehener, aber legitimer Syscall dann die gesamte Anwendung sofort beendet statt nur einen einzelnen Fehler auszuloesen. SCMP_ACT_ERRNO gilt in der Praxis als der pragmatischere Kompromiss.
9Braucht ein einfacher PHP FPM Container für Magento ein eigenes seccomp Profil?
In den meisten Fällen nicht, das Docker Default Profil deckt die für PHP, Composer und uebliche Filesystem Operationen benoetigten Syscalls bereits ab. Ein eigenes Profil lohnt sich vor allem für stark spezialisierte Hilfscontainer mit engem Aufgabenbereich.
10Ersetzt seccomp andere Sicherheitsmassnahmen wie Namespaces?
Nein, seccomp ist eine zusätzliche, orthogonale Schutzschicht und ersetzt weder Namespaces noch Capabilities oder Read Only Root Filesystems. Erst das Zusammenspiel mehrerer unabhaengiger Mechanismen erschwert einen Container Escape wirklich signifikant.