Self-Hosting boomt – und damit auch die Angriffsfläche. Wer Docker-Container oder einen kleinen Kubernetes-Cluster betreibt, ohne eine Sicherheits-Baseline durchzusetzen, macht sein Heimnetz oder Bürosystem zur offenen Scheune. Dieser Artikel zeigt, was in der Praxis tatsächlich funktioniert: von Netzwerk-Isolation über Secret-Management bis zum sicheren Umgang mit Container-Images.
Warum „es ist ja nur Homelab“ keine Strategie ist
Automatisierte Internet-Scanner tasten innerhalb von Minuten nach offenen Ports. Ein schlecht gesicherter Docker-Host mit öffentlich erreichbarer API oder ein Kubernetes-Dashboard ohne Authentifizierung sitzt in derselben Schusslinie wie ein Unternehmensserver. Botnet-Recruitment, Ransomware, Pivot-Angriffe ins Heimnetz – das sind keine akademischen Szenarien. Sie passieren täglich, auch auf Raspberry-Pis und kleinen VPS-Instanzen.
Das wachsende Interesse an Datenhoheit treibt viele dazu, Dienste wie Nextcloud, Vaultwarden oder Heimdall selbst zu betreiben. Das ist vernünftig. Aber der Schritt vom „schnell ausprobiert“ zum „sicher betrieben“ erfordert ein paar konsequente Entscheidungen, die man einmal trifft und dann als Template wiederholt. Kein Hexenwerk, aber auch kein Selbstläufer.
Ich sehe in Foren regelmäßig Setups, bei denen Port 8080, 9000 und 5432 direkt ins Internet gemappt sind, weil „der Reverse Proxy noch nicht eingerichtet ist“. Monatelang. Das ist kein Edge Case.
Netzwerk-Isolation: Ports schließen, bevor man sie öffnet
Die wichtigste Grundregel beim Docker-Betrieb: Kein Port wird veröffentlicht, den man nicht bewusst entschieden hat zu exponieren. Die Standardarchitektur für ein kleines Self-Hosting-Setup lautet: Router → Reverse Proxy (Traefik oder Nginx Proxy Manager) → interne Docker-Netzwerke. Nach außen offen sind exklusiv Port 443 und 80, optional Port 22 mit Fail2ban-Absicherung.
Docker-Netzwerke sind dabei kein optionaler Komfort, sondern ein Sicherheitsmechanismus. Wer alle Container im Default-Bridge-Netzwerk laufen lässt, erlaubt ihnen, miteinander zu kommunizieren, ohne dass das explizit gewollt ist. Besser: Für jede Applikationsgruppe ein eigenes benanntes Netzwerk anlegen. Der Reverse Proxy hängt in allen Netzwerken, die er routen soll. Datenbank-Container haben keinen Zugang zum externen Netzwerk.
Für Services, die hinter dem Reverse Proxy laufen, gehört die Port-Bindung an 127.0.0.1 – nicht an 0.0.0.0. Ein direkter externer Zugriff am Proxy vorbei ist damit strukturell ausgeschlossen. Wer VPN-Zugang für Admin-Oberflächen nutzt, anstatt diese über den Proxy ins Netz zu hängen, schläft ruhiger. Das gilt besonders für Monitoring-Dashboards und Datenbank-Frontends.
Rechte, Capabilities und der privilegierte Container-Irrtum
Container als Root-User zu betreiben ist der am weitesten verbreitete Fehler in Homelab-Setups. Viele ältere Docker-Images setzen Root als Standard voraus, weil das der bequeme Default ist. In der Praxis bedeutet das: Wenn der Container kompromittiert wird, läuft der Angreifer-Prozess mit UID 0. Auf dem Host ist das je nach Setup direkt eskalierbar.
Die Gegenstrategie ist schlicht: In der docker-compose.yml mit user: "1000:1000" einen nicht-privilegierten User setzen, sofern das Image das unterstützt. Capabilities per cap_drop: [ALL] vollständig entfernen und nur gezielt wieder hinzufügen, was der Prozess tatsächlich braucht. Zusätzlich security_opt: [no-new-privileges=true] setzen – das verhindert, dass ein Prozess über setuid/setgid-Bits an zusätzliche Rechte kommt.
Der privileged: true-Modus ist in 99 Prozent der Homelab-Setups nicht nötig. Er gibt dem Container nahezu vollen Zugriff auf den Host-Kernel. Wer ihn trotzdem setzt – oft aus Faulheit beim Debuggen – sollte ihn spätestens dann entfernen, wenn der Container produktiv geht. Gleiches gilt für das Mounten des Docker-Sockets (/var/run/docker.sock) in Container: Das ist faktisch ein Root-Bypass auf den Docker-Daemon und sollte gemieden oder über einen restriktiven Proxy-Layer abgeschirmt werden.
Read-Only-Root-Filesystem wo möglich: read_only: true in der Compose-Definition, kombiniert mit explizit definierten beschreibbaren Volumes nur für die Verzeichnisse, die der Prozess wirklich schreiben muss. Das schränkt die Angriffsfläche für persistente Modifikationen erheblich ein. Konkrete Compose-Snippets für diese Sicherheits-Defaults sind öffentlich dokumentiert und gut wiederverwendbar.
Secret-Management: Was nicht im Git-Repo landen darf
Passwörter, API-Keys und Datenbankzugangsdaten in docker-compose.yml hardzucoden oder in ungeschützte .env-Dateien zu schreiben, ist der zweithäufigste ernsthafte Fehler. Ein versehentlicher git push reicht, um Secrets öffentlich zu machen – inklusive aller forks und forks-of-forks auf GitHub.
Die pragmatischste Lösung für kleine Teams: Docker Secrets für Swarm-Setups oder Kubernetes Secrets für K8s-Deployments nutzen. Für reine Compose-Setups auf einem einzelnen Host funktionieren Umgebungsvariablen, die ausschließlich auf dem Host gesetzt werden (export DB_PASSWORD=... in einer systemd-Unit oder einem Host-seitigen .env, das nicht ins Repository committed wird). Die .gitignore muss .env und alle Dateien mit Credentials konsequent ausschließen.
Wer einen Schritt weiter gehen will: HashiCorp Vault ist auch im Self-Hosting-Kontext betreibbar, hat aber selbst Betriebsaufwand. Für Homelabs ist oft ein passwortgeschützter, verschlüsselter Secrets-Store wie Vaultwarden oder Bitwarden Self-Hosted in Kombination mit sauberer Env-Variable-Übergabe ausreichend und wartbarer als ein eigener Vault-Cluster.
Kubernetes Secrets sind in der Standardinstallation base64-kodiert, aber nicht verschlüsselt. Für produktive Cluster – auch kleine – empfiehlt sich Encryption at Rest für den etcd-Store. Das ist in den offiziellen Kubernetes-Dokumentationen beschrieben und in K3s über entsprechende Flags aktivierbar.

