Den Docker-Socket absichern - das unterschätzte Sicherheitsrisiko

Den Docker-Socket absichern - das unterschätzte Sicherheitsrisiko

Der Docker-Socket /var/run/docker.sock ist effektiv ein root-Shell auf dem Host — wer ihn in einen Container mountet, gibt diesem Container vollen Host-Zugriff.

Warum der Socket so mächtig ist

# Container mit Socket-Zugriff kann auf dem Host alles tun:
docker run -v /var/run/docker.sock:/var/run/docker.sock alpine \
  docker run -v /:/host --rm alpine chroot /host   # Host-Filesystem vollständig gemountet
  • Wer den Docker-Socket hat, kann:
  • Neue Container starten (auch privilegierte)
  • Host-Verzeichnisse mounten
  • Laufende Container inspecten (inkl. ENV-Variablen mit Secrets)
  • Den Docker-Daemon selbst steuern

Wer den Socket wirklich braucht

Einige legitime Tools brauchen den Socket:

  • Traefik: Auto-Discovery von Containern
  • Portainer: Container-Management
  • Watchtower: Automatische Image-Updates
  • Dozzle: Log-Viewer

Die Frage ist nicht, ob man ihn mountet, sondern wie man das Risiko begrenzt.

Mitigation 1: Socket-Proxy (empfohlen)

tecnativa/docker-socket-proxy sitzt zwischen Tool und Socket und exposed nur bestimmte API-Endpunkte:

services:
  socket-proxy:
    image: tecnativa/docker-socket-proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      CONTAINERS: 1    # Erlaubt: /containers/*
      SERVICES: 0      # Verboten: /services/*
      TASKS: 0
      NETWORKS: 1
      IMAGES: 0        # Verboten: Images pullen/pushen
      INFO: 1
      PING: 1
      POST: 0          # Alle POST-Requests (Schreib-Ops) verboten
    networks:
      - socket-proxy   # Isoliertes Netzwerk

  traefik:
    image: traefik:v3.0
    environment:
      DOCKER_HOST: tcp://socket-proxy:2375   # Via Proxy, nicht direkt
    networks:
      - socket-proxy
      - public

networks:
  socket-proxy:
    internal: true     # Kein Internet-Zugriff aus diesem Netz
  public:

Traefik sieht nur Container-Listen, kann aber keine neuen Container starten oder Images pullen.

Mitigation 2: Rootless Docker

# Docker im Rootless-Modus installieren
dockerd-rootless-setuptool.sh install

# Socket liegt dann unter:
$XDG_RUNTIME_DIR/docker.sock

Im Rootless-Modus läuft der Docker-Daemon ohne root-Rechte. Ein kompromittierter Container kann nicht auf root-Ressourcen des Hosts zugreifen.

Docker TCP: niemals ohne TLS

# GEFÄHRLICH: Ungesicherter TCP-Zugriff
dockerd -H tcp://0.0.0.0:2375    # Jeder im Netz hat root-Zugriff

# Sicher: Mit TLS-Zertifikaten
dockerd -H tcp://0.0.0.0:2376 --tlsverify \
  --tlscacert=ca.pem \
  --tlscert=server-cert.pem \
  --tlskey=server-key.pem

Port 2375 (ungesichert) sollte niemals öffentlich erreichbar sein. Wer Docker remote verwalten will: SSH-Tunneling ist die sichere Alternative.

# Remote Docker via SSH (kein offener Port nötig)
docker -H ssh://user@remote-host ps
DOCKER_HOST=ssh://user@remote-host docker ps

Wer darf auf den Socket zugreifen?

ls -la /var/run/docker.sock
# srw-rw---- root docker

# Nur Mitglieder der docker-Gruppe
usermod -aG docker deployuser

Die docker-Gruppe ist für alle praktischen Zwecke gleichwertig mit root. Mitgliedschaft nur für vertrauenswürdige Accounts.

Socket-Zugriff im Audit-Log

# Mit auditd überwachen wer den Socket nutzt
auditctl -w /var/run/docker.sock -p rwxa -k docker-socket
ausearch -k docker-socket

Checkliste Socket-Sicherheit

  • Socket-Proxy für Tools wie Traefik und Portainer
  • Kein :2375 offen ohne TLS
  • Rootless Docker wo möglich
  • docker-Gruppe minimal besetzt
  • Keine Produktions-Apps bekommen den Socket

Der Docker-Socket ist das wertvollste Angriffsziel auf einem Docker-Host — und er wird in vielen Setups sorglos gemountet.

Weiterführend

Wer sich tiefer mit Linux-Sicherheit, Dateiberechtigungen und Systemhärtung befasst, findet passende Artikel auf nolr.nexon.cyou.