Veröffentlicht am

Node Security: Kubernetes-Worker absichern

Teilen:
Authors

Node Security: So härten Sie Ihre Kubernetes-Worker-Nodes

TL;DR

Worker Nodes sind die Angriffsfläche, die oft vergessen wird. Während Teams RBAC und Network Policies konfigurieren, läuft der Kubelet mit offenen Ports und die Container-Runtime ohne Isolation. Dieser Guide zeigt, wie Sie Kubelet absichern, CIS Benchmarks automatisiert prüfen, OS-Updates automatisieren und mit gVisor oder Kata Containers eine zusätzliche Isolationsschicht einziehen.


Der API Server bekommt die meiste Aufmerksamkeit beim Cluster-Hardening. Aber Angriffe zielen häufig auf die Worker Nodes selbst: Ein Container-Escape, ein offener Kubelet-Port oder ein ungepatchtes Betriebssystem reichen aus, um den gesamten Cluster zu kompromittieren.

# Prüfen, ob der Kubelet Read-Only-Port offen ist
curl -s http://<node-ip>:10255/pods | jq '.items[].metadata.name'
# Wenn hier Pod-Namen erscheinen: der Node ist verwundbar

Wenn dieser Befehl eine Liste von Pods zurückgibt, kann jeder im Netzwerk ohne Authentifizierung sehen, welche Workloads auf dem Node laufen.

Kubelet absichern

Der Kubelet ist der Agent auf jedem Worker Node. Er empfängt Anweisungen vom API Server und verwaltet die Container. In der Standardkonfiguration hat er mehrere Schwachstellen.

Read-Only-Port deaktivieren

Port 10255 liefert ohne Authentifizierung Metriken und Pod-Informationen. Deaktivieren Sie ihn:

# /var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
readOnlyPort: 0
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: true
    cacheTTL: 2m0s
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s
protectKernelDefaults: true
eventRecordQPS: 5
rotateCertificates: true
serverTLSBootstrap: true
tlsMinVersion: VersionTLS12

Die wichtigsten Einstellungen im Detail:

ParameterWertWirkung
readOnlyPort: 0DeaktiviertKein unauthentifizierter Zugriff auf Port 10255
anonymous.enabled: falseDeaktiviertAlle Anfragen müssen authentifiziert sein
authorization.mode: WebhookAPI ServerKubelet fragt API Server für Autorisierung
protectKernelDefaults: trueAktiviertKubelet startet nicht, wenn Kernel-Parameter unsicher sind
rotateCertificates: trueAktiviertAutomatische Zertifikatsrotation

Kubelet-Flags für zusätzliche Härtung

Neben der Konfigurationsdatei gibt es Flags, die direkt beim Kubelet-Start gesetzt werden:

# /etc/systemd/system/kubelet.service.d/10-hardening.conf
[Service]
ExecStart=
ExecStart=/usr/bin/kubelet \
  --config=/var/lib/kubelet/config.yaml \
  --container-runtime-endpoint=unix:///run/containerd/containerd.sock \
  --make-iptables-util-chains=true \
  --streaming-connection-idle-timeout=5m

Das Flag --streaming-connection-idle-timeout=5m beendet inaktive kubectl exec-Sitzungen nach 5 Minuten. Standardmäßig bleiben diese Verbindungen unbegrenzt offen.

CIS Benchmarks mit kube-bench prüfen

Der CIS Kubernetes Benchmark definiert über 200 Prüfpunkte für die sichere Konfiguration. kube-bench automatisiert diese Prüfung.

# kube-bench als DaemonSet auf allen Nodes ausführen
kubectl apply -f - <<EOF
apiVersion: batch/v1
kind: Job
metadata:
  name: kube-bench-node
  namespace: kube-system