Image-Updates und Vulnerability-Scanning: kein „set and forget“
Container-Images werden nicht automatisch sicherer, weil sie einmal sauber gebaut wurden. Basis-Images wie debian:bookworm-slim oder alpine:3.20 erhalten regelmäßig Sicherheits-Patches. Wer seine Images nie neu baut oder neue Upstream-Images zieht, läuft auf veralteten Paketen – mit entsprechenden CVEs.
Das latest-Tag ist im produktiven Betrieb eine Falle. Es zieht bei jedem docker pull eine möglicherweise inkompatible neue Version. Feste Tags oder besser: Image-Digests (image: nginx@sha256:abc123...) geben reproduzierbare Deployments. Update-Tooling wie Renovate oder Dependabot kann PRs für neue Tags generieren, die man bewusst reviewed und merged.
Für Vulnerability-Scanning von Images eignen sich Tools wie Trivy oder Grype. Beide lassen sich lokal ausführen und in CI-Pipelines integrieren. Ein wöchentlicher Scan der eigenen Images gegen aktuelle CVE-Datenbanken ist für kleine Teams realistisch umsetzbar. Container-Security-Best-Practices empfehlen das Image-Scanning explizit als zentralen Baustein – nicht als optionales Add-on.
Für automatisierte Pull-and-Restart-Zyklen gibt es Watchtower – ein beliebtes Tool im Homelab-Kontext. Es prüft laufende Container auf neue Image-Versionen und startet sie neu. Praktisch, aber Vorsicht: Wer Watchtower auf latest-Tags loslässt, aktualisiert unkontrolliert. Die sicherere Konfiguration nutzt Watchtower im Monitor-only-Modus oder mit festem Update-Zeitfenster und exakten Tag-Filtern.
Kubernetes für kleine Teams: K3s, kube-bench und was man wirklich braucht
Kubernetes lohnt sich für kleine Teams erst, wenn mehrere Knoten, Hochverfügbarkeit oder automatisiertes Scaling tatsächlich gebraucht werden. Für die meisten Homelab-Szenarien mit fünf bis zwanzig Containern ist Docker Compose auf einem gut gehärteten Host einfacher zu betreiben, besser zu verstehen und weniger Angriffsfläche.
Wenn K8s es sein soll: K3s ist die vernünftige Wahl für ressourcensparende On-Premise-Deployments. Es bringt einen reduzierten Footprint und ist offiziell CNCF-zertifiziert. Der API-Server darf nicht direkt aus dem Internet erreichbar sein – Zugang ausschließlich über SSH-Jumphost oder VPN. Ein öffentlich erreichbarer Kubernetes-API-Server ist ein hochpriorisiertes Angriffsziel.
Netzwerk-Policies sind in Standard-K8s-Installationen oft nicht aktiv. Ohne sie können alle Pods im Cluster miteinander kommunizieren. Eine Default-Deny-Policy für eingehenden Traffic zu Pods, kombiniert mit gezielten Allow-Regeln, ist Pflicht. Das CNI-Plugin muss Network Policies unterstützen – Flannel tut das nicht nativ, Calico oder Cilium schon.
Das Tool kube-bench prüft eine laufende Cluster-Konfiguration gegen CIS-Benchmarks und gibt konkrete Handlungsempfehlungen aus. Für jeden, der einen selbst verwalteten Cluster in Betrieb nehmen will, ist ein kube-bench-Durchlauf vor dem Go-Live kein optionaler Schritt. RBAC-Regeln und Service-Accounts nach dem Prinzip minimaler Rechte konfigurieren: Kein Pod braucht Cluster-Admin-Rechte, nur weil das einfacher zu konfigurieren ist. Kubernetes-Härtung im Detail deckt OS-Baseline, etcd-Verschlüsselung und API-Sicherung systematisch ab.
Backup-Strategie und Monitoring: Was in kleinen Setups oft fehlt
Volumes sichern. Klingt trivial, wird aber erschreckend oft vergessen oder halbherzig umgesetzt. Ein funktionierendes Backup für Container-Volumes bedeutet: tägliche Snapshots der Datenverzeichnisse, Offsite-Kopie (z. B. rclone zu einem S3-kompatiblen Storage), und regelmäßige Restore-Tests. Ein Backup, das nicht wiederhergestellt wurde, ist kein Backup.
Für Kubernetes-Cluster empfiehlt sich Velero für Cluster-State und PVC-Snapshots. Für reine Docker-Setups reicht ein Shell-Skript, das per Cronjob Volumes komprimiert und verschlüsselt überträgt, oft völlig aus. Wichtig: Kubernetes-Secrets und ConfigMaps ebenfalls sichern – sie leben im etcd-Store und sind bei einem Cluster-Neuaufbau sonst verloren.
Monitoring muss nicht ein vollständiger Prometheus-Grafana-Stack mit AlertManager sein. Für kleine Teams ist Uptime Kuma für Service-Verfügbarkeit ein leichtgewichtiger Einstieg. Loki für Log-Aggregation mit einem minimalen Promtail-Agenten auf dem Host deckt die wichtigsten Log-Quellen ab. Kritisch: Container-Restart-Events und fehlgeschlagene Health-Checks sollten Benachrichtigungen auslösen. Ein Container, der crashloopt, bemerkt man sonst erst, wenn der Service stundenlang ausgefallen ist.
Ressourcenlimits sind kein optionaler Komfort. Ein Container ohne CPU- und Memory-Limits kann den gesamten Host in die Knie zwingen. In Compose: deploy.resources.limits setzen. In Kubernetes: resources.limits in den Pod-Specs. Das ist auch der einzige Schutz gegen einfache Denial-of-Service-Effekte durch fehlerhafte oder kompromittierte Container.
Host-Härtung: Die Basis unterhalb von Docker und K3s
Wer Container absichert, aber den darunterliegenden Host vernachlässigt, baut auf einem unsicheren Fundament. Host-Härtung ist keine optionale Ergänzung, sondern Voraussetzung für alles, was darüber läuft. Einige Maßnahmen, die sich für kleine Teams mit überschaubarem Aufwand umsetzen lassen:
- SSH-Zugang absichern: Passwort-Authentifizierung deaktivieren, ausschließlich SSH-Keys verwenden.
PermitRootLogin noin der sshd_config. Port-Änderung allein ist kein Sicherheitsmerkmal, aber Fail2ban reduziert automatisierte Brute-Force-Versuche spürbar. - Unattended Upgrades aktivieren: Auf Debian- und Ubuntu-basierten Hosts sorgt das Paket
unattended-upgradesdafür, dass Sicherheits-Patches automatisch eingespielt werden. Kernel-Updates erfordern einen Neustart – das lässt sich perneedrestartautomatisieren oder als Maintenance-Window planen. - Firewall-Regeln auf dem Host: UFW oder nftables als zweite Verteidigungslinie hinter dem Router. Docker manipuliert iptables direkt und kann UFW-Regeln umgehen – das ist ein bekanntes Problem. Abhilfe:
DOCKER-USER-Chain in iptables für host-seitige Filterung nutzen oder den Docker-Daemon mit--iptables=falsestarten und Netzwerkregeln vollständig manuell verwalten. - Audit-Logging:
auditdauf dem Host protokolliert sicherheitsrelevante Systemaufrufe. Für Setups, bei denen Nachvollziehbarkeit wichtig ist – etwa in kleinen Teams mit mehreren Admins – ist das ein sinnvoller Schritt, der kaum Overhead erzeugt.
Wer hochsichere Infrastrukturen aufbauen und dabei auch Gerätemanagement und Identität berücksichtigen möchte, findet in ganzheitlichen Ansätzen wertvolle Orientierung – auch wenn der eigene Kontext kleiner ist. Die Grundprinzipien übertragen sich.
Mehrere Admins, geteilte Verantwortung: Zugriffskonzepte für kleine Teams
Self-Hosting im Team bringt eine Dimension ins Spiel, die im Homelab-Einzelbetrieb entfällt: Wer hat Zugriff auf was, und wer hat diesen Zugriff autorisiert? Ohne klares Zugriffskonzept entstehen geteilte Root-Passwörter, persönliche SSH-Keys auf Produktionssystemen und keine Nachvollziehbarkeit, wer wann welche Änderung vorgenommen hat.
Konkrete Maßnahmen für Teams mit zwei bis fünf Personen:
- Individuelle Accounts statt shared Root: Jeder Admin hat einen eigenen Nutzer auf dem Host mit sudo-Rechten. Root-Login ist deaktiviert. Wer ausscheidet, wird sofort aus der Sudo-Gruppe entfernt und sein SSH-Key aus den authorized_keys gelöscht.
- Zugriffsprotokoll: Selbst einfaches Logging in eine zentrale Log-Datei, die alle sudo-Aufrufe und SSH-Logins aufzeichnet, schafft Nachvollziehbarkeit. In Kubernetes lässt sich das über Audit-Logging des API-Servers lösen, das in K3s konfigurierbar ist.
- Secrets nie per Chat oder E-Mail teilen: Wer Credentials über Slack oder E-Mail verteilt, verliert die Kontrolle über deren Lebenszyklus. Ein gemeinsamer, verschlüsselter Passwort-Manager – etwa Vaultwarden im Self-Hosted-Betrieb – ist die saubere Alternative. Geteilte Einträge können dort bei Bedarf rotiert werden, ohne dass alle Beteiligten informiert werden müssen.
- Deployment-Prozess dokumentieren: Eine kurze README im Repository, die beschreibt, wie neue Services deployed werden, welche Sicherheits-Defaults Pflicht sind und wer welche Entscheidungen trifft, reduziert Reibung und verhindert, dass unter Zeitdruck unsichere Abkürzungen genommen werden.
Der organisatorische Aspekt wird in technischen Ratgebern zu Self-Hosting regelmäßig unterschätzt. Technische Maßnahmen greifen nur dann zuverlässig, wenn sie auch bei Zeitdruck, Personalwechsel und wachsender Dienstezahl konsequent angewendet werden. Ein schriftlich vereinbartes, minimales Sicherheitskonzept – selbst ein einseitiges Dokument – ist in kleinen Teams oft wirksamer als das technisch aufwändigste Setup ohne gemeinsames Verständnis dahinter.
Was bleibt und was als nächstes zu tun ist
Die Sicherheits-Baseline für ein produktives Self-Hosting-Setup mit Docker oder K3s ist kein monolithisches Projekt. Sie ist eine Sammlung von Defaults, die man einmal sauber aufschreibt und dann als Template für jeden neuen Dienst verwendet: kein Root, keine offenen Ports am Proxy vorbei, Secrets aus Env-Variablen auf dem Host, feste Image-Tags, wöchentlicher Scan, tägliche Volume-Backups mit Restore-Test, Monitoring-Alert auf Restart-Events.
Wer Kubernetes wirklich braucht, prüft das ehrlich: Brauche ich Multi-Node-Redundanz? Automatisches Scheduling? Horizontale Skalierung? Wenn nein – Docker Compose auf einem gehärteten Host ist die wartbarere Wahl. Wenn ja – K3s mit konsequentem RBAC, Network Policies und kube-bench-Durchlauf vor dem Go-Live.
Die eigentliche Frage ist nicht, ob Self-Hosting sicher sein kann. Die Frage ist, ob man bereit ist, die Defaults konsequent zu überdenken – und nicht erst dann, wenn der erste Alert kommt.





Was halten Sie von dem Thema? Hier können Sie mit anderen Leserinnen und Lesern ins Gespräch gehen.
Mitreden & diskutieren
Ihre Meinung zählt — teilen Sie Gedanken, Fragen oder Erfahrungen zu diesem Artikel.