Workshop wiki · German

Musterlösung: Kubernetes-Prüfung 04 – Advanced + Security

Schwierigkeitsgrad: Advanced + Security Sprache: Deutsch Typ: Musterlösung / Erwartungshorizont

Workshop examples as ZIP files
Learning progress in the web app

Mark chapters as read, view reading progress and check off practice modules after enabling the optional web app. Workshop progress is calculated from chapters across all document pages. Your choices stay on this device; there is no account or server sync. Installation is not required. Withdrawing your choice in Privacy settings deletes the progress.

Reading progress0%
0%
0 / 8 chapters read
Other language versionEnglish ↗Greek ↗

Musterlösung: Kubernetes-Prüfung 04 – Advanced + Security

Schwierigkeitsgrad: Advanced + Security
Sprache: Deutsch
Typ: Musterlösung / Erwartungshorizont

Diese Datei ist eine passende Lösung zur Prüfung 04-advanced-security-kubernetes-pruefung-DE.md.
Alle Beispiele sind für Lab- und Review-Zwecke gedacht. Verwende keine echten Secrets, Tokens, Kundendaten oder produktiven Cluster-Kontexte.


1. Hinweise zur Verwendung

Empfohlener Namespace:

bash
export NS=exam-security

Diese Musterlösung kombiniert Review-Dokumentation, Beispielmanifeste und erwartete Evidence. Nicht jedes Lab enthält Kyverno, Gatekeeper, ValidatingAdmissionPolicy, Trivy, Cosign, Falco oder Tetragon. Fehlt ein Tool, muss die Abgabe fachlich korrekt beschreiben, welche Kontrolle produktiv erforderlich wäre und welches Stop-Kriterium gilt.


01 / 08

2. Teil A: Musterantworten Security-Fachfragen

1. Zentrale Angriffsflächen von Kubernetes

Wichtige Angriffsflächen sind API Server, Authentifizierung, RBAC, Admission, etcd, Nodes, kubelet, Container Runtime, Workloads, ServiceAccounts, Secrets, Netzwerk, Registry, CI/CD, GitOps und Add-ons. Ein Review muss API-, Node-, Workload-, Netzwerk-, Secret- und Supply-Chain-Risiken getrennt betrachten.

2. Authentication, Authorization und Admission Control

Authentication klärt, wer eine Anfrage stellt. Authorization entscheidet, ob diese Identität die Aktion auf der Ressource ausführen darf. Admission Control prüft oder verändert zugelassene Anfragen vor der Persistenz in etcd. Beispiel: Ein Benutzer darf Pods erstellen, aber Admission blockiert privileged: true.

3. Risiken von privileged, hostPath, hostNetwork, hostPID, hostIPC

Einstellung Risiko
privileged: true Container erhält sehr weitreichende Host-Fähigkeiten
hostPath Zugriff auf Host-Dateisystem und mögliche Manipulation
hostNetwork Umgeht Pod-Netzwerkisolation, Zugriff auf Node-Netzwerk
hostPID Sicht auf Host-Prozesse
hostIPC Zugriff auf Host-IPC-Namespace

Solche Einstellungen sind nur mit starker Begründung, Isolation und Ausnahmeprozess vertretbar.

4. ServiceAccounts und automatisch gemountete Tokens

ServiceAccounts sind Workload-Identitäten. Automatisch gemountete Tokens erlauben API-Zugriff aus dem Pod. Wird ein Pod kompromittiert, kann ein Angreifer den Token missbrauchen. Pods ohne API-Bedarf sollten automountServiceAccountToken: false setzen.

5. Gefährliche RBAC-Verben und Ressourcen

Gefährlich sind unter anderem *, get/list/watch secrets, create pods, pods/exec, create rolebindings, bind, escalate, impersonate, nodes/proxy und ClusterRoleBindings. Risiken sind Secret-Exfiltration, Privilege Escalation, laterale Bewegung und Umgehung von RBAC-Schutzmechanismen.

6. Pod Security Standards

