Begriff
Unprivileged Container
Warum wichtig?
Dieser Begriff ist ein Knoten im SengakujiWorks-Wissensnetz. Nutze Level 0 für die erste Einordnung, Level 1 für Praxis, Level 2 für technische Struktur und Level 3 für Grenzen, Fallstricke und Expertenkontext.
Standardmäßig ist der "Root"-User im Docker Container auch der "Root"-User auf dem Host-Server. Er hat zwar eingeschränkte Sicht (Namespaces), aber wenn er ausbricht (Container Escape), ist er Gott auf deinem Server. Ein Unprivileged Container läuft zwar im Container als "Root" (UID 0), ist aber auf dem Host ein Niemand (UID 1001). Selbst wenn der Hacker ausbricht, hat er auf dem Server keine Rechte. Er kann nichts löschen, nichts installieren. Das ist der Goldstandard für Container-Sicherheit.
Merksatz: Ein Container, dessen Prozesse auf dem Host-System einem nicht-privilegierten Benutzer zugeordnet sind (User Namespace Remapping), um die Auswirkungen eines Container-Ausbruchs zu minimieren.
Der einfache Weg (Non-Root User): Im Dockerfile:
USER 1001
Der Prozess läuft als User 1001. Er darf keine Systemdateien anfassen und keine Privileged Ports (< 1024) binden.
Der harte Weg (User Namespace Remapping):
In daemon.json:
"userns-remap": "default"
Docker mappt Container-Root (0) auf Host-User (100000).
Für den Container sieht es aus wie Root. Für den Host ist es User 100000.
Praxisroutine
In der Praxis lernst du Unprivileged Container, indem du mit einem kleinen, kontrollierten Beispiel beginnst. Baue zuerst einen Minimalfall, prüfe das Ergebnis, veraendere genau eine Sache und beobachte, was sich ändert. Notiere dir Eingabe, Aktion, Ausgabe und typischen Fehler.
Übung: Erstelle ein Beispiel aus deinem Alltag, fuehre den Ablauf gedanklich Schritt für Schritt durch und markiere die Stelle, an der du Feedback oder ein Log brauchst. Wenn du diese Stelle benennen kannst, verstehst du den Begriff praktisch.
1. Rootless Docker / Podman
Docker brauchte früher einen Daemon, der als Root lief (dockerd).
Sicherheitsrisiko: Wer mit dem Daemon redet, hat Root-Rechte.
Rootless Docker (und Podman) läuft komplett im Userspace.
Der Daemon selbst gehört deinem User.
Kein sudo docker mehr nötig.
Nutzt newuidmap und newgidmap (SUID binaries), um Namespaces ohne Root aufzubauen.
2. Capabilities Dropping
Auch wenn du als Root im Container läufst, nimmt Docker dir standardmäßig viele Kräfte weg (Linux Capabilities).
CAP_SYS_ADMIN(Der Gott-Modus): Weg.CAP_NET_ADMIN(IPs ändern): Weg. Wenn dudocker run --privilegedmachst, gibst du alle Capabilities zurück. Tu das niemals in Produktion (außer für Docker-in-Docker).
3. Bind Mount Probleme
Bei User Remapping (Host User 1000 -> Container Root 0) gibt es oft Probleme mit Volumes. Du mountest einen Ordner rein. Der Container schreibt eine Datei (als Root). Auf dem Host gehört die Datei User 100000 (Subuid). Du (User 1000) kannst sie nicht lesen/löschen! "Permission Denied". Lösung: Podman macht das oft automatisch besser ("Permission Shift").
1. User Namespace Remapping Deep Dive
Technisch nutzt Linux das User Namespace Feature.
In /etc/subuid wird festgelegt, welche IDs ein User verwenden darf.
Beispiel: Rixx:100000:65536.
Das bedeutet: Der User Rixx darf im Container die UID 0 (Root) nutzen. Der Kernel mappt diese "0" auf die reale UID "100000" auf dem Host.
Wenn der Prozess im Container nun versucht, /etc/shadow des Host-Systems zu lesen, sieht der Kernel den Zugriff von UID 100000. Da /etc/shadow nur für die echte UID 0 lesbar ist, wird der Zugriff verweigert. Der Hacker "denkt" er ist Root, ist aber in einer Sandbox mit einer Pseudo-Identität gefangen.
2. Rootless Networking (slirp4netns)
Ein unprivilegierter Container hat ein Problem: Er darf keine Netzwerk-Interfaces auf dem Host anlegen (Veth-Pairs).
Um trotzdem Internet zu haben, nutzt Rootless-Docker oder Podman das Tool slirp4netns.
Dies emuliert einen kompletten TCP/IP-Stack im Userspace. Es schickt Ethernet-Pakete über einen TAP-Socket und übersetzt sie in normale System-Calls.
Der Preis: Performance. Rootless Networking ist ca. 10-20% langsamer als Root-Networking und hat Probleme mit MTU-Größen und ICMP (Ping funktioniert oft nicht ohne Hacks). In High-Performance Umgebungen muss man dies durch spezialisierte Plugins (wie cni-ovn) optimieren.
3. Das SUID-Dilemma & No-New-Privileges
Obwohl der Container unprivilegiert ist, könnte ein bösartiges Progrämmchen im Container versuchen, über SUID-Binaries (wie sudo) mehr Rechte zu erlangen.
Sicherheitsarchitekten setzen daher in Produktion zusätzlich das Flag --security-opt=no-new-privileges.
Dieser Kernel-Befehl verbietet es einem Prozess und all seinen Kindern, jemals wieder Privilegien zu erhöhen (auch nicht über SUID). Das schließt das letzte Schlupfloch, falls ein Hacker im Container einen Weg finden sollte, vom "Pseudo-Root" zum "Echten Root" zu werden.
Quick-Check
Warum Port 80 Problem?
Nur Root darf Ports < 1024 binden (Linux Regel). Ein unprivilegierter Container (Nginx als User 1001) muss Port 8080 nutzen. (Ab Kernel 4.11 kann man das lockern viasysctl net.ipv4.ip_unprivileged_port_start).Ist "USER 1000" sicher genug?
Viel sicherer als Root. Aber wenn es im Kernel eine Lücke gibt ("Dirty Pipe"), könnte User 1000 trotzdem Root werden. User Namespaces (Remapping) sind eine extra Schicht Sicherheit.Kubernetes?
Man nutztsecurityContextim Pod:runAsNonRoot: true. K8s verweigert den Start, wenn das Image als Root laufen will. Wichtig für Policy (OPA Gatekeeper).