Security: Kubernetes
Vollständige Security-Dokumentation für Kubernetes-Workshops, Plattformdesign, Betriebsreviews und Security-Assessments.
Stand: 13. Juni 2026
1. Ziel und Geltungsbereich
Dieses Dokument beschreibt den vollständigen Themenbereich Security in Kubernetes. Es ist für Workshops, interne Plattformstandards, Security Reviews, Betriebsübergaben und Architekturentscheidungen gedacht.
Du sollst nach dem Durcharbeiten in der Lage sein:
- Kubernetes-Security fachlich zu strukturieren,
- Risiken je Umgebung zu bewerten,
- sichere Defaults für Workloads zu definieren,
- API-, RBAC-, Pod-, Netzwerk-, Secret-, Node- und Supply-Chain-Kontrollen umzusetzen,
- Security-Anforderungen in
kind,minikube,k3d, WSL, lokalen VMs, Remote-VMs, Bare Metal, kubeadm-Clustern, k3s, RKE2, k0s, Talos, EKS, AKS, GKE, OKE, DOKS, LKE und OpenShift einzuordnen, - Security-Funde zu triagieren,
- Incidents reproduzierbar zu behandeln,
- Compliance- und Audit-Anforderungen in technische Kontrollen zu übersetzen.
1.1. Was dieses Dokument abdeckt
| Bereich | Inhalt |
|---|---|
| Cluster Security | API Server, etcd, kubelet, Controller, Scheduler, Admission, Audit |
| Identity | Benutzer, Gruppen, ServiceAccounts, OIDC, Cloud-Workload-Identity |
| Authorization | RBAC, Least Privilege, Eskalationspfade, Review-Kommandos |
| Workload Security | Pod Security Standards, SecurityContext, Capabilities, seccomp, AppArmor, SELinux |
| Network Security | NetworkPolicies, CNI, DNS, Ingress, Gateway API, Egress, Service Mesh |
| Secrets | Kubernetes Secrets, Encryption at Rest, externe Secret-Systeme, Rotation |
| Supply Chain | Images, Registries, SBOM, Signaturen, Scans, Admission-Gates |
| Runtime Security | Falco, Tetragon, Audit Logs, eBPF, Verhaltensanalyse |
| Node Security | OS-Härtung, kubelet, Runtime, SSH, Patches, Immutable Nodes |
| Environments | WSL, kind, minikube, k3d, VM, Bare Metal, Cloud, Managed Kubernetes |
| Operations | Backup, Restore, Disaster Recovery, Patching, Monitoring, Logging, Alerting |
| Compliance | CIS, NSA/CISA, interne Standards, Audit-Reports |
1.2. Was dieses Dokument nicht ersetzt
Dieses Dokument ersetzt nicht:
- eine rechtliche Compliance-Prüfung,
- eine organisationsweite Risikoanalyse,
- Herstellerdokumentation deines Providers,
- Penetrationstests,
- Notfallübungen,
- Produktionsfreigaben durch Security, Datenschutz oder Governance.
Es liefert aber die technische Grundlage, damit du diese Prozesse fundiert vorbereitest.
1.3. Begriffe
| Begriff | Bedeutung |
|---|---|
| Control Plane | API Server, etcd, Scheduler, Controller Manager und weitere Steuerungskomponenten |
| Node | Maschine, auf der kubelet und Container Runtime laufen |
| Workload | Anwendung oder Plattformkomponente, die als Pod läuft |
| Admission | Prüfung oder Veränderung von API-Anfragen vor Speicherung in etcd |
| Runtime Security | Erkennung und Bewertung von Verhalten nach dem Start eines Containers |
| Supply Chain | Weg vom Quellcode über Build, Image, Registry, Deployment bis zur Laufzeit |
| Least Privilege | Nur die Berechtigungen vergeben, die objektiv erforderlich sind |
| Break Glass | Notfallzugang für außergewöhnliche Störungen mit starker Kontrolle und Audit |
2. Security-Leitprinzipien
Kubernetes-Security ist kein einzelnes Feature. Sie entsteht durch Schichten, Verantwortlichkeiten und Wiederholbarkeit.
2.1. Grundsätze
- Deklarativ statt manuell. Sicherheitskontrollen gehören in Git, IaC, Helm, Kustomize oder Policy-Engines.
- Least Privilege überall. Benutzer, ServiceAccounts, Nodes, Cloud-Rollen, Registry-Zugriffe und CI/CD-Tokens bekommen nur notwendige Rechte.
- Default Deny vor Allow List. Netzwerk, RBAC, Admission und Egress sollten mit restriktiven Defaults starten.
- Identität statt statischer Secrets. Nutze OIDC, Workload Identity, Pod Identity, Managed Identity oder kurzlebige Tokens.
- Immutable statt reparieren. Kompromittierte Nodes und unsichere Images werden ersetzt, nicht manuell bereinigt.
- Admission verhindert Fehler früh. Was nicht laufen darf, sollte möglichst nicht in etcd landen.
- Observability ist Security-Kontrolle. Ohne Audit Logs, Metriken, Runtime Events und zentrale Logs ist Security blind.
- Restore ist Teil von Security. Backups ohne Restore-Test sind keine belastbare Kontrolle.
- Supply Chain beginnt vor Kubernetes. Images, Dependencies, Build Runner, Registry und GitOps-Controller gehören zum Angriffsmodell.
- Umgebung bestimmt Risiko. Ein lokales
kind-Lab braucht andere Kontrollen als ein reguliertes Multi-Tenant-Produktionscluster.
2.2. Minimaler Sicherheitsstandard für produktionsnahe Cluster
| Kontrolle | Mindeststandard |
|---|---|
| API-Zugriff | Keine offene API aus dem Internet; Zugriff über VPN, private Endpunkte, Bastion, SSO oder IP-Allowlist |
| RBAC | Keine breit genutzten cluster-admin-Bindings; Review von bind, escalate, impersonate, nodes/proxy |
| Pod Security | Namespace-Labels für baseline oder restricted; Ausnahmen dokumentiert |
| Secrets | Encryption at Rest, striktes RBAC, keine echten Secrets in Git, Rotation geregelt |
| Netzwerk | Default-Deny je Tenant/Namespace; DNS, Monitoring und notwendiger Egress explizit erlaubt |
| Images | Keine latest-Tags in Produktion; Scans; Digest-Pinning oder Signaturprüfung für kritische Workloads |
| Nodes | kubelet geschützt; SSH minimiert; Runtime aktuell; OS-Patches geplant |
| Audit | API-Audit aktiviert oder Provider-Audit-Logs angebunden; Logs manipulationsgeschützt gespeichert |
| Backup | etcd beziehungsweise Cluster-State, PV-Daten, Secrets, Zertifikate und IaC-State gesichert und Restore getestet |
| Incident Response | Runbooks für kompromittierten Pod, Node, Secret, Registry, CI/CD und API-Zugang |
2.3. Security-Reifegrade
| Reifegrad | Beschreibung | Typische Merkmale |
|---|---|---|
| 0: Ad hoc | Manuelle Cluster, kaum Standards | cluster-admin für viele, keine NetworkPolicies, keine Scans |
| 1: Baseline | Grundkontrollen eingeführt | RBAC, PSS, einfache Scans, zentrale Logs |
| 2: Standardisiert | Wiederholbare Plattform | GitOps, Policy as Code, Secrets extern, Backup/Restore getestet |
| 3: Kontrolliert | Audit- und Compliance-fähig | CIS-Reviews, SIEM-Anbindung, Runtime Detection, Cloud-Guardrails |
| 4: Resilient | Security ist Betriebsprozess | Tabletop-Übungen, automatisierte Rotation, Multi-Cluster-DR, kontinuierliche Verbesserung |
3. Schnellstart: Security-Baseline
Dieser Abschnitt liefert eine sofort nutzbare Baseline für Labs und produktionsnahe Tests. Für echte Produktion passt du jede Kontrolle an deine Organisation, Regulatorik, Netzwerkarchitektur und Provider-Vorgaben an.
3.1. Namespace mit Pod Security Admission
apiVersion: v1
kind: Namespace
metadata:
name: app-prod
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
Validierung:
kubectl apply -f namespace-app-prod.yaml
kubectl get ns app-prod --show-labels
3.2. Default-Deny für Ingress und Egress
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: app-prod
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Wichtig: Diese Policy blockiert auch DNS-Egress, sofern du DNS nicht explizit erlaubst.
3.3. DNS-Egress erlauben
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-egress
namespace: app-prod
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Passe die Labels an deine CoreDNS-Installation an. Manche Distributionen verwenden andere Labels.
3.4. Sicherer ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: app-runtime
namespace: app-prod
automountServiceAccountToken: false
Wenn deine Anwendung die Kubernetes API nicht benötigt, mountest du kein Token. Wenn sie die API benötigt, vergibst du exakt die benötigten Rechte und aktivierst Token-Mount nur für diesen Workload.
3.5. Minimal-RBAC für lesenden Pod-Zugriff im Namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: app-prod
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader-app-runtime
namespace: app-prod
subjects:
- kind: ServiceAccount
name: app-runtime
namespace: app-prod
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
3.6. Gehärtetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
namespace: app-prod
labels:
app.kubernetes.io/name: demo-app
app.kubernetes.io/part-of: workshop
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: demo-app
template:
metadata:
labels:
app.kubernetes.io/name: demo-app
app.kubernetes.io/part-of: workshop
spec:
serviceAccountName: app-runtime
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: ghcr.io/example/demo-app@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 10001
runAsGroup: 10001
capabilities:
drop:
- ALL
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 20
periodSeconds: 10
readinessProbe:
httpGet:
path: /readyz
port: http
initialDelaySeconds: 5
periodSeconds: 5
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
3.7. Baseline-Validierung
kubectl auth can-i list pods -n app-prod --as system:serviceaccount:app-prod:app-runtime
kubectl auth can-i get secrets -n app-prod --as system:serviceaccount:app-prod:app-runtime
kubectl get networkpolicy -n app-prod
kubectl get pods -n app-prod -o wide
kubectl describe pod -n app-prod -l app.kubernetes.io/name=demo-app
Erwartung:
- Der ServiceAccount darf Pods lesen, aber keine Secrets lesen.
- Pods laufen ohne Root, ohne Privilege Escalation und mit
RuntimeDefault-seccomp. - Netzwerk ist standardmäßig geschlossen.
- Ausnahmen sind explizit dokumentiert.
4. Bedrohungsmodell
Kubernetes hat mehrere Angriffsflächen. Ein brauchbares Security-Modell betrachtet nicht nur Pods, sondern die gesamte Liefer- und Betriebsstrecke.
4.1. Hauptangriffsflächen
| Angriffsfläche | Typische Risiken | Kontrollen |
|---|---|---|
| API Server | gestohlene kubeconfigs, offene API, schwaches RBAC, fehlende Audit Logs | OIDC, MFA, private API, RBAC, Audit, Admission |
| etcd | unverschlüsselte Secrets, Snapshot-Leak, Zugriff auf Control Plane | Encryption at Rest, TLS, Backup-Schutz, Node-Isolation |
| kubelet | anonyme Zugriffe, nodes/proxy, Exec auf Node-Workloads |
Webhook Authn/Authz, Netzwerkabschottung, RBAC-Review |
| Workloads | Root-Container, privilegierte Pods, HostPath, Capabilities | PSS, SecurityContext, Admission, Runtime Detection |
| CNI und Netzwerk | offene Pod-Kommunikation, unkontrollierter Egress, DNS-Missbrauch | NetworkPolicies, Egress-Gateway, DNS-Policy, Service Mesh optional |
| Ingress/Gateway | fehlendes TLS, unsichere Header, offene Admin-Endpunkte | TLS, WAF, Rate Limit, Auth, Gateway-Rollenmodell |
| Registry | manipulierte Images, unsichere Tags, CVEs | Scans, Signaturen, Digest-Pinning, Registry-RBAC |
| CI/CD | Runner-Kompromittierung, Secret-Leak, Supply-Chain-Manipulation | kurzlebige Tokens, isolierte Runner, SBOM, Provenance |
| GitOps | breit berechtigter Controller, Drift, unreviewte Manifeste | Repo-RBAC, branch protection, scoped ServiceAccounts, Admission |
| Cloud-IAM | Node-Rollen mit zu vielen Rechten, Metadata-Service-Missbrauch | Pod Identity, Workload Identity, IMDS-Härtung, least privilege |
| Nodes | SSH, ungepatchtes OS, Container Escape, lokale Credentials | OS-Härtung, Patches, immutable Nodes, Runtime Detection |
| Add-ons | überprivilegierte Controller, Webhook-Ausfall, CRD-Missbrauch | Add-on-Review, Versionierung, RBAC, PDB, Observability |
4.2. Angreiferprofile
| Profil | Beschreibung | Beispiel |
|---|---|---|
| Externer Angreifer | Kein initialer Clusterzugang | Ausnutzung einer App-CVE über Ingress |
| Bösartiger Insider | Legitime Identität mit Absicht zum Missbrauch | Entwickler liest Secrets außerhalb seines Teams |
| Kompromittierter Workload | Angreifer kontrolliert einen Pod | Shell im Container, ServiceAccount-Token auslesen |
| Kompromittierter Node | Angreifer hat Host-Zugriff | Container Runtime, kubelet, Pod-Dateisysteme |
| Kompromittierte Pipeline | Build oder Deployment wird manipuliert | Image enthält Backdoor, GitOps deployt schädliche Änderung |
| Kompromittierter Cloud-Account | Cloud-IAM missbraucht | NodeRole darf Secrets Manager oder Storage breit lesen |
4.3. Typische Angriffsketten
flowchart LR
A[Public App CVE] --> B[Shell im Pod]
B --> C[ServiceAccount Token]
C --> D[RBAC prüfen]
D --> E{Rechte zu breit?}
E -- ja --> F[Secrets lesen oder Pods erstellen]
E -- nein --> G[Node oder Netzwerk erkunden]
F --> H[Cloud Credentials oder DB-Zugriff]
G --> I[Egress zu C2 oder lateral movement]
flowchart LR
A[CI Runner kompromittiert] --> B[Image manipuliert]
B --> C[Registry Push]
C --> D[GitOps Rollout]
D --> E[Pod startet im Cluster]
E --> F[Runtime Detection oder Admission?]
F -- keine Kontrolle --> G[Persistenz und Datenzugriff]
F -- Kontrolle aktiv --> H[Deployment blockiert oder Alarm]
4.4. Bedrohungen nach STRIDE
| STRIDE | Kubernetes-Beispiel | Kontrolle |
|---|---|---|
| Spoofing | gestohlene kubeconfig, falsche ServiceAccount-Identität | OIDC, MFA, kurzlebige Tokens, Audit |
| Tampering | manipuliertes Manifest, Image oder Admission Webhook | Git-Schutz, Signaturen, Admission, branch protection |
| Repudiation | Änderungen nicht nachvollziehbar | Audit Logs, Git-Historie, SIEM, Change-Prozess |
| Information Disclosure | Secrets, ConfigMaps, Logs oder PV-Daten offengelegt | RBAC, Encryption, Log-Scrubbing, Data Classification |
| Denial of Service | Resource Exhaustion, Webhook-Ausfall, API-Überlastung | Quotas, LimitRanges, PDB, HA, Rate Limits |
| Elevation of Privilege | bind, escalate, impersonate, privileged Pods |
RBAC-Review, PSS, Admission, separate Admin-Gruppen |
5. Defense-in-Depth-Architektur
Security in Kubernetes ist mehrschichtig. Eine einzelne Policy ist nie ausreichend.
5.1. Gesamtbild
flowchart TB
subgraph Supply[Supply Chain]
Code[Code Review]
Build[Build Runner]
Scan[Scan und SBOM]
Sign[Signatur und Provenance]
Registry[Registry]
end
subgraph Access[Zugriff]
User[Benutzer / Gruppen]
OIDC[OIDC / SSO / MFA]
Kubeconfig[kubeconfig / Exec Plugin]
end
subgraph API[Kubernetes API]
APIServer[API Server]
Authn[Authentifizierung]
Authz[RBAC / Webhook Authz]
Admission[Admission / Policy]
Audit[Audit Logs]
Etcd[etcd]
end
subgraph Runtime[Laufzeit]
Node[Node]
Kubelet[kubelet]
RuntimeEngine[containerd / CRI-O]
Pod[Pod]
Net[NetworkPolicy / CNI]
Detect[Runtime Detection]
end
Code --> Build --> Scan --> Sign --> Registry
User --> OIDC --> Kubeconfig --> APIServer
Registry --> Admission
APIServer --> Authn --> Authz --> Admission --> Etcd
APIServer --> Audit
Etcd --> Kubelet
Kubelet --> RuntimeEngine --> Pod
Pod --> Net
RuntimeEngine --> Detect
Audit --> Detect
5.2. API-Anfragepfad
sequenceDiagram
participant Client as kubectl / Controller / GitOps
participant API as kube-apiserver
participant Authn as Authentifizierung
participant Authz as Autorisierung
participant Admission as Admission
participant Etcd as etcd
participant Audit as Audit Backend
Client->>API: Request
API->>Audit: RequestReceived
API->>Authn: Wer bist du?
Authn-->>API: Benutzer / Gruppen / ServiceAccount
API->>Authz: Darfst du das?
Authz-->>API: allow / deny
API->>Admission: Validieren / Mutieren
Admission-->>API: allow / deny / patch
API->>Etcd: Persistieren
API->>Audit: ResponseComplete
API-->>Client: Antwort
5.3. Kontrollmatrix
| Phase | Präventiv | Detektiv | Reaktiv |
|---|---|---|---|
| Code | Review, SAST, Dependency Pinning | Secret-Scanning | Revert, Token-Rotation |
| Build | isolierte Runner, SBOM, Signatur | Build-Audit, Provenance-Prüfung | Runner neu aufsetzen |
| Registry | RBAC, Immutable Tags, Scans | Registry-Audit | Image sperren, Pull blockieren |
| Admission | PSS, RBAC, Kyverno, Gatekeeper, CEL | Policy Reports, Audit | Policy korrigieren, Ausnahme entfernen |
| Runtime | SecurityContext, NetworkPolicy | Falco, Tetragon, Logs, Metrics | Pod isolieren, Node rotieren |
| Data | Encryption, Secrets extern | Access Logs, KMS Logs | Keys rotieren, Restore |
| Operations | Change-Prozess, Backup | Monitoring, SIEM | Incident Response, DR |
6. Umgebungen und Verantwortlichkeiten
Security-Kontrollen unterscheiden sich stark nach Umgebung. Du musst immer klären, wer welche Schicht kontrolliert.
6.1. Verantwortungsmodell
| Umgebung | Control Plane | Nodes | Netzwerk | Storage | Typische Security-Verantwortung |
|---|---|---|---|---|---|
| WSL | lokal / experimentell | Windows + WSL | Host NAT / Mirrored | lokales Dateisystem | Lernumgebung sichern, keine echten Secrets |
| kind | Container auf Docker/Podman | lokaler Host | Docker-Netz | lokale Volumes | schnelle Tests, Admission und Manifeste prüfen |
| minikube | lokaler Single-Node-Cluster | lokaler Host/VM/Container | Treiberabhängig | lokales Storage | Labs, Add-on-Verhalten, Ingress-Tests |
| k3d | k3s in Containern | lokaler Host | Docker-Netz | lokale Volumes | schnelle k3s-nahe Tests |
| lokale VM | du | du | du | du | OS, Runtime, kubeadm, Firewall, Backup |
| Remote-VM | du + Provider | du | Provider-Netz + du | Provider-Disks + du | Cloud-Firewall, SSH, kubeadm, Backup |
| Bare Metal | du | du | du | du | vollständige Verantwortung bis Firmware/BMC |
| EKS | AWS | du oder AWS je Node-Typ | AWS + du | AWS + du | IAM, Pod Identity, Security Groups, Logs, Add-ons |
| AKS | Microsoft | du oder Microsoft je Modus | Azure + du | Azure + du | Entra ID, Azure Policy, Defender, Key Vault |
| GKE | du oder Google je Modus | Google + du | Google + du | IAM/RBAC, Workload Identity, Binary Authorization | |
| OpenShift | Plattformteam/Provider | Plattformteam/Provider | Plattformteam/Provider | Plattformteam/Provider | SCC, Operators, Routes, Projects, OAuth |
| Talos | du | deklarativ via Talos API | du | du | Immutable OS, API-gesicherte Node-Verwaltung |
6.2. Entscheidungsdiagramm
flowchart TD
A[Welche Umgebung?] --> B{Nur Lernen oder CI?}
B -- ja --> C[kind, minikube, k3d]
B -- nein --> D{Produktionsnaher Betrieb?}
D -- lokal --> E[VM, Bare Metal, kubeadm, k3s, RKE2, Talos]
D -- cloud --> F[EKS, AKS, GKE, OKE, DOKS, LKE]
D -- Enterprise PaaS --> G[OpenShift]
C --> H[Keine echten Secrets, Host schützen, Policies testen]
E --> I[OS, Runtime, API, etcd, CNI, Storage selbst härten]
F --> J[Provider-IAM, private Endpunkte, Workload Identity, Logs]
G --> K[SCC, OAuth, Operators, Projects, ClusterRoles]
6.3. Security-Ausnahmen je Umgebung
| Umgebung | Erlaubte Vereinfachung | Nicht akzeptabel |
|---|---|---|
| lokales Lab | Self-signed TLS, Demo-Secrets, Single Node | echte Kundendaten, produktive Cloud-Tokens |
| CI-Cluster | kurzlebiger Cluster, vereinfachte Ingress-Regeln | persistente Admin-Tokens, unisolierte Runner mit Produktivzugriff |
| Dev-Cluster | weniger strenge Availability | fehlende RBAC-Trennung, offene Secrets, kein Audit |
| Staging | produktionsnahe Policies | andere Images/Policies als Produktion ohne Begründung |
| Produktion | kontrollierte Ausnahmen | cluster-admin für Apps, privileged Pods ohne Review, offene API |
7. API-Sicherheit
Der API Server ist die zentrale Steuerungsebene. Fast jede Sicherheitsentscheidung führt irgendwann zur Kubernetes API.
7.1. Risiken
- kubeconfig-Dateien mit Admin-Rechten werden weitergegeben.
- API-Endpunkte sind öffentlich erreichbar.
- Alte Zertifikate oder Tokens laufen nicht ab.
- Benutzer bekommen
cluster-admin, weil RBAC-Design fehlt. - Audit Logs fehlen oder werden nicht ausgewertet.
- Admission Webhooks sind unsicher betrieben oder lassen bei Fehlern alles durch.
7.2. API-Zugriff absichern
| Kontrolle | Empfehlung |
|---|---|
| Netzwerkzugriff | API privat halten oder per IP-Allowlist, VPN, Bastion, Zero-Trust-Zugang begrenzen |
| Identität | OIDC/SSO mit MFA statt statischer Client-Zertifikate für Menschen |
| kubeconfig | keine Admin-kubeconfigs auf Laptops verteilen; Exec-Plugins bevorzugen |
| Break Glass | separat, zeitlich begrenzt, stark auditiert, nicht für Alltagsarbeit |
| Audit | API-Audit aktivieren beziehungsweise Provider-Audit-Logs anbinden |
| Zertifikate | Ablauf überwachen, Rotation dokumentieren, CA-Material schützen |
7.3. kubeconfig sicher behandeln
kubectl config get-contexts
kubectl config view --minify
kubectl config current-context
Prüfe regelmäßig:
find ~/.kube -type f -maxdepth 2 -print -exec ls -l {} \;
Sichere Mindestregeln:
~/.kube/configsollte nur für deinen Benutzer lesbar sein.- kubeconfigs gehören nicht in Git.
- kubeconfigs gehören nicht in Tickets, Chat, Wikis oder Lernmaterialien.
- In Trainings verwendest du Demo-Cluster und Demo-Credentials.
- Für CI/CD verwendest du kurzlebige OIDC-Flows oder dedizierte ServiceAccounts mit minimalen Rechten.
7.4. API-Server-Flags in selbst betriebenen Clustern
Bei kubeadm liegen API-Server-Parameter typischerweise im Static-Pod-Manifest:
sudo grep -n "audit\|authorization\|admission\|encryption" /etc/kubernetes/manifests/kube-apiserver.yaml
Wichtige Themen:
| Thema | Ziel |
|---|---|
--authorization-mode |
Node,RBAC oder organisationsspezifisch erweitert |
--enable-admission-plugins |
notwendige Admission Controller aktivieren |
--audit-policy-file |
Audit Policy laden |
--audit-log-path oder Webhook |
Audit Events persistieren |
--encryption-provider-config |
Secrets und andere sensible Ressourcen verschlüsseln |
--anonymous-auth |
anonyme Zugriffe vermeiden, sofern nicht zwingend benötigt |
| TLS-Flags | sichere Zertifikate und CAs verwenden |
7.5. API-Sicherheitsprüfung
kubectl version
kubectl cluster-info
kubectl auth whoami
kubectl auth can-i --list
kubectl get --raw /readyz?verbose
kubectl get --raw /livez?verbose
Für produktive Umgebungen prüfst du zusätzlich:
kubectl get clusterrolebinding -o wide
kubectl get validatingwebhookconfiguration,mutatingwebhookconfiguration
kubectl get validatingadmissionpolicy,validatingadmissionpolicybinding
kubectl get mutatingadmissionpolicy,mutatingadmissionpolicybinding
8. Authentifizierung, Autorisierung und Admission
Jede API-Anfrage durchläuft mehrere Stufen.
flowchart LR
Request[API Request] --> Authn[Authentifizierung]
Authn --> Authz[Autorisierung]
Authz --> Admission[Admission]
Admission --> Etcd[Persistenz in etcd]
Admission --> Audit[Audit]
8.1. Authentifizierung
Kubernetes kennt keine native User-API für Menschen. Benutzeridentitäten kommen aus externen Mechanismen.
Typische Methoden:
| Methode | Einsatz |
|---|---|
| X.509 Client-Zertifikate | Cluster-Admin, kubeadm, Komponenten, selten für Menschen im Alltag |
| Bearer Tokens | ServiceAccounts, externe Systeme, Legacy-Flows |
| OIDC | SSO für Menschen und CI/CD |
| Webhook Token Auth | Provider-Integration, zum Beispiel EKS |
| Exec Credential Plugin | Cloud-CLI erzeugt kurzlebige Tokens für kubeconfig |
Empfehlung:
- Menschen verwenden SSO/OIDC mit MFA.
- Maschinen verwenden kurzlebige, zweckgebundene Tokens.
- Legacy-Token-Secrets werden vermieden.
- Zertifikatslaufzeiten werden überwacht.
8.2. Autorisierung
Die häufigste Autorisierung ist RBAC. Kubernetes kann weitere Modi nutzen, aber in den meisten Plattformen ist RBAC die zentrale Steuerung.
Autorisierungsfragen:
kubectl auth can-i get pods -n demo
kubectl auth can-i create deployments -n demo
kubectl auth can-i get secrets -A
kubectl auth can-i '*' '*' --all-namespaces
kubectl auth can-i get pods --as alice@example.com -n demo
kubectl auth can-i get secrets --as system:serviceaccount:demo:app -n demo
8.3. Admission
Admission Controller werden nach Authentifizierung und Autorisierung, aber vor Persistenz in etcd ausgeführt.
Typische Admission-Kontrollen:
| Kontrolle | Zweck |
|---|---|
| Pod Security Admission | Pod Security Standards erzwingen, warnen oder auditieren |
| ResourceQuota | Ressourcenverbrauch je Namespace begrenzen |
| LimitRanger | Defaults und Grenzen für Containerressourcen setzen |
| ValidatingAdmissionPolicy | deklarative CEL-basierte Validierung im API Server |
| MutatingAdmissionPolicy | deklarative Mutation im API Server, ab Kubernetes v1.36 stabil |
| ValidatingWebhook | externe Validierung, zum Beispiel Gatekeeper, Kyverno, eigene Webhooks |
| MutatingWebhook | externe Mutation, zum Beispiel Sidecar-Injection |
8.4. Admission-Fehler sicher behandeln
Webhook-Ausfälle sind ein Betriebs- und Sicherheitsrisiko.
| Einstellung | Bedeutung | Empfehlung |
|---|---|---|
failurePolicy: Fail |
API-Anfrage wird bei Webhook-Fehler blockiert | für harte Sicherheitskontrollen |
failurePolicy: Ignore |
API-Anfrage läuft trotz Fehler weiter | nur für nicht-kritische Kontrollen |
timeoutSeconds |
Timeout je Webhook | kurz halten, messen, alarmieren |
namespaceSelector |
Geltungsbereich | systemkritische Namespaces bewusst behandeln |
objectSelector |
Objektfilter | sparsam nutzen, Umgehungen prüfen |
8.5. Admission-Review-Kommandos
kubectl get validatingwebhookconfiguration -o wide
kubectl get mutatingwebhookconfiguration -o wide
kubectl describe validatingwebhookconfiguration <name>
kubectl describe mutatingwebhookconfiguration <name>
kubectl get validatingadmissionpolicy,validatingadmissionpolicybinding
kubectl get mutatingadmissionpolicy,mutatingadmissionpolicybinding
kubectl get events -A --sort-by=.lastTimestamp | grep -i admission
9. RBAC und Least Privilege
RBAC ist eine der wichtigsten Kubernetes-Kontrollen. Fehlkonfigurationen führen direkt zu Privilege Escalation.
9.1. RBAC-Objekte
| Objekt | Scope | Aufgabe |
|---|---|---|
| Role | Namespace | Rechte innerhalb eines Namespaces definieren |
| ClusterRole | Cluster | Clusterweite oder wiederverwendbare Rechte definieren |
| RoleBinding | Namespace | Role oder ClusterRole an Subjekte in einem Namespace binden |
| ClusterRoleBinding | Cluster | ClusterRole clusterweit an Subjekte binden |
9.2. Subjekte
RBAC kann gebunden werden an:
- Benutzer,
- Gruppen,
- ServiceAccounts.
Beispiele:
subjects:
- kind: User
name: alice@example.com
- kind: Group
name: platform-admins
- kind: ServiceAccount
name: app
namespace: demo
9.3. Gefährliche Berechtigungen
| Berechtigung | Risiko |
|---|---|
cluster-admin |
Vollzugriff auf Cluster |
* auf * |
auch zukünftige Ressourcen und CRDs betroffen |
create pods |
kann zur Ausführung von Code im Cluster führen |
create pods/exec |
direkter Shell-Zugriff in Container |
get/list/watch secrets |
Zugriff auf sensible Daten und Tokens |
create rolebindings |
Rechte können an sich selbst oder andere gebunden werden |
bind |
Rollen binden, auch wenn man deren Rechte nicht besitzt |
escalate |
Rollen mit höheren Rechten erstellen oder ändern |
impersonate |
als andere Identität handeln |
nodes/proxy |
Zugriff auf kubelet-APIs, potenziell Container-Exec auf Nodes |
certificatesigningrequests/approval |
Zertifikate ausstellen oder genehmigen |
update validatingwebhookconfigurations |
Admission-Schutz schwächen |
update mutatingwebhookconfigurations |
Mutation manipulieren |
update namespaces |
Pod-Security-Labels entfernen |
9.4. RBAC-Review
kubectl get role,rolebinding -A
kubectl get clusterrole,clusterrolebinding
kubectl describe clusterrolebinding cluster-admin
kubectl get clusterrolebinding -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.roleRef.name}{"\t"}{range .subjects[*]}{.kind}:{.namespace}:{.name}{","}{end}{"\n"}{end}'
Suche nach Wildcards:
kubectl get clusterrole -o yaml | grep -n "\*"
kubectl get role -A -o yaml | grep -n "\*"
Prüfe Secrets-Zugriffe:
kubectl get clusterrole,role -A -o yaml | grep -n -B5 -A10 "secrets"
Prüfe Impersonation, Bind und Escalate:
kubectl get clusterrole,role -A -o yaml | grep -n -B5 -A10 "impersonate\|bind\|escalate"
9.5. Sichere Rollen entwerfen
Vorgehen:
- Beschreibe den Use Case.
- Ermittle benötigte API-Ressourcen.
- Verwende
RolestattClusterRole, wenn Namespace-Scope genügt. - Verwende nur konkrete Verben.
- Vermeide Wildcards.
- Trenne lesen, schreiben, deployen, administrieren.
- Teste mit
kubectl auth can-i. - Dokumentiere Besitzer, Zweck und Ablaufdatum.
9.6. Beispiel: Entwicklerrolle im Namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: developer-workload-editor
namespace: team-a
labels:
security.example.com/owner: platform
rules:
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: [""]
resources: ["pods", "pods/log", "services", "configmaps"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
Diese Rolle erlaubt nicht:
- Secrets lesen,
- RBAC ändern,
- Pods direkt execen,
- NetworkPolicies ändern,
- Namespace-Labels ändern,
- Cluster-Objekte ändern.
9.7. Break-Glass-Modell
Break-Glass-Zugänge sind Notfallzugänge. Sie gehören nicht in den Alltag.
Mindestregeln:
- wenige Personen,
- MFA,
- getrennte Konten,
- zeitlich begrenzte Aktivierung,
- Audit und Alarmierung,
- Pflicht zur Nachdokumentation,
- regelmäßige Testübung,
- sofortige Sperrung bei Austritt oder Rollenwechsel.
9.8. RBAC-Anti-Patterns
| Anti-Pattern | Warum kritisch |
|---|---|
cluster-admin für CI/CD |
Kompromittierte Pipeline übernimmt Cluster |
cluster-admin für Argo CD ohne Scope |
Git-Repo wird Cluster-Root |
| Wildcards in Rollen | zukünftige CRDs automatisch eingeschlossen |
get secrets für Entwicklergruppen |
Geheimnisse werden zu normalen Konfigurationsdaten |
pods/exec breit vergeben |
Shell-Zugriff wird Standard statt Ausnahme |
Namespace-Admin darf RoleBindings auf cluster-admin setzen |
direkte Eskalation |
| ServiceAccount-Token automatisch in jedem Pod | unnötige API-Credentials in kompromittierbaren Pods |
10. ServiceAccounts und Workload-Identitäten
ServiceAccounts sind Identitäten für Prozesse in Pods. Sie sind keine Benutzerkonten für Menschen.
10.1. Risiken
- Default-ServiceAccount wird überall genutzt.
- Tokens werden automatisch in Pods gemountet.
- ServiceAccounts haben zu breite Rollen.
- Tokens landen in Logs, Debug-Dumps oder Container-Dateisystemen.
- Cloud-Zugriffe laufen über Node-Rollen statt Workload-Identitäten.
10.2. Standardregeln
| Regel | Empfehlung |
|---|---|
| eigener ServiceAccount je Workload | ja |
default-ServiceAccount verwenden |
nein |
automountServiceAccountToken: false |
Standard, außer API-Zugriff ist nötig |
| Rollen scope-minimal | Namespace statt Cluster |
| Cloud-Zugriff | Workload Identity, Pod Identity, Managed Identity, nicht Node-Rolle |
| Token-Rotation | kurzlebige, gebundene Tokens bevorzugen |
10.3. ServiceAccount ohne Token-Mount
apiVersion: v1
kind: ServiceAccount
metadata:
name: frontend
namespace: shop
automountServiceAccountToken: false
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: shop
spec:
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
serviceAccountName: frontend
automountServiceAccountToken: false
containers:
- name: app
image: ghcr.io/example/frontend:1.0.0
10.4. ServiceAccount mit minimalem API-Zugriff
apiVersion: v1
kind: ServiceAccount
metadata:
name: config-reader
namespace: shop
automountServiceAccountToken: true
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: read-configmaps
namespace: shop
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: config-reader-read-configmaps
namespace: shop
subjects:
- kind: ServiceAccount
name: config-reader
namespace: shop
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: read-configmaps
10.5. Cloud-Workload-Identitäten
flowchart LR
Pod[Pod] --> SA[Kubernetes ServiceAccount]
SA --> OIDC[Cluster OIDC Issuer]
OIDC --> CloudIAM[Cloud IAM Trust]
CloudIAM --> Resource[Cloud Resource]
| Provider | Mechanismus | Ziel |
|---|---|---|
| AWS EKS | EKS Pod Identity oder IRSA | Pod bekommt IAM-Rolle statt Node-Rolle |
| Azure AKS | Microsoft Entra Workload ID / Managed Identity | Pod nutzt Azure-Identität ohne statisches Secret |
| Google GKE | Workload Identity Federation for GKE | Pod erhält Google IAM-Zugriff ohne JSON-Key |
| Oracle OKE | Workload Identity / Instance Principal je Design | Cloud-Zugriffe trennen |
| generisch | OIDC Federation | kurzlebige, zweckgebundene Cloud-Tokens |
10.6. Prüfkommandos
kubectl get serviceaccounts -A
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.serviceAccountName}{"\t"}{.spec.automountServiceAccountToken}{"\n"}{end}'
kubectl auth can-i --as system:serviceaccount:shop:frontend --list -n shop
kubectl get rolebinding,clusterrolebinding -A -o yaml | grep -n "ServiceAccount"
11. Namespace- und Mandantentrennung
Namespaces sind keine harte Sicherheitsgrenze wie separate Cluster. Sie sind eine Verwaltungs- und Policy-Grenze.
11.1. Wofür Namespaces geeignet sind
- Team-Trennung,
- RBAC-Scope,
- ResourceQuota,
- LimitRange,
- NetworkPolicies,
- Pod Security Admission,
- Secret-Scope,
- GitOps-App-Grenzen,
- Kosten- und Ownership-Labels.
11.2. Wofür Namespaces nicht ausreichen
Namespaces trennen nicht automatisch:
- Node-Kernel,
- Container Runtime,
- CNI-Dataplane,
- clusterweite Ressourcen,
- CRDs,
- Webhooks,
- Storage-Backends,
- Cloud-IAM,
- Cluster-Admin-Zugriffe.
Für echte Mandantentrennung brauchst du zusätzliche Kontrollen oder separate Cluster.
11.3. Namespace-Baseline
apiVersion: v1
kind: Namespace
metadata:
name: team-a-prod
labels:
owner.example.com/team: team-a
environment.example.com/stage: prod
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: team-a-prod
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.memory: 16Gi
pods: "50"
persistentvolumeclaims: "10"
---
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-a-prod
spec:
limits:
- type: Container
defaultRequest:
cpu: 100m
memory: 128Mi
default:
memory: 512Mi
max:
memory: 2Gi
11.4. Multi-Tenancy-Modelle
| Modell | Beschreibung | Geeignet für |
|---|---|---|
| Namespace je Team | mehrere Teams in einem Cluster | interne Plattformen mit moderatem Risiko |
| Namespace je App | feinere Isolation | GitOps und Kostenkontrolle |
| Cluster je Umgebung | dev/stage/prod getrennt | klare Betriebsgrenzen |
| Cluster je Tenant | harte Mandantentrennung | regulierte oder externe Mandanten |
| Project-Modell OpenShift | Namespace plus Plattformpolicies | OpenShift-Umgebungen |
| Virtual Cluster | API-Isolation über vCluster/Kapsule | Entwicklungsplattformen, nicht immer harte Security-Grenze |
11.5. Namespace-Review
kubectl get ns --show-labels
kubectl get resourcequota,limitrange -A
kubectl get networkpolicy -A
kubectl get rolebinding -A
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.nodeName}{"\n"}{end}'
12. Pod Security Standards und Pod Security Admission
Pod Security Standards definieren drei Profile:
| Profil | Zweck |
|---|---|
| Privileged | weitgehend unbeschränkt, für Infrastruktur-Workloads mit hohem Vertrauen |
| Baseline | verhindert bekannte Privilege-Eskalationen, lässt viele Standard-Workloads laufen |
| Restricted | stark gehärtet, Zielbild für viele produktive App-Workloads |
Pod Security Admission setzt diese Standards über Namespace-Labels um.
12.1. Modi
| Modus | Wirkung |
|---|---|
enforce |
verletzende Pods werden abgelehnt |
audit |
Verletzungen werden in Audit Logs geschrieben |
warn |
Benutzer erhalten Warnungen bei API-Anfragen |
12.2. Baseline vor Restricted migrieren
Für bestehende Plattformen gehst du typischerweise stufenweise vor:
warn=restrictedsetzen.- Warnungen auswerten.
audit=restrictedsetzen.- Ausnahmen dokumentieren.
- Workloads anpassen.
enforce=baselineoderenforce=restrictedaktivieren.- Regressionstests in CI einbauen.
12.3. Namespace mit Warnung statt sofortiger Blockade
apiVersion: v1
kind: Namespace
metadata:
name: migration-test
labels:
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest
12.4. Privileged-Ausnahmen
Einige Plattformkomponenten benötigen mehr Rechte:
- CNI-Agenten,
- CSI-Node-Plugins,
- Node-Exporter mit Host-Mounts,
- Runtime-Security-Agenten,
- Service-Mesh-CNI,
- kube-proxy oder eBPF-Agenten,
- Storage- oder Backup-Agenten.
Regeln für Ausnahmen:
- eigener Namespace,
- eigener Owner,
- Review-Datum,
- Begründung,
- möglichst kein App-Team-Zugriff,
enforce=privilegednur für Systemnamespaces,- Admission-Ausnahmen nicht breit setzen.
12.5. Test eines verbotenen Pods
apiVersion: v1
kind: Pod
metadata:
name: should-fail
namespace: app-prod
spec:
containers:
- name: shell
image: busybox
command: ["sleep", "3600"]
securityContext:
privileged: true
kubectl apply -f should-fail.yaml
Erwartung bei enforce=restricted: Der Pod wird abgelehnt.
13. SecurityContext, Linux-Isolation und Container-Härtung
Pod Security Admission ist nur eine Schicht. Du solltest Workloads selbst sicher deklarieren.
13.1. Empfohlene Container-SecurityContext
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault
Hinweis: seccompProfile kann auf Pod- oder Container-Ebene gesetzt werden. runAsNonRoot und runAsUser müssen zum Image passen.
13.2. Pod-SecurityContext
spec:
securityContext:
runAsNonRoot: true
fsGroup: 10001
fsGroupChangePolicy: OnRootMismatch
seccompProfile:
type: RuntimeDefault
13.3. Capabilities
Linux Capabilities erlauben einzelne privilegierte Aktionen ohne vollständigen Root-Kontext. In Kubernetes solltest du standardmäßig alle droppen und nur begründet hinzufügen.
| Capability | Risiko |
|---|---|
NET_ADMIN |
Netzwerk manipulieren, Routing, Interfaces |
SYS_ADMIN |
sehr breit, häufig praktisch privileged |
SYS_PTRACE |
Prozesse inspizieren |
DAC_READ_SEARCH |
Dateisystemrechte umgehen |
CHOWN |
Besitz ändern, manchmal nötig |
NET_BIND_SERVICE |
Ports <1024 binden, häufig vermeidbar |
Beispiel für begründete Ausnahme:
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
add: ["NET_BIND_SERVICE"]
Besser ist oft: Anwendung auf Port 8080 hören lassen und Service auf Port 80 mappen.
13.4. Root-Dateisystem read-only
Ein read-only Root-Dateisystem reduziert Persistenz und Manipulation im Container.
securityContext:
readOnlyRootFilesystem: true
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
13.5. Host-Namespace vermeiden
Vermeide in App-Workloads:
hostNetwork: true
hostPID: true
hostIPC: true
Diese Optionen erhöhen Zugriff und Sichtbarkeit auf den Node. Sie sind typischerweise nur für Infrastrukturkomponenten akzeptabel.
13.6. hostPath vermeiden
hostPath verbindet Container direkt mit Node-Dateisystemen. Das ist gefährlich.
Problematische Beispiele:
volumes:
- name: host-root
hostPath:
path: /
type: Directory
Ausnahmen:
- DaemonSets für Monitoring,
- CNI,
- CSI,
- Runtime Detection,
- Node-Agenten.
Jede Ausnahme braucht Review.
13.7. User Namespaces
User Namespaces können die Abbildung von Benutzer-IDs im Container und auf dem Host trennen. Dadurch kann ein Prozess im Container als Root erscheinen, ohne auf dem Host Root zu sein. Prüfe die Unterstützung deiner Kubernetes-Version, Runtime, Distribution und CNI-Konfiguration, bevor du das als Standard einführst.
Beispiel:
apiVersion: v1
kind: Pod
metadata:
name: userns-demo
spec:
hostUsers: false
containers:
- name: app
image: busybox
command: ["sleep", "3600"]
13.8. AppArmor, SELinux und seccomp
| Mechanismus | Zweck | Hinweise |
|---|---|---|
| seccomp | Systemaufrufe begrenzen | RuntimeDefault als Standard setzen |
| AppArmor | Programmprofile für Dateisystem/Netzwerk/Capabilities | vor allem Ubuntu/Debian-Umgebungen |
| SELinux | Mandatory Access Control | relevant bei RHEL, Fedora, OpenShift, RKE2 mit SELinux |
Beispiel seccomp:
securityContext:
seccompProfile:
type: RuntimeDefault
13.9. Prüfung von Workload-Härtung
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.securityContext.runAsNonRoot}{"\t"}{.spec.securityContext.seccompProfile.type}{"\n"}{end}'
Mit jq detaillierter:
kubectl get pods -A -o json | jq -r '
.items[] |
[.metadata.namespace,
.metadata.name,
(.spec.containers[]?.securityContext.privileged // false),
(.spec.containers[]?.securityContext.allowPrivilegeEscalation // "unset"),
(.spec.containers[]?.securityContext.readOnlyRootFilesystem // "unset")]
| @tsv'
14. Admission Policy, Policy as Code und Governance
Admission ist die technische Stelle, an der du unsichere Ressourcen vor dem Start blockierst.
14.1. Policy-Optionen
| Option | Typ | Stärken | Grenzen |
|---|---|---|---|
| Pod Security Admission | eingebaut | einfach, standardisiert | nur Pod-Sicherheitsfelder |
| ValidatingAdmissionPolicy | eingebaut, CEL | kein externer Webhook, schnell | Validierung, keine komplexe externe Logik |
| MutatingAdmissionPolicy | eingebaut, CEL | deklarative Mutation im API Server | Versionsabhängigkeit, nicht für alles geeignet |
| Kyverno | Kubernetes-native Policy Engine | YAML-nah, validate/mutate/generate/verifyImages | zusätzlicher Controller/Webhook |
| OPA Gatekeeper | Rego/OPA | mächtig, auditfähig, viele Libraries | Rego-Know-how nötig |
| eigene Webhooks | beliebig | maximale Flexibilität | Betriebsaufwand, Ausfallrisiko |
| Cloud Policy | Provider | zentrale Governance | Provider-spezifisch |
14.2. ValidatingAdmissionPolicy: latest-Tags verbieten
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: disallow-latest-image-tag
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
validations:
- expression: "object.spec.containers.all(c, !c.image.endsWith(':latest'))"
message: "Container-Images dürfen nicht mit dem Tag latest verwendet werden. Nutze einen versionierten Tag oder Digest."
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: disallow-latest-image-tag-binding
spec:
policyName: disallow-latest-image-tag
validationActions:
- Deny
matchResources:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- kube-system
14.3. Kyverno-Beispiel: runAsNonRoot erzwingen
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-run-as-non-root
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-run-as-non-root
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Pods müssen runAsNonRoot=true setzen."
pattern:
spec:
securityContext:
runAsNonRoot: true
14.4. Kyverno-Beispiel: Images aus erlaubten Registries
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: restrict-image-registries
spec:
validationFailureAction: Enforce
background: true
rules:
- name: only-approved-registries
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Images müssen aus genehmigten Registries stammen."
pattern:
spec:
containers:
- image: "ghcr.io/my-org/* | registry.example.com/*"
Passe Syntax und Version an deine Kyverno-Version an. Teste Policies immer zuerst im Audit- oder Warnmodus.
14.5. Gatekeeper-Beispiel: ConstraintTemplate
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
required := input.parameters.labels[_]
not input.review.object.metadata.labels[required]
msg := sprintf("Label %v fehlt", [required])
}
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-owner-and-env
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels:
- owner.example.com/team
- environment.example.com/stage
14.6. Policy-Lifecycle
flowchart LR
Draft[Policy Entwurf] --> Audit[Audit/Warn-Modus]
Audit --> Report[Policy Reports auswerten]
Report --> Fix[Workloads anpassen]
Fix --> Enforce[Enforce aktivieren]
Enforce --> Monitor[Monitoren]
Monitor --> Review[Regelmäßiger Review]
Review --> Draft
14.7. Governance-Regeln
- Jede Policy hat Owner, Zweck, Schweregrad und Ausnahmeprozess.
- Policies werden versioniert und getestet.
- Systemnamespaces werden separat behandelt.
failurePolicyist bewusst gewählt.- Policies werden vor Cluster-Upgrades validiert.
- Admission-Controller haben PDBs, Monitoring und Ressourcenlimits.
- Policy-Ausnahmen sind zeitlich begrenzt.
15. Secrets, Schlüssel und vertrauliche Daten
Kubernetes Secrets sind für vertrauliche Daten gedacht, aber sie sind nicht automatisch ausreichend geschützt. Base64 ist Kodierung, keine Verschlüsselung.
15.1. Secret-Risiken
| Risiko | Beispiel | Kontrolle |
|---|---|---|
| Secrets in Git | password: supersecret im Manifest |
SOPS, Sealed Secrets, External Secrets, Secret-Scanning |
| Secrets in Logs | App loggt Env Vars | Log-Scrubbing, App-Review, keine Secrets als Env wenn vermeidbar |
| breites RBAC | Entwickler können alle Secrets lesen | Namespace-spezifische Rollen, keine list secrets |
| etcd unverschlüsselt | Snapshot enthält Klartext | Encryption at Rest, Snapshot-Schutz |
| statische Cloud Keys | JSON-Key im Secret | Workload Identity / Pod Identity |
| fehlende Rotation | DB-Passwort jahrelang gültig | Rotation, kurze TTLs, dynamische Secrets |
15.2. Secret-Verwendungsarten
| Methode | Vorteil | Risiko |
|---|---|---|
| Env Var | einfach | landet häufig in Dumps, schwerer rotierbar |
| Volume Mount | Rotation besser möglich | Datei-Rechte und App-Reload beachten |
| CSI Secret Store | externe Quelle, kein dauerhaftes Kubernetes Secret nötig | Provider/Driver-Komplexität |
| External Secrets Operator | Synchronisierung aus externem Secret Manager | Controller braucht Zugriff auf Secret Backend |
| SOPS/Sealed Secrets | GitOps-freundlich | Schlüsselmanagement kritisch |
| Vault Agent / Injector | dynamische Secrets | zusätzliche Plattformkomponente |
15.3. Kubernetes Secret mit Demo-Wert
kubectl create secret generic demo-secret \
-n app-prod \
--from-literal=username=demo \
--from-literal=password='not-for-production' \
--dry-run=client -o yaml
15.4. Secrets nicht ausgeben
Vermeide in Schulungen:
kubectl get secret app-secret -o yaml
kubectl get secret app-secret -o jsonpath='{.data.password}' | base64 -d
Wenn du es demonstrieren musst, verwende bewusst Dummy-Werte und lösche Shell-Historie in Lab-Umgebungen.
15.5. Encryption at Rest
Beispiel für eine Encryption Configuration in selbst betriebenen Clustern:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
- configmaps
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-32-byte-key>
- identity: {}
API Server einbinden:
- --encryption-provider-config=/etc/kubernetes/encryption/encryption-config.yaml
Nach Aktivierung musst du bestehende Objekte neu schreiben, damit sie verschlüsselt gespeichert werden:
kubectl get secrets -A -o json | kubectl replace -f -
In Produktion solltest du KMS-Provider oder Provider-spezifische Key-Management-Integrationen bevorzugen, wenn verfügbar.
15.6. Externe Secret-Systeme
| System | Typischer Einsatz |
|---|---|
| HashiCorp Vault | dynamische Secrets, PKI, Datenbank-Credentials, Kubernetes Auth |
| AWS Secrets Manager | EKS-Workloads mit Pod Identity/IRSA |
| AWS SSM Parameter Store | Konfiguration und einfache Secrets |
| Azure Key Vault | AKS mit Workload Identity oder CSI Driver |
| Google Secret Manager | GKE mit Workload Identity Federation |
| External Secrets Operator | Kubernetes-native Synchronisierung aus externen Backends |
| Secrets Store CSI Driver | Secrets als Volume aus externen Backends |
| Mozilla SOPS | verschlüsselte GitOps-Manifeste |
| Bitnami Sealed Secrets | public-key-basierte Secret-Verschlüsselung für Git |
15.7. Secret-Rotation
Rotation umfasst:
- neues Secret erzeugen,
- Anwendung kompatibel machen,
- Secret ausrollen,
- Workload reloaden oder neu starten,
- altes Secret invalidieren,
- Zugriff und Logs prüfen,
- Dokumentation aktualisieren.
Beispiel Restart nach Secret-Änderung:
kubectl rollout restart deployment/app -n app-prod
kubectl rollout status deployment/app -n app-prod
15.8. Secret-Leak-Runbook Kurzfassung
- Secret als kompromittiert behandeln.
- Nutzung sperren oder Passwort/API-Key rotieren.
- Logs und Audit prüfen.
- betroffene Workloads neu deployen.
- Git-Historie und Artefakte bereinigen, falls Secret dort lag.
- Root Cause beheben.
- Detection verbessern.
16. etcd- und Control-Plane-Schutz
etcd speichert den Cluster-Zustand. Wer etcd lesen oder manipulieren kann, kontrolliert effektiv den Cluster.
16.1. etcd-Risiken
- Secrets in Klartext bei fehlender Encryption at Rest,
- ungeschützte Snapshots,
- Zugriff auf etcd-Zertifikate,
- fehlende TLS-Absicherung,
- kein Restore-Test,
- unsichere Control-Plane-Nodes,
- fehlendes Monitoring für Leader, Latenz, Disk und Quorum.
16.2. Selbst betriebene Cluster
Prüfe:
sudo ls -l /etc/kubernetes/pki/etcd
sudo crictl ps | grep etcd
sudo grep -n "etcd" /etc/kubernetes/manifests/etcd.yaml
etcd-Snapshot:
sudo ETCDCTL_API=3 etcdctl snapshot save /var/backups/etcd/etcd-$(date +%F-%H%M).db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
Snapshot-Status:
ETCDCTL_API=3 etcdctl snapshot status /var/backups/etcd/<snapshot>.db -w table
Sicherheitsregeln:
- Snapshots verschlüsseln.
- Snapshots nicht auf Control-Plane-Nodes als einzige Kopie belassen.
- Restore regelmäßig testen.
- Zugriff auf etcd-Zertifikate begrenzen.
- Control-Plane-Nodes nicht für normale Workloads nutzen.
- API Server und etcd nicht öffentlich exponieren.
16.3. Managed Kubernetes
Bei EKS, AKS, GKE und ähnlichen Diensten verwaltet der Provider die Control Plane. Du steuerst dennoch:
- API-Endpunkt-Erreichbarkeit,
- Cloud-IAM,
- Audit-/Control-Plane-Logs,
- Secrets Encryption/KMS-Optionen,
- Add-ons,
- Nodes,
- Workload-Identitäten,
- NetworkPolicies,
- RBAC,
- Backup der Kubernetes-Ressourcen und PV-Daten.
16.4. Control-Plane-Härtung in kubeadm
sudo ls -l /etc/kubernetes/manifests
sudo grep -n "authorization-mode\|admission\|audit\|encryption" /etc/kubernetes/manifests/kube-apiserver.yaml
sudo grep -n "profiling\|bind-address" /etc/kubernetes/manifests/kube-controller-manager.yaml
sudo grep -n "profiling\|bind-address" /etc/kubernetes/manifests/kube-scheduler.yaml
Typische Ziele:
- RBAC aktiv,
- NodeAuthorizer aktiv,
- Admission-Plugins passend,
- Audit aktiviert,
- Profiling deaktiviert oder abgeschottet,
- bind-address nicht unnötig offen,
- Zertifikate regelmäßig geprüft.
17. Node-, Host- und Runtime-Härtung
Ein Node ist eine kritische Sicherheitsgrenze. Wenn ein Angreifer Node-Zugriff erhält, sind alle Pods auf diesem Node gefährdet.
17.1. Node-Baseline
| Bereich | Kontrolle |
|---|---|
| OS | unterstützte Version, automatische Security Updates oder Patchfenster |
| SSH | minimal, MFA/Bastion, keine Passwortauthentifizierung |
| Firewall | nur notwendige Ports, kubelet nicht öffentlich |
| Runtime | containerd oder CRI-O aktuell, keine Docker-Socket-Mounts |
| kubelet | anonyme Auth deaktivieren, Webhook Authz, Zertifikate schützen |
| Kernel | LSM aktivieren, sysctl kontrollieren, unnötige Module vermeiden |
| Filesystem | separate Partitionen je Bedarf, Logs rotieren, sensible Pfade schützen |
| Monitoring | Node Exporter, Runtime Logs, kubelet Logs, Disk/Memory/Pressure |
| Lifecycle | Nodes drainen und ersetzen statt manuell reparieren |
17.2. kubelet-Schutz
kubelet stellt eine HTTPS-API bereit. Diese API kann sensible Informationen liefern und je nach Rechten mächtige Aktionen erlauben.
Prüfung:
sudo cat /var/lib/kubelet/config.yaml | grep -E "anonymous|authorization|authentication" -n
sudo ss -lntp | grep kubelet
Zielwerte:
authentication:
anonymous:
enabled: false
webhook:
enabled: true
authorization:
mode: Webhook
RBAC für nodes/proxy prüfst du besonders streng:
kubectl get clusterrole -o yaml | grep -n -B5 -A15 "nodes/proxy"
kubectl get clusterrolebinding -o yaml | grep -n -B5 -A15 "nodes"
17.3. Container Runtime
Prüfe Runtime:
kubectl get nodes -o wide
crictl info
crictl ps
systemctl status containerd --no-pager
systemctl status crio --no-pager
Empfehlungen:
- keine Docker-Socket-Mounts in Pods,
- Runtime regelmäßig patchen,
- keine unsicheren Registries außer bewusst und isoliert,
- Registry-Mirrors mit TLS,
- cgroup-Treiber konsistent mit kubelet,
- Runtime-Logs zentral erfassen.
17.4. Docker-Socket-Anti-Pattern
Sehr kritisch:
volumeMounts:
- name: docker-sock
mountPath: /var/run/docker.sock
volumes:
- name: docker-sock
hostPath:
path: /var/run/docker.sock
Wer den Docker- oder Container-Runtime-Socket kontrolliert, kann häufig den Host kompromittieren. Nutze stattdessen:
- rootless Build-Tools,
- BuildKit in isolierter Umgebung,
- Kaniko mit Einschränkungen,
- Cloud Build Services,
- dedizierte Build-Cluster,
- separate Runner ohne Produktivzugriff.
17.5. Node-Isolation
Trenne Nodes nach Risiko:
| Node Pool | Workloads |
|---|---|
| system | CoreDNS, CNI, CSI, Ingress, Monitoring |
| default | normale Apps |
| high-security | sensible Workloads |
| privileged | CNI/CSI/Runtime-Agenten mit Host-Zugriff |
| gpu | GPU-Workloads |
| edge | Edge-spezifische Workloads |
Beispiel Taint:
kubectl taint nodes node-a dedicated=system:NoSchedule
Beispiel Toleration:
tolerations:
- key: dedicated
operator: Equal
value: system
effect: NoSchedule
18. Netzwerksicherheit
Ohne NetworkPolicies ist Pod-Kommunikation in vielen Clustern offen. NetworkPolicies funktionieren nur, wenn das CNI-Plugin Enforcement unterstützt.
18.1. Netzwerkzonen
flowchart TB
Internet[Internet] --> Edge[Load Balancer / WAF]
Edge --> Ingress[Ingress Controller / Gateway]
Ingress --> App[App Namespace]
App --> DB[Database Namespace]
App --> DNS[CoreDNS]
App --> Egress[Egress Gateway / NAT]
Egress --> External[Externe APIs]
Monitor[Monitoring] --> App
Security[Runtime Security] --> App
18.2. NetworkPolicy-Grundlagen
NetworkPolicies wählen Pods über Labels aus. Sobald eine Policy für Ingress oder Egress auf einen Pod passt, ist dieser Pod in dieser Richtung isoliert und nur explizit erlaubter Traffic funktioniert.
18.3. Default-Deny pro Namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress-egress
namespace: team-a
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
18.4. Ingress von Ingress Controller erlauben
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-controller-to-web
namespace: team-a
spec:
podSelector:
matchLabels:
app: web
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
podSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
ports:
- protocol: TCP
port: 8080
18.5. App zu Datenbank erlauben
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-to-postgres
namespace: database
spec:
podSelector:
matchLabels:
app: postgres
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
owner.example.com/team: team-a
podSelector:
matchLabels:
app: api
ports:
- protocol: TCP
port: 5432
18.6. Egress zu externer API
Kubernetes NetworkPolicy kann IP-Blöcke, aber keine FQDNs im Standardmodell. FQDN-basierte Egress-Kontrolle brauchst du über CNI-Erweiterungen, Egress-Gateway, Proxy oder Service Mesh.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-egress-payment-provider
namespace: team-a
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 203.0.113.0/24
ports:
- protocol: TCP
port: 443
18.7. CNI-spezifische Erweiterungen
| CNI | Security-relevante Fähigkeiten |
|---|---|
| Calico | NetworkPolicy, GlobalNetworkPolicy, HostEndpoint, Egress-Regeln je Edition |
| Cilium | eBPF, CiliumNetworkPolicy, DNS/FQDN-Policies, Hubble, L7-Policies |
| Antrea | NetworkPolicy, ClusterNetworkPolicy, Flow Visibility |
| Flannel | einfaches Pod-Netz, keine NetworkPolicy ohne zusätzliche Komponenten |
| Weave Net | NetworkPolicy-Unterstützung, historisch verbreitet |
18.8. Egress-Strategien
| Strategie | Vorteil | Nachteil |
|---|---|---|
| NAT Gateway | einfach | keine App-feine Kontrolle |
| HTTP Proxy | FQDN/URL-Kontrolle | App-Konfiguration nötig |
| Egress Gateway | zentraler Ausleitungspunkt | CNI/Service-Mesh-Abhängigkeit |
| Cilium FQDN Policy | Kubernetes-nah | Cilium-spezifisch |
| Service Mesh | mTLS, L7-Policies | Komplexität, Sidecars oder Ambient Mode |
| Cloud Firewall | gute Provider-Integration | begrenzte Pod-Identität je Lösung |
18.9. Netzwerk-Troubleshooting
kubectl get networkpolicy -A
kubectl describe networkpolicy -n team-a
kubectl run netshoot -n team-a --rm -it --image=nicolaka/netshoot --restart=Never -- bash
nslookup kubernetes.default.svc.cluster.local
curl -v http://service.namespace.svc.cluster.local:8080
Prüfe immer:
- Pod-Labels,
- Namespace-Labels,
- CNI-Support,
- DNS-Egress,
- Ingress-Controller-Namespace,
- Service-Port vs. TargetPort,
- Node-Firewalls,
- Cloud-Security-Groups.
19. Ingress, Gateway, TLS und externe Erreichbarkeit
Ingress und Gateway API sind zentrale Angriffsflächen, weil sie interne Workloads nach außen exponieren.
19.1. Ingress-Risiken
- TLS fehlt oder ist falsch konfiguriert.
- Wildcard-Hosts routen unerwartet.
- Admin-Endpunkte sind öffentlich.
- Ingress-Controller hat zu breite RBAC-Rechte.
- Unsichere Annotationen erlauben Snippet Injection.
- Rate-Limits und Body-Limits fehlen.
- Fehlende Authentifizierung für interne Tools.
19.2. Gateway API Rollenmodell
flowchart LR
Infra[Infrastrukturteam] --> GatewayClass[GatewayClass]
Platform[Plattformteam] --> Gateway[Gateway]
AppTeam[App-Team] --> HTTPRoute[HTTPRoute]
GatewayClass --> Gateway
Gateway --> HTTPRoute
HTTPRoute --> Service[Service]
19.3. TLS-Standard
- HTTP auf HTTPS umleiten.
- TLS-Zertifikate automatisiert ausstellen und erneuern.
- Wildcard-Zertifikate nur mit Review.
- Private Services nicht öffentlich routen.
- HSTS nur bewusst aktivieren.
- Zertifikatsablauf alarmieren.
19.4. cert-manager Beispiel
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-example-com
namespace: app-prod
spec:
secretName: app-example-com-tls
dnsNames:
- app.example.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
19.5. Gateway API Beispiel
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: public-gateway
namespace: gateways
spec:
gatewayClassName: nginx
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
mode: Terminate
certificateRefs:
- name: wildcard-example-com
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: app
namespace: app-prod
spec:
parentRefs:
- name: public-gateway
namespace: gateways
hostnames:
- app.example.com
rules:
- backendRefs:
- name: app
port: 8080
19.6. Externe Endpunkte in lokalen Umgebungen
| Umgebung | Zugriff | Security-Hinweis |
|---|---|---|
| WSL | Windows Browser über localhost, Host-Datei oder Port-Forward |
Windows-Hosts-Datei nur für Demo-Domains ändern |
| kind | extraPortMappings, Ingress-Controller, Host-Port |
Ports bewusst beschränken |
| minikube | minikube tunnel, service, ingress Add-on |
Adminrechte für Tunnel beachten |
| k3d | LoadBalancer-Port-Mappings | Konflikte mit lokalen Ports vermeiden |
| lokale VM | Bridged/Host-only/NAT | Host-only für Labs bevorzugen |
| Remote-VM | Public IP, Firewall, Reverse Proxy | nur 80/443 öffnen, SSH begrenzen |
20. Image-, Registry- und Supply-Chain-Security
Kubernetes kann nur das ausführen, was du ihm gibst. Unsichere Images sind eine der häufigsten Ursachen für Cluster-Kompromittierung.
20.1. Supply-Chain-Fluss
flowchart LR
Dev[Developer] --> Repo[Git Repository]
Repo --> CI[CI Runner]
CI --> Build[Image Build]
Build --> Scan[Vulnerability Scan]
Build --> SBOM[SBOM]
Build --> Sign[Signieren]
Sign --> Registry[Registry]
Registry --> Admission[Admission Verification]
Admission --> Cluster[Kubernetes Cluster]
Cluster --> Runtime[Runtime Detection]
20.2. Image-Baseline
| Kontrolle | Empfehlung |
|---|---|
| Base Images | minimal, gepflegt, definierte Herkunft |
| Tags | keine latest in Produktion |
| Digests | für kritische Workloads pinnen |
| CVE-Scans | Build-Zeit und Registry-Zeit |
| Secrets | keine Secrets im Image oder Build-Arg |
| SBOM | erzeugen, speichern, mit Release verknüpfen |
| Signaturen | Cosign/Sigstore oder Registry-native Signaturverfahren |
| Provenance | Build-Herkunft dokumentieren, SLSA-orientiert |
| Registry | RBAC, Immutable Tags, Retention, Malware-Scan |
20.3. Image mit Digest verwenden
containers:
- name: app
image: registry.example.com/team/app@sha256:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
20.4. Trivy-Scan
trivy image registry.example.com/team/app:1.2.3
trivy image --severity HIGH,CRITICAL --exit-code 1 registry.example.com/team/app:1.2.3
trivy fs .
trivy config ./k8s
20.5. SBOM mit Syft
syft registry.example.com/team/app:1.2.3 -o spdx-json > sbom.spdx.json
syft registry.example.com/team/app:1.2.3 -o cyclonedx-json > sbom.cyclonedx.json
20.6. Signieren und Verifizieren mit Cosign
cosign sign registry.example.com/team/app:1.2.3
cosign verify registry.example.com/team/app:1.2.3
cosign verify-attestation registry.example.com/team/app:1.2.3
20.7. Admission für signierte Images
Mögliche Wege:
- Kyverno
verifyImages, - Sigstore policy-controller,
- Connaisseur,
- Cloud-native Binary Authorization,
- eigene Validating Webhooks.
20.8. Registry-RBAC
| Rolle | Rechte |
|---|---|
| Build Runner | Push in spezifische Repositories |
| Deployment Controller | Pull, kein Push |
| Entwickler | Pull Dev-Images, kein Prod-Push direkt |
| Security Scanner | Pull und Metadaten lesen |
| Admin | selten, break-glass, auditiert |
20.9. Unsichere Image-Patterns
latest,- unversionierte Base Images,
- Root-User im Image,
- Paketmanager und Shell in Runtime-Images ohne Bedarf,
- SSH-Server im Container,
- Debug-Tools in Produktion,
- Secrets in Layers,
- nicht reproduzierbare Builds,
- Pull aus öffentlichen Registries ohne Mirror und Prüfung.
21. CI/CD- und GitOps-Security
CI/CD und GitOps sind Teil der Kubernetes-Angriffsfläche. Ein kompromittierter Deployment-Controller kann produktive Cluster verändern.
21.1. CI/CD-Risiken
- Runner hat Zugriff auf produktive Secrets.
- Pull Requests können untrusted Code mit Secrets ausführen.
- Deployment-Tokens sind statisch und langlebig.
- Build-Images sind nicht gehärtet.
- Artefakte sind nicht signiert.
- Branch Protection fehlt.
21.2. CI/CD-Baseline
| Kontrolle | Empfehlung |
|---|---|
| Branch Protection | Pflichtreviews, Status Checks, signierte Commits optional |
| Secrets | keine Secrets für untrusted Pull Requests |
| Runner | isoliert, ephemer, minimal berechtigt |
| Deployment | OIDC oder kurzlebige Tokens statt statischer kubeconfigs |
| Scans | SAST, IaC, Container, Dependency, Secret-Scanning |
| Provenance | Build-Attestations speichern |
| Logs | Secrets maskieren, Retention und Zugriff regeln |
21.3. GitOps-Risiken
| Risiko | Kontrolle |
|---|---|
| GitOps Controller hat Cluster-Admin | Rechte auf Zielnamespaces begrenzen |
| App darf Cluster-Ressourcen deployen | AppProject/Policy begrenzen |
| Drift wird automatisch überschrieben | Drift bewusst monitoren, manuelle Änderungen sperren |
| Secrets in Git | SOPS, External Secrets, Sealed Secrets |
| Webhook-Secret geleakt | Rotation und IP-Allowlist |
| Supply-Chain-Manipulation | Signaturen, Reviews, branch protection |
21.4. Argo CD Baseline
- SSO aktivieren.
- Lokale Admin-Konten deaktivieren oder stark schützen.
- AppProjects nutzen.
- Zielnamespaces einschränken.
- Cluster-scoped Ressourcen beschränken.
- Repo-Zugriff minimal vergeben.
- Sync-Windows für kritische Umgebungen prüfen.
- Notifications/Audit anbinden.
21.5. Flux Baseline
- Git-Zugriffe mit deploy keys minimal begrenzen.
- SOPS oder External Secrets nutzen.
- Kustomization-Scope prüfen.
- Controller-RBAC minimieren.
- Image Automation nur mit Review-Prozess nutzen.
- Drift und Reconciliation Events monitoren.
22. Storage- und Daten-Security
Storage ist nicht nur Verfügbarkeit. Storage betrifft Datenklassifikation, Verschlüsselung, Zugriff, Backup und Löschung.
22.1. Storage-Risiken
- PV enthält personenbezogene oder geheime Daten.
- StorageClass provisioniert unverschlüsselte Volumes.
- ReclaimPolicy löscht Daten unerwartet oder behält sie zu lange.
- Backup enthält Secrets oder Kundendaten.
- Snapshot-Rechte sind zu breit.
- Pods mounten fremde PVCs.
- hostPath umgeht Storage-Kontrollen.
22.2. StorageClass Security
kubectl get storageclass -o yaml
kubectl get pv,pvc -A
kubectl get volumesnapshotclass
Prüfe:
| Thema | Frage |
|---|---|
| Encryption | Sind Volumes standardmäßig verschlüsselt? |
| KMS | Wird ein kundeneigener Schlüssel genutzt? |
| ReclaimPolicy | Delete oder Retain bewusst gewählt? |
| VolumeBindingMode | WaitForFirstConsumer für Topologie? |
| AccessModes | Wird RWX nur bei Bedarf verwendet? |
| Snapshots | Wer darf Snapshots erstellen und lesen? |
| Backup | Sind Backups verschlüsselt und getestet? |
22.3. PVC-Zugriff minimieren
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data
namespace: app-prod
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: encrypted-standard
22.4. Snapshot-RBAC begrenzen
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: snapshot-reader
namespace: app-prod
rules:
- apiGroups: ["snapshot.storage.k8s.io"]
resources: ["volumesnapshots"]
verbs: ["get", "list", "watch"]
22.5. Datenklassifikation
| Klasse | Beispiele | Anforderungen |
|---|---|---|
| Öffentlich | Demo-Daten, statische Assets | Standardkontrollen |
| Intern | Konfigurationsdaten, interne Logs | RBAC, Backup, Retention |
| Vertraulich | Kundendaten, Tokens, Geschäftsgeheimnisse | Verschlüsselung, Zugriffskontrolle, Audit |
| Hochsensibel | Schlüsselmaterial, Zahlungsdaten, Gesundheitsdaten | strenge Isolation, KMS, besondere Compliance, minimierter Zugriff |
23. Observability, Audit, Detection und Forensik
Security ohne Sichtbarkeit ist nicht belastbar. Du brauchst Metriken, Logs, Audit Events und Runtime-Signale.
23.1. Signalarten
| Signal | Quelle | Security-Nutzen |
|---|---|---|
| Metriken | kube-state-metrics, node-exporter, cAdvisor | Anomalien, Ressourcenmissbrauch |
| Logs | Pod Logs, kubelet, API Server, Controller | Fehler, Angriffsindikatoren |
| Audit Logs | kube-apiserver oder Provider | Wer hat was wann getan? |
| Events | Kubernetes Events | Scheduling, Pull, Admission, Crashs |
| Runtime Events | Falco, Tetragon, eBPF | Shells, verdächtige Dateien, Netzwerk |
| Cloud Logs | CloudTrail, Azure Activity, GCP Audit Logs | Cloud-IAM und Provideraktionen |
| Network Flow Logs | CNI, Cloud VPC Flow Logs, Hubble | Lateral Movement, Egress |
23.2. Audit Policy Beispiel
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
resources:
- group: ""
resources: ["secrets", "configmaps"]
- level: RequestResponse
verbs: ["create", "update", "patch", "delete"]
resources:
- group: "rbac.authorization.k8s.io"
resources: ["roles", "rolebindings", "clusterroles", "clusterrolebindings"]
- level: Request
verbs: ["create", "update", "patch", "delete"]
resources:
- group: "admissionregistration.k8s.io"
resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"]
- level: Metadata
omitStages:
- RequestReceived
Achte darauf, keine Secret-Werte unnötig in Audit Logs zu schreiben. Audit-Level RequestResponse kann sensible Inhalte enthalten.
23.3. Alert-Kategorien
| Kategorie | Beispiel |
|---|---|
| API-Missbrauch | cluster-admin Binding erstellt |
| RBAC-Eskalation | bind, escalate, impersonate genutzt |
| Secret-Zugriff | ungewöhnlich viele Secret Reads |
| Admission-Bypass | Webhook gelöscht oder failurePolicy geändert |
| Pod-Risiko | privileged Pod gestartet |
| Runtime | Shell in Container, neues Binary, Zugriff auf /etc/shadow |
| Netzwerk | ungewöhnlicher Egress, DNS-Tunneling-Indizien |
| Node | kubelet nicht erreichbar, Node NotReady, Kernel Alerts |
| Registry | kritische CVE in produktivem Image |
| Backup | Backup fehlgeschlagen oder Restore-Test überfällig |
23.4. PrometheusRule Beispiele
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: kubernetes-security-alerts
namespace: monitoring
spec:
groups:
- name: kubernetes-security
rules:
- alert: KubeAPIServerAuditErrorsHigh
expr: increase(apiserver_audit_event_total{stage="Panic"}[5m]) > 0
for: 2m
labels:
severity: critical
annotations:
summary: "Audit-Panic-Events im API Server"
description: "Der API Server hat Audit Events im Panic-Stage erzeugt."
- alert: TooManyPodsPending
expr: count(kube_pod_status_phase{phase="Pending"}) > 20
for: 10m
labels:
severity: warning
annotations:
summary: "Viele Pods sind Pending"
description: "Kann auf Quota-, Scheduling-, CNI- oder Policy-Probleme hinweisen."
23.5. Forensik-Grundsätze
- Verändere den Zustand so wenig wie möglich.
- Sichere Logs, Events, Manifeste und Image-Digests.
- Notiere Zeiträume und Zeitzonen.
- Rotiere Credentials erst nach Sicherung notwendiger Spuren, sofern das Risiko es zulässt.
- Kompromittierte Nodes werden isoliert und ersetzt.
- Nutze Snapshots nur nach Datenschutz- und Freigabeprozess.
23.6. Beweissicherung bei verdächtigem Pod
NS=app-prod
POD=demo-app-abc123
mkdir -p incident-$NS-$POD
kubectl get pod "$POD" -n "$NS" -o yaml > incident-$NS-$POD/pod.yaml
kubectl describe pod "$POD" -n "$NS" > incident-$NS-$POD/describe.txt
kubectl logs "$POD" -n "$NS" --all-containers > incident-$NS-$POD/logs-current.txt
kubectl logs "$POD" -n "$NS" --all-containers --previous > incident-$NS-$POD/logs-previous.txt || true
kubectl get events -n "$NS" --sort-by=.lastTimestamp > incident-$NS-$POD/events.txt
24. Runtime Security
Runtime Security erkennt verdächtiges Verhalten, nachdem ein Workload gestartet ist.
24.1. Was Runtime Security erkennt
- Shell in Container,
- neue ausführbare Dateien,
- Zugriff auf sensible Pfade,
- ungewöhnliche Netzwerkverbindungen,
- Prozessstarts außerhalb des erwarteten Profils,
- Privilege-Escalation-Versuche,
- Container Escape-Indikatoren,
- Kubernetes API-Missbrauch,
- verdächtige Cloud-API-Aufrufe.
24.2. Falco-Baseline
Falco beobachtet Kernel-Events und andere Quellen und erzeugt Alerts anhand von Regeln.
Beispiel-Regel:
- rule: Shell spawned in container
desc: Eine Shell wurde in einem Container gestartet
condition: container.id != host and proc.name in (bash, sh, zsh, csh)
output: Shell in container gestartet (user=%user.name command=%proc.cmdline container=%container.name image=%container.image.repository)
priority: WARNING
tags: [container, shell, mitre_execution]
24.3. Tetragon und eBPF
Tetragon ist besonders relevant in Cilium-Umgebungen. Es kann Prozess-, Netzwerk- und Security-Events auf Basis von eBPF erfassen und Kubernetes-Kontext hinzufügen.
Typische Einsatzfälle:
- Prozessausführung in Pods,
- Netzwerkverbindungen,
- Datei- oder Syscall-nahe Erkennung,
- Policy-nahe Runtime Enforcement je Setup.
24.4. Runtime Detection Architektur
flowchart LR
Kernel[Linux Kernel Events] --> Agent[Runtime Agent: Falco/Tetragon]
K8s[Kubernetes API Kontext] --> Agent
Runtime[Container Runtime] --> Agent
Agent --> Alerts[Alerts]
Alerts --> SIEM[SIEM / Log Backend]
Alerts --> IR[Incident Response]
24.5. Runtime Alert Triage
| Alert | Erste Fragen |
|---|---|
| Shell in Container | War es ein erlaubtes Debugging? Wer hat exec genutzt? |
Write below /etc |
App-Verhalten oder Kompromittierung? read-only root FS aktiv? |
| Connection to unknown IP | legitimer Egress oder C2? DNS-Abfrage prüfen |
| Privileged container | Systemkomponente oder App-Ausnahme? Admission hätte blockieren müssen? |
| Sensitive file read | Welche Datei, welcher Prozess, welcher Benutzer? |
| Crypto miner indicator | Image, Prozess, Egress, CPU-Spike prüfen |
25. Backup-, Restore- und Disaster-Recovery-Security
Backups sind sicherheitskritisch. Sie enthalten oft den vollständigsten Datenbestand.
25.1. Was gesichert werden muss
| Artefakt | Warum relevant |
|---|---|
| Git-Repositories | Zielzustand, Manifeste, IaC |
| IaC-State | Cloud-Ressourcen, IDs, Outputs |
| etcd | Cluster-State selbst betriebener Cluster |
| Kubernetes-Ressourcen | Namespaces, RBAC, CRDs, Deployments, Services |
| PV-Daten | Applikationsdaten |
| Secrets | Wiederherstellung, aber besonders schützen |
| Zertifikate | API, etcd, Ingress, mTLS |
| Registry-Images | Wiederaufbau bei Registry-Ausfall |
| KMS-Schlüssel | Entschlüsselung von Secrets und Volumes |
| Observability-Daten | Forensik und Compliance |
25.2. Backup-Sicherheitsregeln
- Backups verschlüsseln.
- Zugriff auf Backups streng begrenzen.
- Restore regelmäßig testen.
- Backup-Retention definieren.
- Offsite-Kopie oder getrennte Region nutzen.
- Backup-Integrität prüfen.
- Ransomware-Schutz für Backup-Buckets aktivieren, wenn verfügbar.
- Secrets und KMS-Schlüssel getrennt betrachten.
25.3. Velero Backup Beispiel
apiVersion: velero.io/v1
kind: Schedule
metadata:
name: daily-prod
namespace: velero
spec:
schedule: "0 2 * * *"
template:
includedNamespaces:
- app-prod
ttl: 720h0m0s
storageLocation: default
snapshotVolumes: true
25.4. Restore-Test
velero backup create app-prod-manual --include-namespaces app-prod
velero backup describe app-prod-manual
velero restore create app-prod-restore-test --from-backup app-prod-manual --namespace-mappings app-prod:app-prod-restore
velero restore describe app-prod-restore-test
kubectl get all,pvc,secret,configmap -n app-prod-restore
25.5. DR-Security-Fragen
- Wer darf Restore auslösen?
- Darf ein Restore alte verwundbare Images zurückbringen?
- Werden Secret-Rotationen nach Restore erzwungen?
- Wird RBAC mit wiederhergestellt?
- Werden alte Admission-Policies wiederhergestellt?
- Gibt es einen isolierten Restore-Test-Cluster?
- Sind Backups nach Region/Provider-Ausfall verfügbar?
26. Patch-, Update- und Vulnerability-Management
Security ist ein Lifecycle-Thema. Kubernetes-Versionen, Node-Images, Add-ons und Images müssen gepflegt werden.
26.1. Patch-Ebenen
| Ebene | Beispiele |
|---|---|
| OS | Ubuntu, RHEL, Bottlerocket, COS, Azure Linux, Talos |
| Kernel | CVEs, eBPF, Filesystem, Container Escape |
| Container Runtime | containerd, CRI-O, runc |
| Kubernetes | API Server, kubelet, kube-proxy, Controller, Scheduler |
| Add-ons | CNI, CSI, Ingress, cert-manager, External Secrets, Monitoring |
| Workloads | App Images, Dependencies, Base Images |
| Cloud-Ressourcen | Load Balancer, IAM, KMS, Firewall, Registry |
| CI/CD | Runner Images, Actions, Plugins, Tokens |
26.2. Vulnerability Workflow
flowchart LR
Detect[CVE oder Advisory] --> Assess[Betroffenheit prüfen]
Assess --> Risk[Schwere und Exponierung bewerten]
Risk --> Plan[Patch-Plan]
Plan --> Test[Testcluster / Staging]
Test --> Rollout[Produktiver Rollout]
Rollout --> Verify[Validierung]
Verify --> Document[Dokumentation]
26.3. Kubernetes Upgrade Security
Vor Upgrade:
kubectl version
kubectl get nodes -o wide
kubectl get apiservices
kubectl get validatingwebhookconfiguration,mutatingwebhookconfiguration
kubectl get crd
kubectl get events -A --sort-by=.lastTimestamp | tail -100
Prüfe:
- Version Skew,
- deprecated APIs,
- Admission-Kompatibilität,
- CNI/CSI-Kompatibilität,
- Backup und Restore,
- Node-Drain-Verhalten,
- PodDisruptionBudgets,
- Cluster-Autoscaler-Kompatibilität,
- Security-relevante Release Notes.
26.4. Image-CVE-Triage
Nicht jede CVE ist gleich kritisch. Bewerte:
- Wird die verwundbare Library tatsächlich verwendet?
- Ist der Codepfad erreichbar?
- Ist der Pod öffentlich erreichbar?
- Läuft der Container als Root?
- Gibt es NetworkPolicy und Egress-Kontrolle?
- Gibt es Runtime Detection?
- Gibt es einen Fix oder nur Mitigation?
- Ist ein Rebuild mit neuer Base-Image-Version möglich?
26.5. Patch-SLAs Beispiel
| Schwere | Zielzeit |
|---|---|
| Kritisch, ausnutzbar, exponiert | 24 bis 72 Stunden |
| Hoch | 7 bis 14 Tage |
| Mittel | 30 Tage |
| Niedrig | regulärer Wartungszyklus |
| Nicht anwendbar | dokumentierte Ausnahme |
27. Security je Kubernetes-Variante
27.1. kubeadm
kubeadm gibt dir viel Kontrolle und viel Verantwortung.
Wichtige Kontrollen:
- OS-Härtung,
- containerd/CRI-O sicher konfigurieren,
- kubelet Webhook Authn/Authz,
- API-Audit,
- Secrets Encryption at Rest,
- etcd-Snapshots,
- CNI mit NetworkPolicy,
- Control-Plane-Endpoint absichern,
- Zertifikatsrotation,
- Upgrade-Disziplin.
Prüfkommandos:
kubeadm version
kubeadm certs check-expiration
kubectl get nodes -o wide
sudo ls /etc/kubernetes/manifests
sudo journalctl -u kubelet --no-pager | tail -100
27.2. k3s
k3s ist leichtgewichtig und oft für Edge, Labs und kleinere Cluster geeignet.
Security-Fokus:
- Server-Token schützen,
- Embedded etcd oder externe DB absichern,
- Traefik/ServiceLB bewusst aktivieren oder deaktivieren,
- lokale Registry-Mirrors sicher konfigurieren,
- Node-Zugriff minimieren,
- Secret Encryption prüfen,
- Systemd-Unit und Installationsskripte reviewen.
Beispiele:
sudo systemctl status k3s
sudo cat /etc/rancher/k3s/config.yaml
kubectl get nodes -o wide
kubectl get pods -A
27.3. RKE2
RKE2 ist stärker auf produktionsnahe und gehärtete Umgebungen ausgerichtet.
Security-Fokus:
- CIS-Profil prüfen,
- SELinux nutzen, wenn passend,
- statische Pod-Manifeste und Add-ons versionieren,
- Server- und Agent-Tokens schützen,
- etcd-Snapshots verschlüsselt sichern,
- System-Namespaces trennen.
27.4. k0s
k0s bietet eine schlanke Kubernetes-Distribution mit eigener Cluster-Konfiguration.
Security-Fokus:
- Controller/Worker-Rollen sauber trennen,
- k0s-Konfiguration versionieren,
- Join-Tokens kurzlebig behandeln,
- CNI und Storage bewusst wählen,
- kubelet und Runtime prüfen,
- Backup/Restore von Cluster-State testen.
27.5. Talos Linux
Talos ist ein immutable OS für Kubernetes. Verwaltung erfolgt über die Talos API, nicht über SSH.
Security-Fokus:
- MachineConfig als sensiblen Zielzustand behandeln,
talosconfigschützen,- keine klassische SSH-Verwaltung,
- API-Zugriff begrenzen,
- disk encryption prüfen,
- Cluster- und Machine-Secrets sicher speichern,
- Upgrades deklarativ und reproduzierbar fahren.
27.6. Docker Desktop Kubernetes
Geeignet für lokale Entwicklung, nicht für produktive Security-Übungen mit echten Secrets.
Security-Fokus:
- keine produktiven kubeconfigs und Tokens in Docker Desktop verwenden,
- lokale Images und Volumes regelmäßig bereinigen,
- Kubernetes-Kontext eindeutig benennen,
- keine öffentlichen Demo-Ingresses mit echten Daten.
27.7. MicroK8s
MicroK8s ist praktisch für lokale Labs, Edge und Ubuntu-nahe Umgebungen.
Security-Fokus:
- Add-ons bewusst aktivieren,
- lokale Benutzergruppen prüfen,
- Snap-Updates kontrollieren,
- Registry und Ingress absichern,
- Host-Firewall prüfen.
28. Security je Umgebung
28.1. WSL unter Windows 11
WSL ist eine starke Lern- und CLI-Umgebung, aber kein vollständiger Produktionsersatz.
Risiken:
- Windows-Host und WSL teilen Angriffsflächen.
- Dateien unter
/mnt/chaben andere Rechte- und Performance-Eigenschaften. - Docker Desktop Integration erweitert Trust Boundary.
- Windows-Hosts-Datei kann lokale Namensauflösung beeinflussen.
- Echte Cloud-Credentials liegen leicht im Home-Verzeichnis.
Empfehlungen:
- Keine echten Produktionssecrets in WSL-Labs.
- kubeconfig-Kontexte klar benennen.
- Windows Defender/EDR nicht umgehen.
- Lokale Demo-Domains klar als Demo markieren, zum Beispiel
*.127.0.0.1.nip.iooder*.localtest.me. - Windows-Hosts-Datei nur bewusst und dokumentiert ändern.
- Git-Repository nicht mit echten Secrets befüllen.
Windows-Hosts-Datei aus WSL sichern:
sudo cp /mnt/c/Windows/System32/drivers/etc/hosts /mnt/c/Windows/System32/drivers/etc/hosts.k8s-backup
Eintrag hinzufügen, wenn du erhöhte Rechte hast:
printf "127.0.0.1 app.local\n" | sudo tee -a /mnt/c/Windows/System32/drivers/etc/hosts
Rückbau:
sudo cp /mnt/c/Windows/System32/drivers/etc/hosts.k8s-backup /mnt/c/Windows/System32/drivers/etc/hosts
28.2. kind
kind nutzt Kubernetes-Nodes als Container. Es ist ideal für Policy-, Admission-, CI- und Manifesttests.
Security-Hinweise:
- Host-Docker/Podman ist die eigentliche Sicherheitsgrenze.
- Keine echten Secrets.
extraPortMappingsbewusst setzen.- lokale Registry nur mit Demo-Images nutzen.
- Cluster nach Tests löschen.
Beispiel:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 80
hostPort: 8080
protocol: TCP
- containerPort: 443
hostPort: 8443
protocol: TCP
28.3. minikube
minikube ist für lokale Entwicklung und Labs geeignet.
Security-Hinweise:
- Treiber bestimmt Risiko: Docker, VirtualBox, VMware, Hyper-V, SSH.
minikube tunnelkann erhöhte Rechte benötigen.- Add-ons aktivieren zusätzliche Komponenten mit RBAC.
- Lokale Images und Secrets regelmäßig bereinigen.
minikube start --driver=docker
minikube addons enable ingress
minikube addons enable metrics-server
minikube status
28.4. k3d
k3d betreibt k3s in Docker-Containern.
Security-Hinweise:
- Docker-Host schützen.
- Port-Mappings bewusst setzen.
- Traefik oder eigene Ingress-Lösung bewusst wählen.
- Cluster nach Tests löschen.
k3d cluster create lab \
--servers 1 \
--agents 2 \
-p "8080:80@loadbalancer" \
-p "8443:443@loadbalancer"
28.5. Lokale VM
Security-Fokus:
- VM-Snapshots vor riskanten Labs,
- Host-only-Netz für private Labs,
- NAT/Bridged nur bei Bedarf,
- SSH-Key statt Passwort,
- Firewall aktiv,
- keine privaten Cloud-Credentials in Snapshots.
28.6. Remote-VM
Security-Fokus:
- Cloud-Firewall zuerst, Host-Firewall zusätzlich,
- SSH nur von bekannten IPs,
- API Server nicht öffentlich öffnen,
- Kubernetes-Dashboard nicht öffentlich,
- lokale kubeconfigs schützen,
- Disks verschlüsseln,
- Snapshot-Zugriff begrenzen.
28.7. Bare Metal
Security-Fokus:
- Firmware/BIOS/UEFI und BMC absichern,
- Management-Netz trennen,
- PXE/Provisioning-Netz schützen,
- Disk Encryption prüfen,
- physischer Zugriff berücksichtigen,
- Hardware-Supply-Chain bewerten,
- Out-of-band-Zugänge auditieren.
29. Cloud-spezifische Security
Managed Kubernetes reduziert Control-Plane-Betrieb, aber nicht deine Plattformverantwortung.
29.1. AWS EKS
Wichtige Kontrollen:
- private oder eingeschränkte API-Endpunkte,
- IAM Identity Center oder IAM-basierte Authentifizierung sauber modellieren,
- EKS Access Entries statt historisch gewachsener
aws-auth-Unordnung prüfen, - EKS Pod Identity oder IRSA für Workloads,
- Node IAM Role minimal halten,
- Security Groups und NACLs prüfen,
- Control Plane Logs aktivieren,
- Secrets Encryption mit KMS,
- GuardDuty EKS Protection prüfen,
- ECR-Scanning und Image-Signaturen,
- Managed Node Groups oder Fargate je Risiko bewerten.
Prüfkommandos:
aws eks describe-cluster --name <cluster>
aws eks list-access-entries --cluster-name <cluster>
aws eks list-pod-identity-associations --cluster-name <cluster>
aws eks update-kubeconfig --name <cluster> --region <region>
kubectl get nodes -o wide
29.2. Azure AKS
Wichtige Kontrollen:
- Microsoft Entra ID Integration,
- Azure RBAC für Kubernetes Authorization bewusst wählen,
- private Cluster oder API Authorized IP Ranges,
- AKS Workload Identity,
- Azure Policy für Kubernetes,
- Microsoft Defender for Containers,
- Azure Key Vault CSI Driver oder External Secrets,
- Network Policies mit Azure CNI/Cilium/Calico je Setup,
- Node OS Upgrades und Wartungsfenster,
- Container Registry mit Scans und RBAC.
Prüfkommandos:
az aks show -g <resource-group> -n <cluster>
az aks get-credentials -g <resource-group> -n <cluster>
az aks update -g <resource-group> -n <cluster> --enable-oidc-issuer --enable-workload-identity
kubectl get nodes -o wide
29.3. Google GKE
Wichtige Kontrollen:
- IAM und Kubernetes RBAC sauber trennen,
- Workload Identity Federation for GKE nutzen,
- Autopilot für starke Managed Defaults prüfen,
- private Cluster und Master Authorized Networks,
- Shielded GKE Nodes,
- Binary Authorization,
- Artifact Registry Scans,
- Cloud KMS für Secrets und Storage,
- Cloud Audit Logs und Security Command Center,
- GKE Release Channels und Wartungsfenster.
Prüfkommandos:
gcloud container clusters describe <cluster> --region <region>
gcloud container clusters get-credentials <cluster> --region <region>
kubectl get nodes -o wide
29.4. Oracle OKE
Wichtige Kontrollen:
- private API-Endpunkte prüfen,
- OCI IAM Policies minimal halten,
- Worker Nodes in privaten Subnetzen,
- Network Security Groups,
- Vault/KMS-Integration,
- Logging und Audit aktivieren,
- Image Scanning in OCIR prüfen.
29.5. DigitalOcean DOKS
Wichtige Kontrollen:
- kubeconfig-Zugriff begrenzen,
- API-Zugriff und Teamrechte prüfen,
- Container Registry RBAC,
- Load Balancer und Firewall-Regeln,
- Secrets extern verwalten,
- NetworkPolicies mit unterstütztem CNI prüfen.
29.6. Linode/Akamai LKE
Wichtige Kontrollen:
- Cloud Firewall,
- Node-Pool-Zugriff,
- API- und kubeconfig-Schutz,
- Longhorn/CSI-Storage-Security,
- Registry- und Secret-Management,
- Monitoring und Audit über Provider-Optionen ergänzen.
29.7. Multi-Cloud
Multi-Cloud erhöht nicht automatisch Security. Es erhöht Komplexität.
Notwendige Standards:
- einheitliche RBAC-Rollenmodelle,
- einheitliche Labels und Namespaces,
- zentrale Policy-Bibliothek,
- Secret-Backend je Provider oder föderiert,
- einheitliche Audit-Log-Sammlung,
- identische Admission-Gates,
- klare Cluster-Inventarisierung,
- Provider-spezifische Ausnahmen dokumentieren.
30. OpenShift, OKD und SCC
OpenShift ergänzt Kubernetes um eigene Plattformkonzepte. Security Context Constraints, Routes, Operators, Projects und OAuth sind dabei besonders relevant.
30.1. SCC statt nur Pod Security Admission
Security Context Constraints steuern, unter welchen Sicherheitsbedingungen Pods laufen dürfen. Sie sind OpenShift-spezifisch und historisch zentral für Pod-Security.
Prüfung:
oc get scc
oc describe scc restricted-v2
oc adm policy who-can use scc restricted-v2
30.2. OpenShift Security-Baseline
| Bereich | Kontrolle |
|---|---|
| OAuth | IdP, Gruppen, MFA über IdP |
| Projects | Team- und App-Grenzen |
| SCC | restriktive SCCs, Ausnahmen dokumentieren |
| Routes | TLS, HSTS, öffentliche Exposition |
| Operators | OperatorHub-Quellen, Subscription-Kanäle, RBAC |
| ImageStreams | Registry-Trust und ImportPolicies |
| Builds | BuildConfigs und Secrets prüfen |
| MachineConfig | Node-Härtung deklarativ steuern |
30.3. OpenShift-Anti-Patterns
anyuidbreit vergeben,privilegedSCC für App-Namespaces,- ClusterRoleBindings ohne Gruppenmodell,
- Operatoren ohne Lifecycle-Plan,
- Routes ohne TLS,
- Build-Secrets in falschen Namespaces,
- lokale Admin-Konten ohne Audit.
31. Compliance, Benchmarks und Audits
Compliance ist kein Ersatz für Security Engineering. Sie hilft aber, Kontrollen messbar zu machen.
31.1. CIS Kubernetes Benchmark
Der CIS Kubernetes Benchmark enthält konkrete Konfigurationsempfehlungen für Kubernetes und Provider-Varianten.
Typische Bereiche:
- API Server,
- Controller Manager,
- Scheduler,
- etcd,
- kubelet,
- Policies,
- RBAC,
- NetworkPolicies,
- Secrets,
- Pod Security.
31.2. kube-bench
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl get pods -n default
kubectl logs job/kube-bench
Für Produktion solltest du Manifeste vor Anwendung prüfen, Image-Version pinnen und den Scope kontrollieren.
31.3. NSA/CISA-Hardening-orientierte Kontrollen
Typische Themen:
- Container und Pods auf Schwachstellen und Fehlkonfigurationen scannen,
- least privilege für Container und Pods,
- Netzwerksegmentierung,
- starke Authentifizierung,
- Audit Logging,
- Secrets schützen,
- gefährliche Workload-Optionen vermeiden,
- Nodes härten.
31.4. Audit-Artefakte
| Artefakt | Zweck |
|---|---|
| Cluster-Inventar | Umfang und Verantwortung belegen |
| RBAC-Export | Rechte prüfen |
| Policy-Reports | Admission-Compliance prüfen |
| NetworkPolicy-Liste | Segmentierung nachweisen |
| Pod Security Labels | Namespace-Härtung prüfen |
| Secret-Zugriffsauswertung | Zugriff auf vertrauliche Daten bewerten |
| Backup-Protokolle | DR-Fähigkeit belegen |
| Restore-Testbericht | Wiederherstellung nachweisen |
| Patch-Status | Schwachstellenmanagement belegen |
| Audit Logs | nachvollziehbare Änderungen |
31.5. Audit-Export
mkdir -p audit-export
kubectl get ns --show-labels > audit-export/namespaces.txt
kubectl get role,rolebinding -A -o yaml > audit-export/rbac-namespaced.yaml
kubectl get clusterrole,clusterrolebinding -o yaml > audit-export/rbac-cluster.yaml
kubectl get networkpolicy -A -o yaml > audit-export/networkpolicies.yaml
kubectl get pods -A -o yaml > audit-export/pods.yaml
kubectl get validatingwebhookconfiguration,mutatingwebhookconfiguration -o yaml > audit-export/webhooks.yaml
kubectl get validatingadmissionpolicy,validatingadmissionpolicybinding -o yaml > audit-export/validating-admission-policies.yaml || true
kubectl get resourcequota,limitrange -A -o yaml > audit-export/quotas-limits.yaml
Schütze diese Exporte. Sie können Secrets, interne Namen, Images und Architekturdetails enthalten.
32. Tooling-Matrix
| Kategorie | Tools | Zweck |
|---|---|---|
| RBAC Review | kubectl auth can-i, rbac-tool, rakkess |
Rechte prüfen |
| CIS | kube-bench, Kubescape | Benchmark-Checks |
| Manifest Security | kube-score, Polaris, Checkov, KICS, Datree | YAML/IaC-Prüfung |
| Policy | Kyverno, Gatekeeper, ValidatingAdmissionPolicy | Admission/Governance |
| Image Scan | Trivy, Grype, Clair, registry-native Scanner | CVEs und Misconfigurations |
| SBOM | Syft, Trivy, CycloneDX Tools | Softwarebestand erfassen |
| Signatur | Cosign, Sigstore policy-controller, Notary v2 | Image Trust |
| Secrets | SOPS, Sealed Secrets, External Secrets, Vault, CSI Driver | Secret-Verwaltung |
| Runtime | Falco, Tetragon, Tracee | Laufzeiterkennung |
| Network | Cilium Hubble, Calico tools, tcpdump, netshoot | Netzwerktransparenz |
| Cloud Security | GuardDuty, Defender, Security Command Center | Provider-Security |
| GitOps | Argo CD, Flux | deklarative Deployments |
| Audit/SIEM | Loki, OpenSearch, Splunk, Sentinel, Chronicle | zentrale Auswertung |
32.1. Kubescape Beispiel
kubescape scan framework nsa
kubescape scan framework cis
kubescape scan --submit=false
32.2. Polaris Beispiel
polaris audit --audit-path ./manifests --format=pretty
32.3. Checkov Beispiel
checkov -d ./manifests --framework kubernetes
checkov -d ./terraform --framework terraform
32.4. Conftest Beispiel
conftest test deployment.yaml
33. Standard-Runbooks
33.1. Runbook: Kompromittierter Pod
Ziel: Schaden begrenzen, Beweise sichern, Ursache beheben.
- Alarm validieren.
- Namespace, Pod, Node, Image, ServiceAccount erfassen.
- Logs, Events und Manifest sichern.
- Netzwerkzugriff einschränken.
- Pod nicht blind löschen, wenn Forensik erforderlich ist.
- ServiceAccount-Rechte prüfen.
- Secrets rotieren, wenn Zugriff möglich war.
- Image-Digest und Registry-Historie prüfen.
- Workload mit gefixtem Image und Policy neu ausrollen.
- Admission- und Runtime-Regeln verbessern.
Kommandos:
NS=<namespace>
POD=<pod>
kubectl get pod "$POD" -n "$NS" -o wide
kubectl describe pod "$POD" -n "$NS"
kubectl logs "$POD" -n "$NS" --all-containers --previous
kubectl get pod "$POD" -n "$NS" -o jsonpath='{.spec.serviceAccountName}{"\n"}'
kubectl auth can-i --as system:serviceaccount:$NS:$(kubectl get pod "$POD" -n "$NS" -o jsonpath='{.spec.serviceAccountName}') --list -n "$NS"
Containment über NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: isolate-suspect-workload
namespace: app-prod
spec:
podSelector:
matchLabels:
incident.example.com/isolate: "true"
policyTypes:
- Ingress
- Egress
33.2. Runbook: Kompromittierter Node
- Node cordon.
- Scheduling stoppen.
- Workloads je Kritikalität evakuieren oder forensisch sichern.
- Cloud/Host-Netzwerkzugriff begrenzen.
- Node aus Load Balancern entfernen.
- Node-Logs und Runtime-Informationen sichern.
- betroffene Pod-Secrets rotieren.
- Node neu aufbauen oder ersetzen.
- Cluster- und Cloud-Audit prüfen.
NODE=<node>
kubectl cordon "$NODE"
kubectl get pods -A --field-selector spec.nodeName="$NODE" -o wide
kubectl drain "$NODE" --ignore-daemonsets --delete-emptydir-data
Bei ernsthafter Kompromittierung ist Neuaufbau sicherer als Reparatur.
33.3. Runbook: Secret-Leak
- Secret identifizieren.
- betroffene Systeme und Berechtigungen erfassen.
- Secret sofort rotieren oder deaktivieren.
- Verwendungen finden.
- Workloads neu starten.
- Git-Historie, Artefakte und Logs prüfen.
- Audit auf Missbrauch prüfen.
- Prävention verbessern.
kubectl get secret -A | grep <name>
kubectl get pods -A -o yaml | grep -n "secretName: <name>"
kubectl rollout restart deployment -n <namespace> <deployment>
33.4. Runbook: Unerlaubtes cluster-admin Binding
kubectl describe clusterrolebinding cluster-admin
kubectl get clusterrolebinding -o yaml | grep -n -B5 -A20 "cluster-admin"
Vorgehen:
- Binding identifizieren.
- Änderungsquelle über Audit Logs prüfen.
- Binding entfernen, falls nicht genehmigt.
- betroffene Identität sperren oder rotieren.
- RBAC-Eskalationspfad schließen.
- Alerts verbessern.
33.5. Runbook: Admission Webhook ausgefallen
- Fehlermeldung prüfen.
- Webhook-Service und Endpoints prüfen.
- Zertifikate prüfen.
failurePolicybewerten.- kritische Änderungen einfrieren, wenn Policy-Schutz nicht aktiv ist.
- Webhook stabilisieren.
- nachträgliche Drift-Prüfung ausführen.
kubectl get validatingwebhookconfiguration,mutatingwebhookconfiguration
kubectl get pods,svc,endpoints -A | grep -i webhook
kubectl get events -A --sort-by=.lastTimestamp | grep -i webhook
33.6. Runbook: Verdächtiger Egress
- betroffene Pod-IP identifizieren.
- Pod, Namespace, Node und ServiceAccount zuordnen.
- DNS-Logs und Flow-Logs prüfen.
- Egress temporär blockieren.
- Image und Prozesse prüfen.
- Credentials rotieren, falls C2 möglich war.
- Egress-Policy verbessern.
kubectl get pods -A -o wide | grep <pod-ip>
kubectl describe pod -n <namespace> <pod>
kubectl get networkpolicy -n <namespace>
34. Security-Checklisten
34.1. Cluster-Baseline
- API-Zugriff ist nicht offen aus dem Internet erreichbar.
- Benutzer nutzen SSO/OIDC und MFA.
- Break-Glass ist getrennt, auditiert und getestet.
- RBAC verwendet keine unnötigen Wildcards.
cluster-administ stark begrenzt.nodes/proxyist streng kontrolliert.- Audit Logs sind aktiv und zentral gespeichert.
- Secrets Encryption at Rest ist aktiviert oder Provider-äquivalent umgesetzt.
- etcd-Backups sind verschlüsselt und Restore-getestet.
- CNI unterstützt NetworkPolicies.
- kritische Add-ons haben Monitoring und PDBs.
- Upgrade-Prozess und Version Skew sind dokumentiert.
34.2. Namespace-Baseline
- Namespace hat Owner-Labels.
- Pod Security Admission ist gesetzt.
- ResourceQuota ist gesetzt.
- LimitRange ist gesetzt.
- Default-Deny NetworkPolicy ist gesetzt.
- DNS-Egress ist explizit geregelt.
- RBAC ist namespaced und minimal.
- Secrets sind extern oder kontrolliert verwaltet.
- GitOps-Scope ist begrenzt.
34.3. Workload-Baseline
- eigener ServiceAccount.
automountServiceAccountToken: false, wenn API-Zugriff nicht nötig ist.runAsNonRoot: true.allowPrivilegeEscalation: false.capabilities.drop: [ALL].seccompProfile: RuntimeDefault.- kein
privileged: true. - kein
hostNetwork,hostPID,hostIPC. - kein
hostPath, außer dokumentierte Plattformausnahme. - read-only root FS, sofern möglich.
- Image ist versioniert oder per Digest gepinnt.
- Ressourcenrequests und Memory-Limits sind gesetzt.
- Probes sind sinnvoll gesetzt.
- Logs enthalten keine Secrets.
34.4. Supply-Chain-Baseline
- Branch Protection aktiv.
- CI-Runner isoliert.
- Secret-Scanning aktiv.
- Dependency-Scanning aktiv.
- Image-Scanning aktiv.
- SBOM erzeugt.
- Signatur oder Provenance für kritische Images.
- Registry-RBAC minimal.
- keine
latest-Tags in Produktion. - Admission-Gate für kritische Mindestanforderungen.
34.5. Cloud-Baseline
- API-Endpunkt privat oder eingeschränkt.
- Workload Identity statt statischer Cloud Keys.
- Node-Rollen minimal.
- Cloud-Audit-Logs aktiv.
- KMS für Secrets/Storage genutzt.
- Security-Groups/Firewalls minimal.
- Container Registry Scans aktiv.
- Provider Security Services bewertet.
- Wartungsfenster und automatische Updates dokumentiert.
35. Workshop-Labs
35.1. Lab 1: RBAC Least Privilege
Ziel: Du baust eine Rolle, die Pods lesen, aber keine Secrets lesen darf.
Schritte:
- Namespace erstellen.
- ServiceAccount erstellen.
- Role und RoleBinding erstellen.
kubectl auth can-itesten.- Zugriff auf Secrets bewusst verweigern.
Abnahme:
kubectl auth can-i get pods -n lab-rbac --as system:serviceaccount:lab-rbac:reader
kubectl auth can-i get secrets -n lab-rbac --as system:serviceaccount:lab-rbac:reader
35.2. Lab 2: Pod Security Admission
Ziel: Du blockierst einen privilegierten Pod.
Schritte:
- Namespace mit
warn=restrictederstellen. - Privileged Pod anwenden und Warnung beobachten.
- Namespace auf
enforce=restrictedsetzen. - Privileged Pod erneut anwenden.
- gehärteten Pod deployen.
35.3. Lab 3: NetworkPolicy Default Deny
Ziel: Du isolierst einen Namespace und erlaubst nur definierte Kommunikation.
Schritte:
- App und Test-Pod deployen.
- Verbindung vor Policy testen.
- Default-Deny anwenden.
- DNS-Egress erlauben.
- gezielten Service-Zugriff erlauben.
35.4. Lab 4: Secrets sicher verwenden
Ziel: Du vergleichst Secret als Env Var, Volume und externes Secret-Modell.
Schritte:
- Demo-Secret erstellen.
- Secret als Volume mounten.
- Rollout bei Secret-Änderung testen.
- RBAC auf Secrets prüfen.
- Secret-Scan gegen Repository laufen lassen.
35.5. Lab 5: Image Security
Ziel: Du scannst, signierst und verifizierst ein Image.
Schritte:
- Image bauen.
- Trivy Scan ausführen.
- SBOM erzeugen.
- Cosign signieren.
- Admission-Policy diskutieren.
35.6. Lab 6: Audit und Incident Response
Ziel: Du simulierst einen verdächtigen API-Zugriff und sammelst Spuren.
Schritte:
- ServiceAccount mit falscher Rolle erstellen.
- Zugriff testen.
- Audit-/Events prüfen.
- Rolle korrigieren.
- Post-Incident-Review schreiben.
35.7. Lab 7: Cloud Workload Identity
Ziel: Du ersetzt statische Cloud-Secrets durch Workload Identity.
Varianten:
- EKS Pod Identity oder IRSA,
- AKS Workload Identity,
- GKE Workload Identity Federation.
Abnahme:
- Pod kann genau eine erlaubte Cloud-Ressource erreichen.
- Node-Rolle hat keine breiten App-Rechte.
- Kein statischer Cloud-Key liegt als Kubernetes Secret vor.
36. Häufige Anti-Patterns
| Anti-Pattern | Problem | Besser |
|---|---|---|
cluster-admin für Apps |
vollständige Clusterübernahme bei Pod-Kompromittierung | namespaced RBAC |
| Default-ServiceAccount | keine Identitätsklarheit | eigener ServiceAccount je Workload |
| automatische Token-Mounts | unnötige API-Credentials | automountServiceAccountToken: false |
| keine NetworkPolicies | lateral movement leicht | Default-Deny + Allowlist |
privileged: true |
Container-Isolation stark reduziert | nur Systemausnahmen |
hostPath / |
Host-Dateisystem zugänglich | vermeiden, isolierte Volumes |
| Docker Socket Mount | Host-Übernahme möglich | isolierte Build-Umgebung |
| Secrets in Git | dauerhafte Kompromittierung | SOPS, External Secrets, Vault |
latest-Tag |
nicht reproduzierbar | versionierter Tag oder Digest |
| keine Audit Logs | keine Nachvollziehbarkeit | API-Audit und SIEM |
| Webhook ohne Monitoring | Admission-Ausfälle unbemerkt | Metriken, Alerts, PDB |
| offene Kubernetes API | direkter Angriffspfad | private API, VPN, IP-Allowlist |
| Node SSH für Alltag | Umgehung von Kubernetes-Kontrollen | deklarative Wartung, drain/replace |
| Debug-Container in Prod ohne Prozess | unkontrollierter Zugriff | zeitlich begrenztes Break-Glass |
37. Beispiel-Repository-Struktur
kubernetes-security/
├── README.md
├── clusters/
│ ├── dev/
│ ├── stage/
│ └── prod/
├── namespaces/
│ ├── base/
│ │ ├── namespace.yaml
│ │ ├── resourcequota.yaml
│ │ ├── limitrange.yaml
│ │ └── networkpolicy-default-deny.yaml
│ └── overlays/
├── policies/
│ ├── pod-security/
│ ├── kyverno/
│ ├── gatekeeper/
│ └── validating-admission-policy/
├── rbac/
│ ├── roles/
│ ├── rolebindings/
│ └── reviews/
├── workloads/
│ ├── secure-deployment.yaml
│ └── examples/
├── secrets/
│ ├── external-secrets/
│ ├── sops/
│ └── sealed-secrets/
├── observability/
│ ├── audit-policy.yaml
│ ├── prometheus-rules.yaml
│ └── falco-rules.yaml
├── scripts/
│ ├── audit-export.sh
│ ├── rbac-review.sh
│ ├── policy-test.sh
│ └── incident-collect.sh
└── docs/
├── threat-model.md
├── exceptions.md
├── runbooks.md
└── audit-evidence.md
37.1. Ausnahmeprozess als Datei
apiVersion: security.example.com/v1
kind: SecurityException
metadata:
name: allow-privileged-csi-node
spec:
owner: platform-storage
namespace: storage-system
control: pod-security-restricted
reason: CSI Node Plugin benötigt Host-Zugriff für Volume-Mounts.
compensatingControls:
- eigener Namespace
- nur Plattformteam hat Schreibrechte
- Image signiert
- Runtime Detection aktiv
- NetworkPolicy aktiv
expires: "2026-12-31"
reviewCycle: quarterly
38. Kommandoreferenz Security
38.1. Clusterüberblick
kubectl version
kubectl cluster-info
kubectl get nodes -o wide
kubectl get ns --show-labels
kubectl get pods -A -o wide
38.2. RBAC
kubectl auth can-i --list
kubectl auth can-i get secrets -A
kubectl auth can-i get pods --as system:serviceaccount:demo:app -n demo
kubectl get role,rolebinding -A
kubectl get clusterrole,clusterrolebinding
kubectl describe clusterrolebinding cluster-admin
38.3. ServiceAccounts
kubectl get serviceaccounts -A
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{.spec.serviceAccountName}{"\t"}{.spec.automountServiceAccountToken}{"\n"}{end}'
38.4. Pod Security
kubectl get ns --show-labels | grep pod-security
kubectl label ns demo pod-security.kubernetes.io/warn=restricted --overwrite
kubectl label ns demo pod-security.kubernetes.io/audit=restricted --overwrite
kubectl label ns demo pod-security.kubernetes.io/enforce=restricted --overwrite
38.5. SecurityContext prüfen
kubectl get pods -A -o json | jq -r '
.items[] as $pod |
$pod.spec.containers[]? |
[$pod.metadata.namespace, $pod.metadata.name, .name,
(.securityContext.privileged // false),
(.securityContext.allowPrivilegeEscalation // "unset"),
(.securityContext.readOnlyRootFilesystem // "unset")]
| @tsv'
38.6. NetworkPolicies
kubectl get networkpolicy -A
kubectl describe networkpolicy -n <namespace> <policy>
kubectl run netshoot -n <namespace> --rm -it --restart=Never --image=nicolaka/netshoot -- bash
38.7. Secrets
kubectl get secrets -A
kubectl auth can-i get secrets -n <namespace> --as <identity>
kubectl get pods -A -o yaml | grep -n "secretName"
38.8. Admission
kubectl get validatingwebhookconfiguration,mutatingwebhookconfiguration
kubectl get validatingadmissionpolicy,validatingadmissionpolicybinding
kubectl get mutatingadmissionpolicy,mutatingadmissionpolicybinding
kubectl get events -A --sort-by=.lastTimestamp | grep -i admission
38.9. Images
kubectl get pods -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.metadata.name}{"\t"}{range .spec.containers[*]}{.image}{","}{end}{"\n"}{end}'
trivy image <image>
cosign verify <image>
syft <image> -o spdx-json
38.10. Node und Runtime
kubectl get nodes -o wide
kubectl describe node <node>
kubectl top nodes
sudo journalctl -u kubelet --no-pager | tail -100
crictl info
crictl ps
38.11. Events und Logs
kubectl get events -A --sort-by=.lastTimestamp | tail -100
kubectl logs -n <namespace> <pod> --all-containers
kubectl logs -n <namespace> <pod> --all-containers --previous
38.12. Cloud
# AWS EKS
aws eks describe-cluster --name <cluster>
aws eks list-access-entries --cluster-name <cluster>
aws eks list-pod-identity-associations --cluster-name <cluster>
# Azure AKS
az aks show -g <resource-group> -n <cluster>
az aks get-credentials -g <resource-group> -n <cluster>
# Google GKE
gcloud container clusters describe <cluster> --region <region>
gcloud container clusters get-credentials <cluster> --region <region>
39. Entscheidungsfragen für Architektur-Reviews
39.1. Cluster und Umgebung
- Welche Umgebung ist betroffen: lokal, VM, Bare Metal, Cloud, Managed, OpenShift?
- Wer betreibt Control Plane, Nodes, Netzwerk und Storage?
- Welche Datenklassifikation hat der Workload?
- Gibt es Mandantentrennung oder nur Team-Trennung?
- Welche Compliance-Anforderungen gelten?
39.2. Identität und Zugriff
- Wie melden sich Menschen an?
- Gibt es MFA?
- Welche Gruppen bekommen welche Rollen?
- Wie funktioniert Break Glass?
- Gibt es statische kubeconfigs?
- Welche ServiceAccounts existieren?
- Welche Workloads brauchen API-Zugriff?
39.3. Workload Security
- Läuft der Container als Nicht-Root?
- Sind Capabilities gedroppt?
- Ist Privilege Escalation deaktiviert?
- Gibt es Host-Namespace- oder hostPath-Nutzung?
- Sind Ressourcenlimits und Requests gesetzt?
- Ist das Image geprüft, signiert oder per Digest gepinnt?
39.4. Netzwerk
- Gibt es Default-Deny?
- Ist DNS explizit erlaubt?
- Welche Ingress-Pfade sind öffentlich?
- Wie wird Egress kontrolliert?
- Gibt es Service-to-Service-mTLS?
- Sind Admin-Endpunkte intern?
39.5. Secrets und Daten
- Wo liegen Secrets autoritativ?
- Sind Secrets in Git ausgeschlossen?
- Ist Encryption at Rest aktiv?
- Wie funktioniert Rotation?
- Wer darf Secrets lesen?
- Sind Backups verschlüsselt?
39.6. Betrieb und Detection
- Sind Audit Logs aktiv?
- Werden Runtime Events erfasst?
- Welche Alerts existieren?
- Gibt es Runbooks?
- Wurde Restore getestet?
- Wie schnell werden kritische CVEs gepatcht?
40. Quellen und weiterführende Referenzen
40.1. Kubernetes Primärdokumentation
- Kubernetes Security Overview:
https://kubernetes.io/docs/concepts/security/ - Kubernetes Security Checklist:
https://kubernetes.io/docs/concepts/security/security-checklist/ - Controlling Access to the Kubernetes API:
https://kubernetes.io/docs/concepts/security/controlling-access/ - RBAC:
https://kubernetes.io/docs/reference/access-authn-authz/rbac/ - RBAC Good Practices:
https://kubernetes.io/docs/concepts/security/rbac-good-practices/ - ServiceAccounts:
https://kubernetes.io/docs/concepts/security/service-accounts/ - Managing ServiceAccounts:
https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/ - Pod Security Standards:
https://kubernetes.io/docs/concepts/security/pod-security-standards/ - Pod Security Admission:
https://kubernetes.io/docs/concepts/security/pod-security-admission/ - SecurityContext:
https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ - NetworkPolicies:
https://kubernetes.io/docs/concepts/services-networking/network-policies/ - Good Practices for Secrets:
https://kubernetes.io/docs/concepts/security/secrets-good-practices/ - Encrypting Confidential Data at Rest:
https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/ - Auditing:
https://kubernetes.io/docs/tasks/debug/debug-cluster/audit/ - Admission Controllers:
https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/ - ValidatingAdmissionPolicy:
https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/ - MutatingAdmissionPolicy:
https://kubernetes.io/docs/reference/access-authn-authz/mutating-admission-policy/ - Kubelet Authentication and Authorization:
https://kubernetes.io/docs/reference/access-authn-authz/kubelet-authn-authz/
40.2. Benchmarks und Hardening
- CIS Kubernetes Benchmark:
https://www.cisecurity.org/benchmark/kubernetes - NSA/CISA Kubernetes Hardening Guidance:
https://www.cisa.gov/news-events/alerts/2022/03/15/updated-kubernetes-hardening-guide - kube-bench:
https://github.com/aquasecurity/kube-bench - Kubescape:
https://kubescape.io/
40.3. Policy, Supply Chain und Runtime
- Kyverno:
https://kyverno.io/ - OPA Gatekeeper:
https://open-policy-agent.github.io/gatekeeper/ - Sigstore Cosign:
https://docs.sigstore.dev/cosign/ - Sigstore Policy Controller:
https://docs.sigstore.dev/policy-controller/overview/ - Falco:
https://falco.org/docs/ - Cilium Tetragon:
https://tetragon.io/ - Trivy:
https://trivy.dev/ - Syft:
https://github.com/anchore/syft - Grype:
https://github.com/anchore/grype
40.4. Cloud-Provider
- AWS EKS Best Practices Guide:
https://docs.aws.amazon.com/eks/latest/best-practices/ - AKS Security Concepts:
https://learn.microsoft.com/en-us/azure/aks/concepts-security - GKE Hardening Guide:
https://cloud.google.com/kubernetes-engine/docs/how-to/hardening-your-cluster - GKE Autopilot Security:
https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-security - OpenShift Security Context Constraints:
https://docs.redhat.com/
Anhang A: Minimal sichere Workload-Vorlage
apiVersion: apps/v1
kind: Deployment
metadata:
name: secure-app
namespace: app-prod
labels:
app.kubernetes.io/name: secure-app
app.kubernetes.io/managed-by: gitops
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: secure-app
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
template:
metadata:
labels:
app.kubernetes.io/name: secure-app
spec:
serviceAccountName: secure-app
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: registry.example.com/team/secure-app@sha256:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ports:
- name: http
containerPort: 8080
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 10001
runAsGroup: 10001
capabilities:
drop: ["ALL"]
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
readinessProbe:
httpGet:
path: /readyz
port: http
livenessProbe:
httpGet:
path: /healthz
port: http
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir: {}
Anhang B: Security-Ausnahmen bewerten
| Frage | Bewertung |
|---|---|
| Welche Policy wird verletzt? | genaue Kontrolle nennen |
| Warum ist die Ausnahme nötig? | technischer Grund, kein Komfortgrund |
| Welche Alternative wurde geprüft? | zum Beispiel Non-root, andere Ports, Sidecar vermeiden |
| Welcher Scope ist betroffen? | Namespace, App, Node Pool |
| Wie lange gilt die Ausnahme? | Ablaufdatum |
| Welche Kompensationskontrollen existieren? | NetworkPolicy, Runtime Detection, separate Nodes |
| Wer genehmigt? | Plattform + Security + Owner |
| Wie wird rückgebaut? | konkreter Plan |
Anhang C: Security-Review-Protokoll
# Kubernetes Security Review
## Metadaten
- Cluster:
- Umgebung:
- Namespace:
- Anwendung:
- Owner:
- Datum:
- Reviewer:
## Ergebnis
- Risikostufe:
- Freigabe:
- offene Punkte:
## Identität und RBAC
- Benutzerzugriff geprüft:
- ServiceAccount geprüft:
- Secrets-Zugriff geprüft:
- ClusterRoleBindings geprüft:
## Workload Security
- Pod Security Admission:
- SecurityContext:
- Privileged/hostPath/hostNetwork:
- Ressourcen:
## Netzwerk
- Default-Deny:
- Ingress:
- Egress:
- DNS:
## Secrets und Daten
- Secret-Quelle:
- Encryption:
- Rotation:
- Backup:
## Supply Chain
- Image:
- Scan:
- SBOM:
- Signatur:
## Observability
- Logs:
- Audit:
- Alerts:
- Runtime Detection:
## Ausnahmen
| Ausnahme | Grund | Ablaufdatum | Kompensation |
|---|---|---|---|
## Maßnahmen
| Maßnahme | Owner | Fällig | Status |
|---|---|---|---|
Anhang D: Security Mindset für Workshops
Im Workshop gilt:
- Du verwendest keine echten Secrets.
- Du verwendest keine echten Kundendaten.
- Du trennst Lab-Kontexte von produktiven Kontexten.
- Du prüfst vor jedem
kubectl apply, in welchem Kontext du bist. - Du verwendest Dry-Run, Diff und Review.
- Du dokumentierst jede Ausnahme.
- Du baust Rückbau und Cleanup ein.
Kontext-Schutz:
kubectl config current-context
kubectl config get-contexts
Optionaler Prompt-Schutz:
export KUBE_PS1_ENABLED=on
Oder verwende Tools wie kubectx, kubens und Shell-Prompt-Integrationen, damit du Cluster und Namespace immer sichtbar hast.