privileged erlaubt praktisch alles und ist keine Sicherheitsbaseline. baseline blockiert bekannte gefährliche Einstellungen, erlaubt aber noch breite Standard-Workloads. restricted erzwingt stärkere Härtung wie non-root, seccomp und reduzierte Privilegien. Für neue Namespaces ist restricted häufig Zielzustand.

7. Erwartete SecurityContext-Felder

Erwartet werden:

yaml
securityContext:
  runAsNonRoot: true
  seccompProfile:
    type: RuntimeDefault
containers:
  - securityContext:
      runAsUser: 1000
      runAsGroup: 1000
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]

Zusätzlich: keine Host-Namespace-Nutzung, keine unkontrollierten hostPath-Mounts, Ressourcenlimits und schreibbare Pfade nur über definierte Volumes.

8. NetworkPolicy und Lateral Movement

NetworkPolicies reduzieren laterale Bewegung, weil Pods nicht mehr beliebig miteinander oder nach außen sprechen dürfen. Sie ersetzen keine Verschlüsselung. Für Vertraulichkeit und Integrität des Transports sind TLS oder mTLS nötig.

9. DNS-Egress bei Default Deny

Default-Deny-Egress blockiert auch DNS. Ohne DNS-Ausnahme können Pods Services oder externe Ziele nicht per Namen auflösen. Deshalb wird TCP/UDP 53 zu CoreDNS oder kube-dns explizit erlaubt.

10. Supply-Chain-Kontrollen

Erwartet werden zugelassene Registries, kein latest in Produktion, Digest-Pinning, Image Scans, SBOM, Signaturprüfung, Build Provenance, Pull-Secret-Owner und Admission-Verifikation.

11. Kubernetes Secrets und Base64

Kubernetes Secrets sind API-Objekte und standardmäßig Base64-kodiert, nicht verschlüsselt im Sinne einer sicheren Geheimhaltung. Schutz braucht RBAC, etcd-Verschlüsselung, Backup-Schutz, minimale Mounts, Rotation und gegebenenfalls externe Secret-Systeme.

12. Belastbare Incident-Evidence

Evidence enthält Zeitpunkt, Namespace, Pod YAML, Events, Logs, Previous Logs, Image Digest, ServiceAccount, RBAC, can-i-Ausgaben, Audit Logs, Runtime Alerts, Flow Logs und dokumentierte Maßnahmen. Sie muss reproduzierbar und manipulationsarm gesichert werden.

13. Prävention, Detection und Response

Prävention verhindert unsichere Zustände, zum Beispiel Pod Security oder Admission. Detection erkennt verdächtiges Verhalten, zum Beispiel Runtime Alerts oder Audit Logs. Response beschreibt Eindämmung, Evidence-Sicherung, Rotation, Rebuild und Lessons Learned.

14. Policy-Ausnahmen mit Owner, Begründung und Ablaufdatum

Ausnahmen ohne Owner und Ablaufdatum werden dauerhaft und unsichtbar. Eine belastbare Ausnahme braucht fachliche Begründung, Risiko, kompensierende Kontrollen, Ablaufdatum, Review-Termin und Freigabe.

15. Sofortmaßnahmen bei kompromittiertem Pod und Secret Leak

  • Triage und Scope bestimmen.
  • Pod/Namespace isolieren, nicht vorschnell löschen, wenn Evidence nötig ist.
  • Logs, Events, YAML, Image Digest und RBAC sichern.
  • Secret und ServiceAccount-Token rotieren.
  • Egress begrenzen.
  • Image, CI und GitOps prüfen.
  • Sauber rebuilden und redeployen.
  • Policy und Runbook nachschärfen.

02 / 08

3. Teil B: Threat Model und RBAC-Audit

B1: threat-model.md

markdown
# Threat Model: checkout-api

## Assets und Schutzwert