spec:
  template:
    spec:
      hostPID: true
      nodeSelector:
        node-role.kubernetes.io/worker: ""
      containers:
        - name: kube-bench
          image: aquasec/kube-bench:v0.8.0
          command: ["kube-bench", "run", "--targets=node", "--json"]
          volumeMounts:
            - name: var-lib-kubelet
              mountPath: /var/lib/kubelet
              readOnly: true
            - name: etc-systemd
              mountPath: /etc/systemd
              readOnly: true
            - name: etc-kubernetes
              mountPath: /etc/kubernetes
              readOnly: true
      restartPolicy: Never
      volumes:
        - name: var-lib-kubelet
          hostPath:
            path: /var/lib/kubelet
        - name: etc-systemd
          hostPath:
            path: /etc/systemd
        - name: etc-kubernetes
          hostPath:
            path: /etc/kubernetes
  backoffLimit: 0
EOF

# Ergebnisse auswerten
kubectl -n kube-system logs job/kube-bench-node | jq '.Controls[].tests[].results[] | select(.status == "FAIL")'

Die häufigsten Findings bei Node-Checks:

  • 4.2.1: Kubelet-Authentifizierung nicht aktiviert
  • 4.2.2: Kubelet-Autorisierung auf AlwaysAllow
  • 4.2.6: protectKernelDefaults nicht gesetzt
  • 4.2.10: Read-Only-Port aktiv
  • 4.2.12: Zertifikatsrotation deaktiviert

Alle diese Punkte werden durch die oben gezeigte Kubelet-Konfiguration behoben.

Betriebssystem-Härtung

Die Node-Sicherheit beginnt beim Betriebssystem. Verwenden Sie minimale, auf Container optimierte Distributionen.

Empfohlene Node-Betriebssysteme

Für Kubernetes-Nodes eignen sich spezialisierte Distributionen besser als vollwertige Server-Betriebssysteme:

  • Flatcar Container Linux: Automatische Updates, unveränderliches Dateisystem, minimale Angriffsfläche
  • Bottlerocket (AWS): Von Amazon entwickelt, SELinux standardmäßig aktiv
  • Talos Linux: API-gesteuertes OS ohne SSH, keine Shell

Falls Sie Ubuntu oder RHEL verwenden, minimieren Sie die installierte Software:

# Unnötige Pakete entfernen (Ubuntu)
apt purge -y telnet rsh-client rsh-redone-client
apt autoremove -y

# Automatische Sicherheitsupdates aktivieren
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades

# Kernel-Parameter härten
cat >> /etc/sysctl.d/99-kubernetes-hardening.conf <<SYSCTL
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.log_martians = 1
kernel.panic = 10
kernel.panic_on_oops = 1
vm.overcommit_memory = 1
SYSCTL

sysctl --system

Container-Runtime-Isolation mit gVisor und Kata Containers

Die Standard-Container-Runtime (runc) teilt sich den Host-Kernel mit allen Containern. Ein Kernel-Exploit in einem Container gefährdet den gesamten Node. Sandbox-Runtimes schaffen eine zusätzliche Isolationsschicht.

gVisor (runsc) einrichten

gVisor implementiert einen eigenen User-Space-Kernel, der Syscalls abfängt und filtert:

# RuntimeClass für gVisor
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: gvisor
handler: runsc
scheduling:
  nodeSelector:
    runtime.kubernetes.io/gvisor: "true"
---
# Pod mit gVisor-Runtime starten
apiVersion: v1
kind: Pod
metadata:
  name: sandboxed-app
  namespace: production
spec:
  runtimeClassName: gvisor
  containers:
    - name: app
      image: registry.example.com/app:v2.1.0
      securityContext:
        runAsNonRoot: true
        readOnlyRootFilesystem: true
        allowPrivilegeEscalation: false
        capabilities:
          drop: ['ALL']
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 500m
          memory: 256Mi

Vergleich der Container-Runtimes

