Reagowanie na ucieczkę procesu z kontenera na hosta oraz kompromitację klastra Kubernetes: przejęty node, nadmierne uprawnienia RBAC, privileged pod, ClusterRoleBinding do cluster-admin. Playbook czysto defensywny — bez instrukcji eksploatacji, wyłącznie sygnały, izolacja, dowody i odbudowa zaufanego stanu. Priorytet typowy P1, podbijany do P0 przy potwierdzonym dostępie do hosta lub eskalacji do cluster-admin.
Gdy kontener działa w trybie privileged, ma zamontowany socket CRI/Docker, hostPID/hostNetwork lub nadmierne RBAC, granica izolacji przestaje być gwarantowana. Zasada robocza tego playbooka: dopóki nie udowodnisz, że proces pozostał w namespace kontenera, zakładaj najgorszy scenariusz — dostęp do hosta.
Kubernetes izoluje workloady przez namespace'y jądra, cgroups i RBAC — nie przez twardą granicę maszyny wirtualnej. Błąd konfiguracji (privileged pod, hostPath na /, ClusterRoleBinding do cluster-admin) potrafi zredukować tę izolację do zera. Skutki w środowisku bankowym/fintech:
kube-apiserver (P0 gdy potwierdzone),Nieoczekiwany pod w namespace systemowym lub DaemonSet uruchomiony bez zmiany w IaC/GitOps.
privileged: true, hostPID, hostNetwork, hostIPC, allowPrivilegeEscalation: true, runAsUser: 0 na workloadzie, który tego nie wymaga.
/var/run/docker.sock, /run/containerd/containerd.sock, /proc, /sys, /, /etc, /root, /var/lib/kubelet zamontowane do kontenera aplikacyjnego.
Nowy binding do cluster-admin lub roli z * na verbs/resources, zwłaszcza przypięty do ServiceAccount aplikacji.
Proces poza oczekiwanymi kontenerami (ps auxf), nieznane binarki, nietypowe połączenia wychodzące (ss -tulpn), modyfikacja systemd/cron/SSH.
Wpisy create clusterrolebinding, create pod z privileged, patch daemonset, częste exec do kontenerów spoza standardowego dostępu operacyjnego.
Reguła Falco/Tetragon/eBPF: shell w kontenerze, zapis do /proc//sys//etc, dostęp do socketu CRI, proces z host namespace.
Token ServiceAccount używany z nieoczekiwanego IP/pod-a lub przypięty do wielu namespace'ów bez uzasadnienia.
privileged, hostPath) to ekspozycja konfiguracyjna — dopiero dowód aktywności na nodzie (nieznany proces, modyfikacja systemu, ruch wychodzący) podnosi sprawę do potwierdzonego escape. Brak dowodu na nodzie nie oznacza braku ryzyka — oznacza konieczność dalszej analizy w krokach 4-5.| Rola | Odpowiedzialność |
|---|---|
| IC (Incident Commander) | decyzje, priorytet, komunikacja |
| Platform/K8s Engineer | containment na poziomie klastra i noda |
| SecOps | korelacja audit log, IoC, oś czasu |
| Forensics | zebranie artefaktów przed rebuildem noda |
| App Owner | ocena wpływu na workload i dane |
| Legal/DPO | obowiązki regulacyjne |
| SEV | Warunek |
|---|---|
| SEV1 | potwierdzony dostęp do hosta lub eskalacja do cluster-admin |
| SEV2 | privileged pod/hostPath aktywny, brak jeszcze dowodu aktywności na nodzie |
| SEV3 | nadmierne RBAC wykryte, workload nieaktywny lub już wygaszony |
| SEV4 | ryzykowna konfiguracja wykryta przed wdrożeniem (policy-as-code, CI gate) |
kubectl scale deploy <name> -n <ns> --replicas=0 lub, gdy wymagana szybka reakcja, kubectl delete pod <pod> -n <ns> --grace-period=0 --force. Jeśli planowana forensyka — najpierw snapshot/artefakty (krok 4), dopiero potem kasowanie.kubectl cordon <node> + kubectl drain <node> --ignore-daemonsets --delete-emptydir-data. Przy wysokim podejrzeniu escape: kubectl taint nodes <node> quarantine=true:NoSchedule i odcięcie egress noda na poziomie sieci poza wymaganymi endpointami IR. Zablokuj powiązane tokeny ServiceAccount (kubectl delete secret/serviceaccount).kubectl get all/secrets/cm/rbac -A -o yaml, kubectl get pods -A -o json, kubectl get events -A --sort-by=.lastTimestamp. Z poda: logi i describe. Z noda (jeśli dostępny bez ingerencji w ślad): journalctl, ps auxf, ss -tulpn, crictl ps -a/inspect. Hash + znacznik czasu → Evidence Layer.securityContext poda (privileged, allowPrivilegeEscalation, runAsUser: 0, host*), zamontowane hostPath, RBAC (ClusterRoleBinding do cluster-admin, verbs/resources *, ServiceAccount na wielu namespace'ach), audit log (create clusterrolebinding, create pod privileged, patch daemonset, exec). Ustal, które z tych warunków były spełnione i w jakiej kolejności.kubectl delete node <node> i reprovision przez IaC/autoscaler z czystego obrazu. Zweryfikuj digesty obrazów (kubectl get pods -A -o jsonpath='{..image}'), przywróć minimalne RBAC, włącz polityki admission, monitoruj 24–72h (nowe pody, bindingi, exec, egress, workloady privileged).| Pole | Ryzyko |
|---|---|
privileged: true | kontener działa z pełnymi uprawnieniami jądra hosta |
allowPrivilegeEscalation: true | proces może uzyskać więcej uprawnień niż proces nadrzędny |
runAsUser: 0 | proces działa jako root wewnątrz kontenera |
hostPID / hostNetwork / hostIPC | współdzielenie przestrzeni nazw hosta — widoczność/dostęp poza kontenerem |
hostPath: /, /proc, /sys, /etc, /var/lib/kubelet | bezpośredni zapis/odczyt systemu plików hosta |
socket docker.sock / containerd.sock | pełna kontrola nad runtime kontenerów na nodzie |
Następca deprecjonowanego Pod Security Policy. Etykiety namespace: enforce=restricted, audit=restricted, warn=restricted — blokują privileged, hostPID/Network/IPC, hostPath dla większości workloadów.
Policy-as-code na poziomie admission controller — reguły odrzucające pody z Principal: "*", brakiem runAsNonRoot, niedozwolonym rejestrem obrazów lub obrazem bez podpisu. Egzekwowane przed wdrożeniem, nie po fakcie.
Profil RuntimeDefault (lub własny, minimalny) ograniczający dostępne wywołania systemowe kontenera — zawęża powierzchnię ataku na jądro hosta niezależnie od pozostałych ustawień.
runAsNonRoot: true, allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, capabilities.drop: [ALL] jako domyślny szablon dla nowych workloadów.
Domyślna blokada ingress/egress na poziomie namespace, z jawnym dopuszczeniem tylko wymaganych połączeń.
Regularny audyt kubectl auth can-i --list --as=system:serviceaccount:<ns>:<sa>. Zakaz przypisywania cluster-admin do ServiceAccount aplikacji.
Falco, Tetragon, auditd, telemetria eBPF, audit log kube-apiserver — reguły na shell w kontenerze, zapis do /proc//sys//etc, dostęp do socketu CRI, tworzenie privileged pod lub ClusterRoleBinding.
Weryfikacja digestów obrazów, skan podatności przed wdrożeniem, zakaz obrazów bez podpisu/atestu pochodzenia.
| Warunek | Flaga | Obowiązek |
|---|---|---|
| Dotknięty workload przetwarzał dane osobowe | GDPR_PERSONAL_DATA | Ocena naruszenia — patrz zasada niżej |
| Potwierdzony dostęp do danych osobowych z poziomu hosta/klastra | GDPR_BREACH | RODO art. 33 — zgłoszenie do PUODO w 72h; art. 34 — zawiadomienie osób przy wysokim ryzyku |
| Podmiot to usługa kluczowa/ważna | NIS2_RELEVANT | Wczesne ostrzeżenie do CSIRT w 24h, zgłoszenie 72h, raport końcowy |
| Sekret/credential dający dostęp do systemu produkcyjnego był w zasięgu | SECRET_EXPOSURE | Natychmiastowa rotacja + wewnętrzna eskalacja bezpieczeństwa |
kube-apiserver.Formularz Intake uruchamiający ten playbook. → Incident Intake
Reguły kierujące zdarzenie do Playbooka O. → Classification Engine
Pokrewny wektor — błędna konfiguracja chmury/K8s API. → Playbook M
Sprzężenie, gdy wektorem wejścia był skompromitowany obraz/zależność. → Playbook F