| Asset | Schutzwert | Begründung |
| --- | --- | --- |
| `payment-api-token` | sehr hoch | Zugriff auf Zahlungs-API möglich |
| `checkout-sa` | hoch | Workload-Identität mit möglichem API-Zugriff |
| Deployment `checkout-api` | hoch | produktiver Workload |
| privates Image | hoch | Supply-Chain-relevant |
| GitOps-Repository | sehr hoch | gewünschter Zustand und Freigabepfad |
| Ingress/Gateway-Route | mittel bis hoch | externe Angriffsfläche |

## Trust Boundaries

- Internet zu Gateway/Ingress.
- Gateway zu `checkout-api`.
- Pod zu Kubernetes API.
- Pod zu Secret-Projektion.
- CI zu Registry.
- GitOps Controller zu Cluster.
- Namespace `shop-prod` zu anderen Namespaces.

## Angriffsflächen

- API Server und RBAC.
- ServiceAccount-Token.
- Container-Image und Registry.
- Secret-Mount und Secret-Rotation.
- NetworkPolicy/Egress.
- GitOps- und CI-Berechtigungen.
- Pod Security und hostnahe Felder.

## Missbrauchsszenarien

| Szenario | Risiko | Kontrolle |
| --- | --- | --- |
| kompromittierter Pod liest `payment-api-token` | Zahlungs-API missbraucht | minimales Secret-Mounting, Rotation, RBAC |
| `checkout-sa` darf Secrets lesen/listen | Secret-Exfiltration | Least Privilege, `can-i`, Audit |
| altes Manifest mit `privileged` und `hostPath` | Host-Kompromittierung | Pod Security, Admission, Review |
| unsigniertes Image wird deployt | Malware oder Manipulation | Signatur, Digest, Scan, SBOM |
| fehlende Egress-Policy | Exfiltration und C2 | Default Deny, DNS/App-Allow |
| CI hat Cluster-Admin | Pipeline-Kompromittierung übernimmt Cluster | GitOps, reduzierte CI-Rechte |

## Vorhandene Kontrollen

- Private Registry.
- GitOps-Pipeline.
- ServiceAccount pro Workload.
- Runtime-Alarm vorhanden.

## Fehlende Kontrollen

- Vollständige NetworkPolicies.
- Dokumentierter Secret-Rotation-Pfad.
- Admission Stop-Kriterien.
- Signatur-/SBOM-Nachweis.
- RBAC-Evidence.
- Incident-Runbook.

## Stop-Kriterien

- ServiceAccount kann Secrets lesen/listen ohne fachlichen Bedarf.
- Workload nutzt `privileged`, `hostPath`, `hostNetwork`, `hostPID` oder `hostIPC` ohne freigegebene Ausnahme.
- Image ist nicht aus erlaubter Registry oder nicht signiert.
- Critical CVE ohne Ausnahme.
- Secret-Rotation nicht möglich oder nicht dokumentiert.
- Keine NetworkPolicy für produktiven Workload.

## Evidence

- `kubectl auth can-i` Ausgaben.
- Policy Reports.
- Image-Digest, Scan, SBOM und Signaturstatus.
- NetworkPolicy-Manifeste und Tests.
- Incident-Evidence aus Logs, Events und Runtime Alerts.

B2: RBAC-Audit

rbac-review.md und Beispielmanifest

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: exam-security
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: app-sa
  namespace: exam-security
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: overprivileged-sa
  namespace: exam-security
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: configmap-reader
  namespace: exam-security
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: app-sa-configmap-reader
  namespace: exam-security
subjects:
  - kind: ServiceAccount
    name: app-sa
    namespace: exam-security
roleRef:
  kind: Role
  name: configmap-reader
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: risky-role
  namespace: exam-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: exam-security
subjects:
  - kind: ServiceAccount
    name: overprivileged-sa
    namespace: exam-security
roleRef:
  kind: Role
  name: risky-role
  apiGroup: rbac.authorization.k8s.io

Pflichtnachweise für evidence/can-i.txt:

bash
kubectl auth can-i get configmaps --as system:serviceaccount:exam-security:app-sa -n exam-security
kubectl auth can-i get secrets --as system:serviceaccount:exam-security:app-sa -n exam-security
kubectl auth can-i get secrets --as system:serviceaccount:exam-security:overprivileged-sa -n exam-security
kubectl auth can-i create rolebindings --as system:serviceaccount:exam-security:overprivileged-sa -n exam-security

Erwartete Bewertung:

Prüfung Erwartung Bewertung
app-sa get configmaps yes akzeptabel bei fachlichem Bedarf
app-sa get secrets no korrekt minimiert
overprivileged-sa get secrets yes kritisch
overprivileged-sa create rolebindings yes kritisch, möglicher Eskalationspfad

Fix:

  • Secret-Rechte entfernen.
  • RoleBinding-Erstellung entfernen.
  • Separaten administrativen Break-Glass-Prozess verwenden.
  • Effektive Rechte erneut mit can-i prüfen.

B3: ServiceAccount Token-Automount

serviceaccount-token-review.md / Deployment

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: no-api-app
  namespace: exam-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"]
          resources:
            requests:
              cpu: 50m
              memory: 64Mi
            limits:
              cpu: 100m
              memory: 128Mi

Prüfung:

bash
kubectl apply -f no-api-app.yml
kubectl rollout status deployment/no-api-app -n exam-security
POD=$(kubectl get pod -l app=no-api-app -n exam-security -o jsonpath='{.items[0].metadata.name}')
kubectl exec "$POD" -n exam-security -- ls -la /var/run/secrets/kubernetes.io/serviceaccount || true

Musterbewertung:

  • Normale Web-Apps ohne Kubernetes-API-Bedarf brauchen kein Token.
  • Controller, Operatoren oder Apps, die Kubernetes-Objekte lesen oder schreiben, brauchen bewusst eingerichtete API-Rechte.

03 / 08

4. Teil C: Workload-, Netzwerk- und Supply-Chain-Hardening

C1: Pod Security Restricted

Namespace labeln:

bash
kubectl create namespace exam-security --dry-run=client -o yaml | kubectl apply -f -
kubectl label namespace exam-security \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted --overwrite

Unsicherer Pod:

yaml
apiVersion: v1
kind: Pod
metadata:
  name: privileged-pod
  namespace: exam-security
spec:
  containers:
    - name: app
      image: busybox:1.36
      command: ["sh", "-c", "sleep 3600"]
      securityContext:
        privileged: true

Erwartung: Der API Server lehnt den Pod durch Pod Security Admission ab.

C2: hardened-deployment.yml

yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: hardened-app
  namespace: exam-security
automountServiceAccountToken: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hardened-app
  namespace: exam-security
  labels:
    app: hardened-app
    owner: platform-security
    environment: exam
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hardened-app
  template:
    metadata:
      labels:
        app: hardened-app
        owner: platform-security
        environment: exam
    spec:
      serviceAccountName: hardened-app
      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
          readinessProbe:
            exec:
              command: ["sh", "-c", "test -f /tmp/status || true"]
            periodSeconds: 10
          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:

bash
kubectl apply -f hardened-deployment.yml
kubectl rollout status deployment/hardened-app -n exam-security
kubectl get pod -l app=hardened-app -n exam-security -o yaml | grep -E 'runAsNonRoot|allowPrivilegeEscalation|readOnlyRootFilesystem|seccompProfile|capabilities' -A3

C3: networkpolicies.yml

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: exam-security
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-dns-egress
  namespace: exam-security
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-egress-to-backend
  namespace: exam-security
spec:
  podSelector:
    matchLabels:
      app: frontend
  policyTypes:
    - Egress
  egress:
    - to:
        - podSelector:
            matchLabels:
              app: backend
      ports:
        - protocol: TCP
          port: 8080
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-backend-ingress-from-frontend
  namespace: exam-security
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

Produktive Zusatzfragen:

  • Braucht der Pod Kubernetes-API-Egress?
  • Braucht er Registry-, Logging-, Monitoring- oder externe API-Ziele?
  • Sind externe Ziele fest begrenzbar?
  • Wird IPv6 oder Dual-Stack berücksichtigt?
  • Erzwingt das CNI NetworkPolicies tatsächlich?

C4: supply-chain-review.md

markdown
# Supply-Chain-Review

## Beispielimage

- Registry: `registry.example.com`
- Repository: `shop/checkout-api`
- Tag: `1.4.2`
- Digest: `sha256:<beispiel-digest>`
- Referenz für Produktion: `registry.example.com/shop/checkout-api@sha256:<beispiel-digest>`
- Pull Policy: `IfNotPresent` oder Plattformstandard; bei unveränderlichen Digests reproduzierbar.
- ImagePullSecret: namespace-spezifisch, Owner `platform-registry`, Rotation alle 90 Tage.

## Prüfstatus

| Kontrolle | Ergebnis | Entscheidung |
| --- | --- | --- |
| erlaubte Registry | erfüllt | ok |
| kein `latest` | erfüllt | ok |
| Digest bekannt | erfüllt | ok |
| CVE-Scan | keine Critical, 1 High mit Ticket | bedingt ok |
| SBOM | vorhanden | ok |
| Signatur | gültig | ok |
| Build Provenance | CI-Build-ID und Commit vorhanden | ok |
| Admission | nur erlaubte Registry, Digest, Signatur | erforderlich |

## Stop-Kriterien

- `latest` ohne Digest in Produktion.
- Image aus nicht erlaubter Registry.
- Critical CVE ohne genehmigte Ausnahme.
- fehlende Signatur bei produktiven Workloads.
- Pull Secret ohne Owner oder Rotation.

C5: admission-policy.md

markdown
# Admission Policy

## Policy-Ziel 1: Required Labels

- Ziel: `owner`, `environment`, `cost-center` erzwingen.
- Scope: Pods, Deployments, Namespaces nach Plattformstandard.
- Modus: zuerst Audit/Warn, danach Enforce.
- Beispielverstoß: Deployment ohne `cost-center`.
- Ausnahme: Owner, Begründung, Ablaufdatum, kompensierende Kontrolle.
- Rollback: Policy auf Audit zurücksetzen oder gezielt Namespace ausnehmen.

### Kyverno-Beispiel

```yaml
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: "?*"
```

## Policy-Ziel 2: `privileged: true` verbieten

- Ziel: Hostnahe Privilegien blockieren.
- Scope: Pods und Workload-Pod-Templates.
- Modus: Warn/Audit in Bestandsnamespaces, Enforce in neuen Namespaces.
- Beispielverstoß: Container mit `securityContext.privileged: true`.
- Ausnahme: nur temporär für freigegebene Systemkomponenten.
- Rollback: Enforce auf Audit zurückstellen, falls legitime Deployments blockiert werden.

### Kyverno-Beispiel

```yaml
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"
```

## Alternative ohne Policy Engine

Wenn Kyverno/Gatekeeper/ValidatingAdmissionPolicy nicht verfügbar ist, wird die Policy als Pseudomanifest und Betriebsanforderung dokumentiert. Stop-Kriterium bleibt: produktive Workloads ohne diese Prüfung werden nicht freigegeben.

04 / 08

5. Teil D: Secrets, Detection, Compliance und Incident Response

D1: secrets-review.md

markdown
# Secrets Review

## Inventar

| Secret | Namespace | Nutzung | Owner | Rotation |
| --- | --- | --- | --- | --- |
| `payment-api-token` | `shop-prod` | checkout-api Zugriff auf Zahlungs-API | payments-team | alle 90 Tage oder bei Incident sofort |

## RBAC-Zugriff

- App-ServiceAccounts erhalten keine `list/watch secrets` Rechte.
- Secret wird nur gezielt als Volume oder Env referenziert.
- Admin-Zugriff ist auditpflichtig.

## Mount-Art

- Bevorzugt Secret-Volume read-only.
- Keine Ausgabe in Logs.
- Keine Secrets in Images oder ConfigMaps.