Kriteriumrunc (Standard)gVisor (runsc)Kata Containers
IsolationsschichtKernel-NamespacesUser-Space-KernelMicroVM (QEMU)
Syscall-OverheadKeiner5-30%2-10%
Speicher-OverheadMinimal~50 MB pro Sandbox~100 MB pro VM
KompatibilitätVollständigEingeschränkt (nicht alle Syscalls)Vollständig
SicherheitsniveauBasisHochSehr hoch

Für die meisten Workloads bietet gVisor den besten Kompromiss zwischen Sicherheit und Performance. Kata Containers eignen sich für besonders sensible Workloads, bei denen vollständige Kernel-Isolation erforderlich ist.

Node-Monitoring für Security-Events

Gehärtete Nodes müssen überwacht werden. Richten Sie Alerts für sicherheitsrelevante Ereignisse ein:

# Falco-Regeln für Node-Security
- rule: Unauthorized Process on Node
  desc: Erkennt unerwartete Prozesse auf Worker Nodes
  condition: >
    spawned_process and
    container.id = host and
    not proc.name in (kubelet, containerd, runc, systemd)
  output: >
    Unerwarteter Prozess auf Node gestartet
    (user=%user.name command=%proc.cmdline node=%evt.hostname)
  priority: WARNING

- rule: Kubelet Config Modified
  desc: Erkennt Änderungen an der Kubelet-Konfiguration
  condition: >
    open_write and
    fd.name startswith /var/lib/kubelet/
  output: >
    Kubelet-Konfiguration geändert
    (file=%fd.name user=%user.name command=%proc.cmdline)
  priority: CRITICAL

FAQ

Wie härte ich Nodes in Managed Kubernetes (EKS, AKS, GKE)?

Bei Managed Kubernetes verwaltet der Cloud-Provider die Nodes teilweise. EKS erlaubt eigene AMIs mit gehärteter Konfiguration. AKS bietet --enable-node-restriction und CIS-gehärtete Node-Images. GKE hat Container-Optimized OS und Shielded Nodes. Kubelet-Konfiguration ist bei allen Anbietern über Node-Pool-Einstellungen möglich.

Bricht gVisor bestehende Anwendungen?

gVisor unterstützt nicht alle Linux-Syscalls. Anwendungen, die auf spezifische Kernel-Features angewiesen sind (z.B. iptables, bestimmte Dateisystem-Operationen), funktionieren möglicherweise nicht. Testen Sie gVisor immer zuerst in einer Staging-Umgebung. Die meisten Web-Anwendungen und APIs laufen problemlos.

Wie oft sollte kube-bench ausgeführt werden?

Führen Sie kube-bench nach jeder Konfigurationsänderung und mindestens wöchentlich als Cronjob aus. In regulierten Umgebungen (BSI, NIS2) empfiehlt sich eine tägliche Ausführung mit automatisierter Benachrichtigung bei neuen Findings.

Muss ich SSH auf Worker Nodes deaktivieren?

Für maximale Sicherheit ja. Nutzen Sie stattdessen kubectl debug node/<node-name> für Troubleshooting. Wenn SSH notwendig ist, beschränken Sie den Zugang auf ein Bastion Host und erlauben nur Key-basierte Authentifizierung mit kurzen Zertifikatslaufzeiten.

Was ist der Unterschied zwischen Node-Hardening und Pod-Hardening?

Node-Hardening sichert das Betriebssystem und den Kubelet ab -- es schützt die Infrastruktur. Pod-Hardening (SecurityContext, Pod Security Standards) sichert die Workloads ab. Beides ist notwendig: Ein gehärteter Pod auf einem ungehärteten Node ist nur halb geschützt.


Kubernetes ohne DevOps-Overhead?

Wir betreiben Ihre Kubernetes-Cluster 24/7 – Sie fokussieren auf Ihr Kerngeschäft. Ab 4.000€/Monat, DSGVO-konform, mit deutschem Support.

24/7 SupportDeutsche RechenzentrenDSGVO-konform

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen