Kubernetes Workshop: Advanced + Security – Übungsaufgaben mit Lösungen
Bezug: 04-advanced-security-DE-aktualisiert.md
Schwierigkeitsgrad: Advanced + Security
Format: Security-Review, Hands-on-Lab, Walkthrough und Musterlösungen
Ziel dieses Übungsdokuments
Dieses Übungsdokument ergänzt den Advanced- und Security-Workshop mit praxisnahen Aufgaben, Review-Checklisten, Musterlösungen und Walkthroughs. Der Schwerpunkt liegt auf Threat Modeling, API Server und Control Plane Hardening, RBAC, Identity, Pod Security Standards, Workload Hardening, RuntimeClass, Network Security, Supply-Chain-Security, Policy-as-Code, Admission Control, Secrets Security, Runtime Detection, Compliance, Evidence und Incident Response.
Arbeite nur in einem Lab-Cluster. Verwende keine produktiven Secrets, keine echten Kundendaten und keine produktiven Cluster-Kontexte.
Voraussetzungen
Du brauchst:
- einen Lab-Cluster
kubectl- Rechte zum Erstellen von Namespaces, ServiceAccounts, RBAC, NetworkPolicies und Test-Workloads
- optional Kyverno, OPA Gatekeeper oder ValidatingAdmissionPolicy-Unterstützung
- optional Trivy, Grype, Cosign oder ein vorbereiteter Supply-Chain-Demo-Flow
- optional Falco, Tetragon, Tracee oder vergleichbare Runtime-Signale
Empfohlener Namespace:
export NS=workshop-security
kubectl create namespace "$NS"
kubectl config set-context --current --namespace="$NS"
Aufgabenübersicht
| Nr. | Thema | Ergebnis |
|---|---|---|
| 1 | Threat Model | Risiken nach API, Node, Workload, Netzwerk, Secrets, Supply Chain |
| 2 | RBAC Audit | effektive Rechte und Eskalationspfade bewertet |
| 3 | ServiceAccount Token | Token-Automount reduziert |
| 4 | Pod Security Restricted | unsichere Pods blockiert und gehärtet |
| 5 | Workload Hardening | SecurityContext fachlich korrekt gesetzt |
| 6 | NetworkPolicy | Default Deny, DNS und App-Traffic kontrolliert |
| 7 | Supply Chain | Image, Tag, Digest, SBOM, Scan und Signatur bewertet |
| 8 | Admission Policy | Required Labels oder SecurityContext erzwungen |
| 9 | Secrets Security | Secret-Flows und Rotation bewertet |
| 10 | Runtime Detection | Signale und Reaktionen definiert |
| 11 | Compliance Evidence | Befund, Risiko, Ausnahme und Fix dokumentiert |
| 12 | Incident Response | Runbook für kompromittierten Pod und Secret Leak |
Teil A – Aufgaben
Aufgabe 1: Kubernetes Threat Model schreiben
Ziel
Du modellierst Sicherheitsrisiken getrennt nach Kubernetes-Angriffsflächen.
Ausgangslage
Eine Beispiel-App besteht aus:
- Namespace
shop-prod, - Deployment
checkout-api, - ServiceAccount
checkout-sa, - Secret
payment-api-token, - Ingress/Gateway-Route,
- privater Registry,
- GitOps-Controller,
- CI-Pipeline.
Arbeitsauftrag
Erstelle threat-model.md mit:
- Assets und Schutzwert,
- Trust Boundaries,
- Angriffsflächen,
- Missbrauchsszenarien,
- vorhandene Kontrollen,
- fehlende Kontrollen,
- Stop-Kriterien,
- Evidence.
Aufgabe 2: RBAC-Audit durchführen
Ziel
Du erkennst zu breite Rechte und Privilege-Escalation-Pfade.
Arbeitsauftrag
- Erstelle zwei ServiceAccounts:
app-saundoverprivileged-sa. - Gib
app-saminimale Leserechte auf ConfigMaps. - Gib
overprivileged-saabsichtlich Rechte auf Secrets und RoleBindings. - Prüfe effektive Rechte mit
kubectl auth can-i. - Dokumentiere Risiken und Fixes.
Aufgabe 3: ServiceAccount Token-Automount reduzieren
Ziel
Du stellst sicher, dass Pods ohne Kubernetes-API-Bedarf kein ServiceAccount-Token automatisch gemountet bekommen.
Arbeitsauftrag
- Erstelle ein Deployment
no-api-app. - Setze
automountServiceAccountToken: false. - Prüfe im Pod, ob
/var/run/secrets/kubernetes.io/serviceaccountvorhanden ist. - Erkläre, wann ein Pod ein Token braucht und wann nicht.
Aufgabe 4: Pod Security Restricted erzwingen
Ziel
Du erzwingst Pod Security Standards im Namespace und korrigierst einen unsicheren Pod.
Arbeitsauftrag
- Setze Namespace-Labels für
restrictedinenforce,auditundwarn. - Erstelle einen unsicheren Pod mit
privileged: true. - Beobachte die Ablehnung.
- Erstelle einen gehärteten Pod, der Restricted-Anforderungen erfüllt.
- Dokumentiere die Unterschiede.
Aufgabe 5: Workload Hardening mit SecurityContext
Ziel
Du übersetzt Workload-Hardening in konkrete Pod- und Container-SecurityContext-Felder.
Arbeitsauftrag
Härtungskriterien:
- nicht als Root laufen,
- Privilege Escalation verbieten,
- Root-Dateisystem read-only,
- alle Linux Capabilities droppen,
- seccomp
RuntimeDefault, - temporäres Schreibverzeichnis über
emptyDir, - keine Host-Namespace-Nutzung.
Erstelle ein Deployment, das diese Kriterien erfüllt.
Aufgabe 6: NetworkPolicy Default Deny mit DNS und App-Erlaubnis
Ziel
Du reduzierst Lateral Movement und erlaubst nur notwendigen Traffic.
Arbeitsauftrag
- Erstelle
frontendundbackend. - Erstelle Default Deny für Ingress und Egress.
- Erlaube DNS-Egress.
- Erlaube
frontendzubackendauf Port 8080. - Blockiere sonstigen Egress.
- Dokumentiere, welche Ausnahmen produktiv zusätzlich nötig wären.
Aufgabe 7: Supply-Chain-Security prüfen
Ziel
Du bewertest einen Kubernetes-Workload aus Supply-Chain-Perspektive.
Arbeitsauftrag
Für ein Beispielimage dokumentierst du:
- Registry,
- Repository,
- Tag,
- Digest,
- Pull Policy,
- ImagePullSecret,
- Scan-Ergebnis,
- SBOM-Status,
- Signaturstatus,
- Admission-Anforderung,
- Stop-Kriterium.
Optional mit Tools:
trivy image <image>
cosign verify <image>@<digest>
Aufgabe 8: Admission Policy schreiben
Ziel
Du formulierst eine Policy, die unsichere oder unvollständige Ressourcen blockiert.
Arbeitsauftrag
Schreibe eine Policy für eines dieser Ziele:
- Required Labels
owner,environment,cost-center, - Verbot von
privileged: true, - Pflicht für
runAsNonRoot: true, - Pflicht für Resource Requests und Limits,
- nur erlaubte Registries.
Nutze je nach Lab Kyverno, OPA Gatekeeper oder eine native ValidatingAdmissionPolicy.
Aufgabe 9: Secrets Security und Rotation bewerten
Ziel
Du unterscheidest Kubernetes Secret, External Secrets, CSI Secret Store, Sealed Secrets und SOPS anhand eines konkreten Risikos.
Arbeitsauftrag
Erstelle secrets-review.md mit:
- Secret-Inventar,
- wer Zugriff hat,
- wo Secrets gemountet werden,
- ob Secrets in Logs oder Events sichtbar werden könnten,
- Rotation-Pfad,
- etcd-/Backup-Risiko,
- Empfehlung für Secret-System,
- Incident-Maßnahme bei Leak.
Aufgabe 10: Runtime Detection einordnen
Ziel
Du definierst Signale, die Runtime Detection oder Audit Logging erkennen soll.
Arbeitsauftrag
Definiere Detection-Regeln oder erwartete Signale für:
- unerwartete Shell im Container,
- Schreibzugriff auf
/etc,/procoder/sys, - unerwarteter Egress,
- Zugriff auf Kubernetes API mit ServiceAccount,
- verdächtiges
kubectl exec, - OOMKill in sicherheitsrelevantem Pod.
Dokumentiere pro Signal: Risiko, Datenquelle, erste Reaktion und Evidence.
Aufgabe 11: Compliance Evidence erstellen
Ziel
Du erstellst einen belastbaren Compliance-Befund mit Risiko, Owner, Ausnahme oder Fix.
Arbeitsauftrag
Erstelle compliance-evidence.md mit mindestens fünf Befunden:
- Namespace ohne Pod-Security-Label,
- ServiceAccount mit zu breiten Rechten,
- Pod ohne Requests/Limits,
- Secret ohne Rotation-Hinweis,
- Workload ohne NetworkPolicy.
Für jeden Befund dokumentierst du:
- Zeitpunkt,
- Ressource,
- Risiko,
- Nachweis,
- Owner,
- Fix,
- Ausnahme mit Ablaufdatum oder Remediation-Frist.
Aufgabe 12: Incident-Runbook schreiben
Ziel
Du formulierst einen Kubernetes-Incident-Response-Pfad für kompromittierten Pod und Secret Leak.
Arbeitsauftrag
Erstelle incident-runbook.md mit:
- Triage,
- Isolation,
- Evidence-Sicherung,
- Containment,
- Secret- und Token-Rotation,
- Image- und CI-Prüfung,
- Rebuild und Redeploy,
- Kommunikation,
- Lessons Learned,
- Policy-Nachschärfung.
Teil B – Lösungen und Walkthroughs
Lösung 1: Threat Model
Musterstruktur:
# Threat Model: checkout-api
## Assets
| Asset | Schutzwert |
| --- | --- |
| payment-api-token | sehr hoch |
| checkout-api Deployment | hoch |
| checkout-sa ServiceAccount | hoch |
| Registry Image | hoch |
| GitOps Repository | sehr hoch |
| Ingress/Gateway Route | mittel bis hoch |
## Trust Boundaries
- Internet zu Ingress/Gateway
- App-Namespace zu Kubernetes API
- Pod zu Secret Store
- CI zu Registry
- GitOps Controller zu Cluster
- Namespace zu anderen Namespaces
## Missbrauchsszenarien
| Szenario | Risiko | Kontrolle |
| --- | --- | --- |
| Pod liest Secret und exfiltriert Token | Zahlungsdatenzugriff | RBAC, Secret-Mount minimieren, NetworkPolicy, Rotation |
| ServiceAccount kann Secrets listen | Secret-Exfiltration | Least Privilege, `can-i`, Audit Logs |
| unsigniertes Image wird deployt | Malware | Signaturprüfung, Digest Pinning, Admission |
| fehlende NetworkPolicy erlaubt Lateral Movement | Ausbreitung | Default Deny, gezielte Egress-Regeln |
| CI hat Cluster-Admin | Pipeline-Kompromittierung wird Cluster-Kompromittierung | GitOps, reduzierte CI-Rechte |
## Stop-Kriterien
- ServiceAccount kann `get/list/watch secrets` ohne fachlichen Bedarf.
- Workload läuft `privileged` ohne Ausnahme.
- Image ist nicht signiert oder nicht gescannt.
- Secret-Rotation nicht möglich.
- keine Evidence für Policy-Ausnahmen.
Lösung 2: RBAC-Audit
ServiceAccounts:
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-sa
namespace: workshop-security
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: overprivileged-sa
namespace: workshop-security
Minimale Role:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: configmap-reader
namespace: workshop-security
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: app-sa-configmap-reader
namespace: workshop-security
subjects:
- kind: ServiceAccount
name: app-sa
namespace: workshop-security
roleRef:
kind: Role
name: configmap-reader
apiGroup: rbac.authorization.k8s.io
Absichtlich riskante Role:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: risky-role
namespace: workshop-security
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "watch"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["create", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: risky-binding
namespace: workshop-security
subjects:
- kind: ServiceAccount
name: overprivileged-sa
namespace: workshop-security
roleRef:
kind: Role
name: risky-role
apiGroup: rbac.authorization.k8s.io
Prüfung:
kubectl apply -f rbac.yml
kubectl auth can-i get configmaps --as system:serviceaccount:workshop-security:app-sa -n workshop-security
kubectl auth can-i get secrets --as system:serviceaccount:workshop-security:app-sa -n workshop-security
kubectl auth can-i get secrets --as system:serviceaccount:workshop-security:overprivileged-sa -n workshop-security
kubectl auth can-i create rolebindings --as system:serviceaccount:workshop-security:overprivileged-sa -n workshop-security
Bewertung:
app-saist akzeptabel, wenn die App ConfigMaps lesen muss.overprivileged-saist kritisch, weil Secret-Lesezugriff und RoleBinding-Erstellung Eskalationspfade öffnen.- Fix: Secret-Zugriff entfernen, RoleBinding-Erstellung entfernen, separate Break-Glass-Prozesse verwenden.
Lösung 3: ServiceAccount Token-Automount
Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: no-api-app
namespace: workshop-security
spec:
replicas: 1
selector:
matchLabels:
app: no-api-app
template:
metadata:
labels:
app: no-api-app
spec:
automountServiceAccountToken: false
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
Prüfung:
kubectl apply -f no-api-app.yml
kubectl rollout status deployment/no-api-app
POD=$(kubectl get pod -l app=no-api-app -o jsonpath='{.items[0].metadata.name}')
kubectl exec "$POD" -- ls -la /var/run/secrets/kubernetes.io/serviceaccount || true
Erwartung:
Der Pfad existiert nicht oder enthält kein automatisch gemountetes Token.
Fachliche Entscheidung:
- Pod braucht Token: Kubernetes API-Zugriff fachlich erforderlich, zum Beispiel Controller.
- Pod braucht kein Token: normale Web-App ohne Cluster-API-Nutzung.
Lösung 4: Pod Security Restricted
Namespace labeln:
kubectl label namespace workshop-security \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted --overwrite
Unsicherer Pod:
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
namespace: workshop-security
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
securityContext:
privileged: true
Erwartung:
kubectl apply -f privileged-pod.yml
Der API Server lehnt den Pod wegen Pod Security Admission ab.
Gehärteter Pod:
apiVersion: v1
kind: Pod
metadata:
name: restricted-pod
namespace: workshop-security
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "sleep 3600"]
securityContext:
runAsUser: 1000
runAsGroup: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Prüfung:
kubectl apply -f restricted-pod.yml
kubectl get pod restricted-pod
kubectl describe pod restricted-pod
Lösung 5: Workload Hardening
Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hardened-app
namespace: workshop-security
spec:
replicas: 1
selector:
matchLabels:
app: hardened-app
template:
metadata:
labels:
app: hardened-app
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
volumes:
- name: tmp
emptyDir: {}
containers:
- name: app
image: busybox:1.36
command: ["sh", "-c", "while true; do echo ok > /tmp/status; sleep 60; done"]
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
runAsGroup: 1000
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
Prüfung:
kubectl apply -f hardened-app.yml
kubectl rollout status deployment/hardened-app
kubectl get pod -l app=hardened-app -o yaml | grep -E 'runAsNonRoot|allowPrivilegeEscalation|readOnlyRootFilesystem|seccompProfile|capabilities' -A3
Erklärung:
readOnlyRootFilesystembenötigt ein separates beschreibbares Verzeichnis, wenn die App schreiben muss.drop: ALLreduziert Kernel-Fähigkeiten.allowPrivilegeEscalation: falseverhindert bestimmte setuid-/setcap-Eskalationen.
Lösung 6: NetworkPolicy
Default Deny:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: workshop-security
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
DNS erlauben:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: workshop-security
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Frontend zu Backend:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: workshop-security
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-egress-to-backend
namespace: workshop-security
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8080
Produktive Zusatzfragen:
- Brauchen Pods Kubernetes-API-Egress?
- Brauchen Pods Registry-, Monitoring- oder Logging-Egress?
- Gibt es externe APIs mit festen Zielen?
- Wird IPv6/Dual-Stack berücksichtigt?
- Erzwingt das CNI diese Policies tatsächlich?
Lösung 7: Supply-Chain-Security
Musterbewertung:
# Supply-Chain-Review
## Image
- Image: registry.example.com/shop/checkout-api:1.4.2
- Digest: sha256:<digest>
- Pull Policy: IfNotPresent oder Always nach Plattformstandard
- Registry: private, zugelassen
- Pull Secret: namespace-spezifisch, rotiert
## Prüfungen
| Prüfung | Ergebnis | Entscheidung |
| --- | --- | --- |
| Tag nicht latest | erfüllt | ok |
| Digest bekannt | erfüllt | ok |
| CVE Scan | 1 High, kein Critical | remediation erforderlich |
| SBOM vorhanden | ja | ok |
| Signatur | gültig | ok |
| Provenance | CI Build-ID vorhanden | ok |
## Stop-Kriterien
- `latest` ohne Digest in Prod.
- Image aus nicht erlaubter Registry.
- Critical CVE ohne Ausnahme.
- fehlende Signatur bei produktiven Workloads.
- Pull Secret ohne Owner oder Rotation.
Optional:
trivy image registry.example.com/shop/checkout-api:1.4.2
cosign verify registry.example.com/shop/checkout-api@sha256:<digest>
Lösung 8: Admission Policy
Kyverno-Beispiel: Required Labels
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-standard-labels
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-owner-environment-cost-center
match:
any:
- resources:
kinds:
- Pod
- Deployment
validate:
message: "owner, environment und cost-center Labels sind erforderlich."
pattern:
metadata:
labels:
owner: "?*"
environment: "?*"
cost-center: "?*"
Kyverno-Beispiel: Privileged verbieten
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-privileged
spec:
validationFailureAction: Enforce
background: true
rules:
- name: privileged-containers
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Privileged Container sind nicht erlaubt."
pattern:
spec:
=(containers):
- =(securityContext):
=(privileged): "false"
Betriebsweg:
- Policy im Audit/Warn-Modus testen.
- Findings bereinigen.
- Ausnahmen mit Owner und Ablaufdatum dokumentieren.
- Enforce aktivieren.
- Rollback-Pfad für Policy-Ausfall definieren.
Lösung 9: Secrets Security
Musterreview:
# Secrets Review
## Inventar
| Secret | Namespace | Nutzung | Owner | Rotation |
| --- | --- | --- | --- | --- |
| payment-api-token | shop-prod | checkout-api | payments-team | alle 90 Tage |
## Zugriff
- Nur checkout-sa darf das Secret mounten.
- Keine List-Rechte auf Secrets für App-ServiceAccounts.
- Kein Secret in Logs, Events oder Images.
## Risiko
Kubernetes Secrets sind Base64-kodierte API-Objekte. Schutz hängt von RBAC, etcd-Verschlüsselung, Backup-Schutz und Pod-Zugriff ab.
## Empfohlener Zielzustand
- External Secrets oder CSI Secret Store für externe Secret-Quelle.
- Kubernetes Secret nur als kurzfristige Laufzeitprojektion.
- Rotation getestet.
- Zugriff über ServiceAccount minimal.
## Leak-Maßnahme
1. Secret-Nutzung identifizieren.
2. Betroffene Pods isolieren.
3. Secret in Quellsystem rotieren.
4. Kubernetes Secret aktualisieren.
5. Pods neu starten.
6. Logs, Events und Audit prüfen.
7. RBAC und NetworkPolicy nachschärfen.
Lösung 10: Runtime Detection
Muster-Signalmatrix:
| Signal | Risiko | Datenquelle | Erste Reaktion | Evidence |
|---|---|---|---|---|
| unerwartete Shell | interaktive Kompromittierung | Falco/Tetragon, Audit exec |
Pod isolieren, Audit prüfen | Prozess, User, Pod, Zeit |
Schreibzugriff /etc |
Manipulation im Container | Runtime Sensor | Workload-Hardening prüfen | Dateipfad, Prozess |
| unerwarteter Egress | Exfiltration oder C2 | Flow Logs, CNI, Runtime | Egress blockieren | Ziel-IP, DNS, Pod |
| Kubernetes API Zugriff | Token-Missbrauch | Audit Logs | ServiceAccount prüfen | Verb, Resource, Subject |
verdächtiges kubectl exec |
manueller Zugriff | API Audit | User und Change prüfen | User, Pod, Befehlzeit |
| OOMKill | Ressourcen- oder Angriffssignal | kubelet/Event/Metrics | Logs und Limits prüfen | Events, Containerstatus |
Wichtige Einordnung:
Detection ersetzt keine Prävention. Sie ergänzt Pod Security, RBAC, NetworkPolicy und Admission Control.
Lösung 11: Compliance Evidence
Musterbefund:
# Compliance Evidence
## Befund 1: Namespace ohne Pod Security Labels
- Zeitpunkt: 2026-06-12 10:00
- Ressource: namespace/team-legacy
- Risiko: Unsichere Pods können ohne Warnung oder Ablehnung erstellt werden.
- Nachweis: `kubectl get ns team-legacy --show-labels`
- Owner: team-legacy
- Fix: Labels für enforce/audit/warn setzen.
- Frist: 14 Tage
## Befund 2: ServiceAccount mit Secret-Leserechten
- Ressource: rolebinding/risky-binding
- Risiko: Secret-Exfiltration.
- Nachweis: `kubectl auth can-i get secrets --as system:serviceaccount:team-a:app-sa -n team-a`
- Fix: Secret-Rechte entfernen, spezifisches Secret-Mounting prüfen.
## Befund 3: Pod ohne Requests/Limits
- Risiko: Scheduling unzuverlässig, Noisy-Neighbor-Effekt.
- Fix: Requests/Limits über Manifest und Admission ergänzen.
## Befund 4: Secret ohne Rotation-Hinweis
- Risiko: Langfristig gültiges Secret erhöht Schaden bei Leak.
- Fix: Owner, Rotationstermin, Quellsystem dokumentieren.
## Befund 5: Workload ohne NetworkPolicy
- Risiko: Lateral Movement.
- Fix: Default Deny und gezielte Allow-Policies.
Eine gute Evidence enthält nicht nur einen Screenshot, sondern reproduzierbare Kommandos, Owner, Risiko, Frist und Nachtest.
Lösung 12: Incident-Runbook
Muster-Runbook:
# Incident Runbook: kompromittierter Pod und Secret Leak
## 1. Triage
- Signalquelle identifizieren: Runtime Alert, Audit Log, User-Meldung, SIEM.
- Betroffene Ressource bestimmen: Namespace, Pod, Node, ServiceAccount, Secret, Image.
- Kritikalität festlegen.
## 2. Isolation
- NetworkPolicy verschärfen oder Namespace isolieren.
- Pod nicht vorschnell löschen, wenn Evidence benötigt wird.
- Bei Node-Verdacht: Node cordon/drain nach Evidence-Plan.
## 3. Evidence sichern
- Pod YAML
- Events
- Logs und Previous Logs
- Image Digest
- ServiceAccount und RBAC
- betroffene Secrets
- Audit Logs
- Runtime Alerts
Beispiel:
kubectl get pod <pod> -n <ns> -o yaml > evidence-pod.yaml
kubectl describe pod <pod> -n <ns> > evidence-describe.txt
kubectl logs <pod> -n <ns> --all-containers > evidence-logs.txt
kubectl get events -n <ns> --sort-by=.metadata.creationTimestamp > evidence-events.txt
## 4. Containment
- ServiceAccount-Rechte reduzieren.
- Token und Secrets rotieren.
- Egress blockieren.
- unsicheres Image sperren.
## 5. Recovery
- Workload aus sauberem Image neu ausrollen.
- GitOps-Zustand prüfen.
- CI/CD und Registry prüfen.
- Smoke Tests durchführen.
## 6. Lessons Learned
- Welche Policy hätte den Vorfall verhindert?
- Welche Detection hat funktioniert?
- Welche Evidence fehlte?
- Welche RBAC- oder Secret-Kontrolle wird nachgeschärft?
Kompromittierter Pod – Minimalbefehle:
kubectl get pod <pod> -n <ns> -o wide
kubectl get pod <pod> -n <ns> -o yaml
kubectl describe pod <pod> -n <ns>
kubectl logs <pod> -n <ns> --all-containers
kubectl logs <pod> -n <ns> --all-containers --previous
kubectl get sa,role,rolebinding -n <ns>
kubectl auth can-i get secrets --as system:serviceaccount:<ns>:<sa> -n <ns>
Secret Leak – Maßnahmen:
- Secret-Verwendung finden.
- Zugriff blockieren oder Workload isolieren.
- Secret im Quellsystem rotieren.
- Kubernetes Secret aktualisieren.
- Pods neu starten.
- Alte Tokens widerrufen.
- Logs und Audit auf Nutzung prüfen.
- RBAC und Secret-Prozess korrigieren.
Cleanup
kubectl delete namespace workshop-security
Bewertungscheckliste
| Kriterium | Erfüllt? |
|---|---|
| Threat Model mit Assets und Trust Boundaries | ☐ |
| RBAC-Eskalationspfade erkannt | ☐ |
| ServiceAccount Token-Automount reduziert | ☐ |
| Pod Security Restricted angewendet | ☐ |
| SecurityContext vollständig gehärtet | ☐ |
| NetworkPolicy mit DNS-Ausnahme und App-Erlaubnis | ☐ |
| Supply-Chain-Review mit Stop-Kriterien | ☐ |
| Admission Policy mit Betriebsmodus | ☐ |
| Secret-Rotation und Leak-Pfad dokumentiert | ☐ |
| Runtime Detection in Reaktionsplan übersetzt | ☐ |
| Compliance Evidence belastbar formuliert | ☐ |
| Incident-Runbook mit Evidence und Recovery | ☐ |