## Risiken

| Risiko | Bewertung |
| --- | --- |
| Logs | Secret darf nicht geloggt werden |
| Events | Fehlermeldungen dürfen keine Werte enthalten |
| Images | Secret darf nicht ins Image gebacken werden |
| Backups | Backup-Zugriff entspricht Secret-Zugriff |
| etcd | Verschlüsselung at rest und Zugriffsschutz nötig |

## Vergleich Secret-Systeme

| Modell | Nutzen | Risiko |
| --- | --- | --- |
| Kubernetes Secret | einfach, API-nativ | RBAC/etcd/Backup kritisch |
| External Secrets | Sync aus externem Store | Controller-Rechte und Store-Zugriff kritisch |
| CSI Secret Store | Laufzeitprojektion als Volume | Rotation und Node-Integration prüfen |
| Sealed Secrets | verschlüsselt in Git | Cluster-Private-Key kritisch |
| SOPS | verschlüsselte Dateien in Git | Key-Management außerhalb des Clusters nötig |

## Rotation-Pfad

1. Secret-Verwendung ermitteln.
2. Neuen Wert im Quellsystem erzeugen.
3. Kubernetes Secret oder External-Secret-Quelle aktualisieren.
4. Pods neu starten oder Reload prüfen.
5. Alten Wert widerrufen.
6. Audit auf missbräuchliche Nutzung prüfen.

## Leak-Maßnahme

- Betroffene Pods isolieren.
- Secret sofort im Quellsystem rotieren.
- ServiceAccount und RBAC prüfen.
- Logs, Events und Audit sichern.
- NetworkPolicy und Admission nachschärfen.

D2: runtime-detection.md

markdown
# Runtime Detection

| Signal | Risiko | Datenquelle | Erste Reaktion | Evidence |
| --- | --- | --- | --- | --- |
| unerwartete Shell im Container | interaktive Kompromittierung | Runtime Sensor, Audit `exec` | Pod isolieren, User prüfen | Zeit, Pod, User, Prozess |
| Schreibzugriff auf `/etc`, `/proc`, `/sys` | Manipulation oder Ausbruchversuch | Falco/Tetragon/Tracee | Workload einfrieren/isolieren | Pfad, Prozess, Container |
| unerwarteter Egress | Exfiltration oder C2 | Flow Logs, DNS, CNI, Runtime | Egress blockieren | Ziel-IP, DNS, Pod, Namespace |
| Zugriff auf Kubernetes API mit ServiceAccount | Token-Missbrauch | Audit Logs | RBAC prüfen, Token rotieren | Verb, Resource, Subject |
| verdächtiges `kubectl exec` | manueller Zugriff ohne Change | API Audit | User/Change validieren | User, Pod, Zeit, Namespace |
| OOMKill in sicherheitsrelevantem Pod | Ressourcenproblem oder Angriffssignal | Events, kubelet, Metrics | App- und Security-Signale trennen | Events, Limits, Logs |

Detection ersetzt keine Prävention. Sie ergänzt Pod Security, RBAC, NetworkPolicy und Admission.

D3: compliance-evidence.md

markdown
# Compliance Evidence

## Befund 1: Namespace ohne Pod-Security-Label

- 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: `enforce/audit/warn` Labels setzen.
- Frist: 14 Tage
- Nachtest: Labels erneut prüfen und unsicheren Pod ablehnen lassen.

## Befund 2: ServiceAccount mit zu breiten Rechten

- Ressource: `rolebinding/risky-binding`
- Risiko: Secret-Exfiltration und Eskalation.
- Nachweis: `kubectl auth can-i get secrets --as system:serviceaccount:team-a:app-sa -n team-a`
- Owner: team-a
- Fix: Secret-Rechte und RoleBinding-Erstellung entfernen.
- Ausnahme: nur mit Ablaufdatum und Security-Freigabe.
- Nachtest: `can-i` muss `no` liefern.

## Befund 3: Pod ohne Requests/Limits

- Ressource: `deployment/legacy-api`
- Risiko: unzuverlässiges Scheduling, Noisy-Neighbor-Effekt, schlechte HPA-Basis.
- Nachweis: `kubectl get deployment legacy-api -o yaml`
- Owner: legacy-team
- Fix: CPU-/Memory-Requests und Limits ergänzen.
- Nachtest: Manifest und QoS prüfen.

## Befund 4: Secret ohne Rotation-Hinweis

- Ressource: `secret/payment-api-token`
- Risiko: langfristiger Schaden bei Leak.
- Nachweis: fehlende Annotation `rotation.platform.example.com/next-date`.
- Owner: payments-team
- Fix: Owner, Quellsystem und Rotationstermin dokumentieren.
- Nachtest: Rotation im Runbook simulieren.

## Befund 5: Workload ohne NetworkPolicy

- Ressource: `namespace/shop-prod`, `deployment/checkout-api`
- Risiko: Lateral Movement und unkontrollierter Egress.
- Nachweis: `kubectl get networkpolicy -n shop-prod`
- Owner: shop-team
- Fix: Default Deny plus DNS-, App- und notwendige externe Egress-Regeln.
- Nachtest: erlaubte und blockierte Pfade testen.

D4: incident-runbook.md

markdown
# Incident Runbook: kompromittierter Pod und Secret Leak

## 1. Triage

- Signalquelle identifizieren: Runtime Alert, Audit Log, SIEM, User-Meldung.
- Betroffene Ressourcen bestimmen: Namespace, Pod, Node, ServiceAccount, Secret, Image.
- Kritikalität und potenzielle Datenexposition bewerten.

## 2. Isolation

- Namespace- oder Pod-Egress per NetworkPolicy begrenzen.
- Pod nicht vorschnell löschen, wenn Evidence benötigt wird.
- Bei Node-Verdacht: Node cordon, Evidence-Plan, dann ggf. drain und rebuild.

## 3. Evidence-Sicherung

```bash
kubectl get pod <pod> -n <namespace> -o wide
kubectl get pod <pod> -n <namespace> -o yaml
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace> --all-containers
kubectl logs <pod> -n <namespace> --all-containers --previous
kubectl get sa,role,rolebinding -n <namespace>
kubectl auth can-i get secrets --as system:serviceaccount:<namespace>:<serviceaccount> -n <namespace>
kubectl get events -n <namespace> --sort-by=.metadata.creationTimestamp
```

Zusätzlich sichern:

- Image-Digest.
- GitOps-Revision.
- Audit Logs.
- Runtime Alerts.
- Flow Logs und DNS-Abfragen.

## 4. Containment

- ServiceAccount-Rechte reduzieren.
- Egress blockieren oder stark einschränken.
- betroffene Workloads skalieren oder isoliert neu deployen.
- unsicheres Image sperren.

## 5. Secret- und Token-Rotation

1. Betroffene Secrets identifizieren.
2. Secret im Quellsystem rotieren.
3. Kubernetes Secret aktualisieren.
4. Pods neu starten oder Reload erzwingen.
5. Alte Tokens widerrufen.
6. Audit auf Nutzung alter Werte prüfen.

## 6. Image- und CI-Prüfung

- Image-Digest mit GitOps-Zustand vergleichen.
- CI-Build, Scan und Signatur prüfen.
- Registry-Zugriffe prüfen.
- Falls Supply-Chain-Verdacht besteht: Image sperren und neu bauen.

## 7. Rebuild und Redeploy

- Manifest-Fix per Pull Request.
- Image neu bauen, scannen, signieren.
- GitOps Sync durchführen.
- Smoke Tests und Security Tests ausführen.

## 8. Kommunikation

- Incident Commander benennen.
- Security, Plattformteam, App-Team und ggf. Datenschutz informieren.
- Status, Risiko, Maßnahmen und ETA dokumentieren.

## 9. Lessons Learned

- Welche Kontrolle fehlte?
- Welche Detection hat funktioniert?
- Welche Evidence fehlte?
- Welche Policy wird nachgeschärft?

## 10. Policy-Nachschärfung

- Pod Security Restricted erzwingen.
- RBAC minimieren.
- `automountServiceAccountToken: false` standardisieren.
- NetworkPolicy Default Deny einführen.
- Image-Signaturen und Digest-Pinning erzwingen.
- Secret-Rotation und External-Secret-Modell verbessern.

## Wann ein Pod nicht sofort gelöscht werden sollte

Wenn Logs, laufende Prozesse, Volumes, Runtime-Signale oder Containerstatus für die Ursachenanalyse wichtig sind, kann sofortiges Löschen Evidence zerstören. In diesem Fall zuerst isolieren und sichern, dann entfernen oder neu deployen.

05 / 08

6. Erwartete Abgabestruktur

text
04-advanced-security-abgabe/
  answers.md
  threat-model.md
  rbac-review.md
  serviceaccount-token-review.md
  pod-security-review.md
  hardened-deployment.yml
  networkpolicies.yml
  supply-chain-review.md
  admission-policy.md
  secrets-review.md
  runtime-detection.md
  compliance-evidence.md
  incident-runbook.md
  evidence/
    can-i.txt
    events.txt
    policy-results.txt
    logs-summary.txt
  cleanup.md

Muster für cleanup.md:

markdown
# Cleanup

```bash
kubectl delete namespace exam-security
```

Falls ClusterPolicies oder clusterweite Demo-Ressourcen angelegt wurden, müssen sie separat und dokumentiert entfernt werden.

06 / 08

7. Cleanup

Namespace entfernen:

bash
kubectl delete namespace exam-security

Clusterweite Policies nur löschen, wenn sie im Lab angelegt wurden:

bash
kubectl delete clusterpolicy require-standard-labels --ignore-not-found
kubectl delete clusterpolicy disallow-privileged --ignore-not-found

07 / 08

8. Bewertungs- und Prüferhinweise

Eine sehr gute Advanced-Security-Lösung:

  • trennt Risiken nach API, Node, Workload, Netzwerk, Secrets und Supply Chain,
  • erkennt ServiceAccount- und RBAC-Eskalationspfade,
  • reduziert automatische ServiceAccount-Token-Mounts,
  • erfüllt Pod Security Restricted oder dokumentiert Abweichungen mit Stop-Kriterien,
  • liefert einen gehärteten SecurityContext,
  • erstellt NetworkPolicies mit Default Deny, DNS und gezieltem App-Traffic,
  • bewertet Image, Registry, Tag, Digest, Scan, SBOM, Signatur und Pull Secret,
  • beschreibt Admission Policies mit Audit/Warn/Enforce, Ausnahme und Rollback,
  • behandelt Secrets mit Rotation, RBAC, etcd-/Backup-Risiko und Leak-Maßnahmen,
  • übersetzt Runtime-Signale in konkrete Reaktionen,
  • erstellt belastbare Compliance Evidence,
  • schreibt ein Incident-Runbook mit Evidence, Containment, Rotation, Recovery und Lessons Learned,
  • verwendet keine echten Secrets oder produktiven Cluster.
08 / 08

K8S · Orthevs Academy

31 modules as one continuous learning path.

The sequence remains unchanged: from the lab skeleton through technical foundations and operating models to final troubleshooting. The technical directory names are deliberately preserved.

Orthevs – Engineering the foundation for what comes next.

Orthevs as an app

Install Orthevs

The Orthevs web app can be installed on supported mobile devices and desktop browsers.

iPhone and iPad

Open Orthevs in Safari. Tap Share, then Add to Home Screen. Enable Open as Web App if offered, then tap Add.

Android

For the web app, open the browser menu and choose Install app or Add to Home screen. Confirm the installation.

Desktop browser

Open the browser menu or the install icon in the address bar, then choose Install app or Add to Dock.

Web app installation depends on your browser. If no install prompt appears, follow the browser steps shown above.