LIVE: New phishing campaigns targeting mobile users —View latest threats →

Back to Tutorials
Zaawansowany 17 min czytania

Docker i Kubernetes: poradnik bezpieczeństwa kontenerów

Kontenery zmieniły sposób wdrażania oprogramowania — ale wiele zespołów uruchamia je z uprawnieniami roota, przestarzałymi obrazami i ujawnionymi sekretami. Oto pełny poradnik wzmacniania zabezpieczeń.

25 lutego 2026

Błędne przekonanie o bezpieczeństwie kontenerów

Częstym błędnym przekonaniem jest to, że kontenery zapewniają silną izolację podobną do maszyn wirtualnych. Tak nie jest. Kontenery współdzielą jądro hosta — luka umożliwiająca ucieczkę z kontenera i wykonanie kodu w jądrze hosta daje dostęp do każdego kontenera na tym hoście oraz do samego hosta. Bezpieczeństwo kontenerów polega na ograniczaniu zasięgu szkód po przejęciu kontenera, a nie na założeniu, że granica jest nie do przebicia.

Powierzchnia ataku obejmuje obraz kontenera, konfigurację uruchomieniową, platformę orkiestracji, sieć i warstwę zarządzania sekretami. Wzmacnianie zabezpieczeń musi objąć je wszystkie.

Wzmacnianie obrazów Docker

Używaj minimalnych obrazów bazowych

Każdy pakiet w obrazie bazowym to potencjalna podatność. Wybieraj obrazy distroless (obrazy Google bez powłoki, menedżera pakietów i narzędzi systemowych) lub Alpine Linux (musl libc, apk, ok. 5 MB):

# Instead of ubuntu:22.04
FROM gcr.io/distroless/java21-debian12

Do obrazów distroless nie da się wejść interaktywną powłoką — to znacznie ogranicza możliwości atakującego, jeśli kontener zostanie przejęty.

Budowanie wieloetapowe

Zależności do budowania (kompilatory, narzędzia buildowe, frameworki testowe) nigdy nie powinny trafiać do obrazu produkcyjnego:

FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o server .

FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]

Obraz końcowy zawiera tylko skompilowany plik binarny i jego zależności uruchomieniowe.

Nigdy nie uruchamiaj jako root

Domyślnie procesy w kontenerach działają jako root (UID 0). Jeśli dojdzie do ucieczki z kontenera, atakujący ma uprawnienia roota na hoście. Zawsze twórz użytkownika bez uprawnień roota:

RUN useradd -u 1001 -r appuser
USER appuser

Połącz to z systemem plików tylko do odczytu (--read-only) i --tmpfs /tmp dla miejsc wymagających zapisu.

Skanuj obrazy pod kątem podatności

Włącz skanowanie obrazów do potoku CI/CD:

# Trivy — fast, comprehensive vulnerability scanner
trivy image myapp:latest

# Grype — alternative with SBOM support
grype myapp:latest

Trivy to szybki, wszechstronny skaner podatności, a Grype — alternatywa z obsługą SBOM. Przerywaj build, jeśli wykryto podatności o wysokim lub krytycznym poziomie. Przebudowuj i aktualizuj obrazy bazowe regularnie — nie tylko przy zmianie kodu aplikacji.

Bezpieczeństwo środowiska uruchomieniowego Docker

Odbieraj uprawnienia (capabilities)

Mechanizm capabilities w Linuksie dzieli uprawnienia roota typu „wszystko albo nic” na osobne jednostki. Odbierz wszystkie i przywróć tylko te, których aplikacja potrzebuje:

docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp

Seccomp i AppArmor

Domyślny profil seccomp w Dockerze blokuje ok. 44 niebezpieczne wywołania systemowe. Stosuj go jawnie i rozważ własny profil dla wrażliwych obciążeń. Profile AppArmor lub SELinux dodają obowiązkową kontrolę dostępu ponad jądrem:

docker run --security-opt seccomp=profile.json myapp
docker run --security-opt apparmor=docker-default myapp

Nigdy nie używaj --privileged

Flaga --privileged daje kontenerowi niemal pełny dostęp do hosta, wyłączając całą izolację bezpieczeństwa. Bywa wymagana w specyficznych przypadkach (np. Docker-in-Docker), ale na produkcji należy jej całkowicie unikać, a podczas przeglądów bezpieczeństwa traktować jako natychmiastowy sygnał alarmowy.

Wzmacnianie bezpieczeństwa Kubernetes

Pod Security Standards

Kubernetes egzekwuje zasady bezpieczeństwa przez Pod Security Standards (zastępujące wycofane PodSecurityPolicy):

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest

Profil restricted wymusza: brak kontenerów uprzywilejowanych, brak użytkownika root, brak eskalacji uprawnień, wymagany profil seccomp i odebranie wszystkich capabilities.

RBAC: najmniejsze uprawnienia dla kont usług

Każdy pod działa z kontem usługi (service account). Domyślnie to konto ma dostęp do API Kubernetes. Stosuj zasadę najmniejszych uprawnień:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-role
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get"]

Audytuj poleceniem kubectl auth can-i --list --as=system:serviceaccount:default:myapp. Wyłącz automatyczne montowanie tokenów kont usług, gdy nie są potrzebne: automountServiceAccountToken: false.

Zarządzanie sekretami

Sekrety Kubernetes są domyślnie tylko zakodowane w Base64, a nie zaszyfrowane. Stosuj:

  • Szyfrowanie w spoczynku: włącz EncryptionConfiguration w serwerze API, aby szyfrować sekrety w etcd
  • Zewnętrzne menedżery sekretów: AWS Secrets Manager, HashiCorp Vault lub GCP Secret Manager przez External Secrets Operator
  • Nigdy nie umieszczaj sekretów w ConfigMapach, zmiennych środowiskowych w specyfikacjach Deploymentów (widocznych przez kubectl describe) ani w obrazach kontenerów

Polityki sieciowe

Domyślnie wszystkie pody w klastrze Kubernetes mogą się ze sobą komunikować. Wdróż NetworkPolicy, aby wymusić mikrosegmentację:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {}
  policyTypes: [Ingress]

Następnie dodaj jawne reguły zezwalające tylko na niezbędne ścieżki komunikacji. Używaj wtyczki CNI, która egzekwuje NetworkPolicy (Calico, Cilium, Weave).

Ciągła kontrola stanu bezpieczeństwa

  • Używaj Falco (narzędzia CNCF do bezpieczeństwa w czasie działania), aby wykrywać podejrzane zachowania: nieoczekiwane uruchomienia powłoki, połączenia wychodzące do nowych adresów IP, próby eskalacji uprawnień
  • Skanuj konfigurację klastra za pomocą kube-bench (CIS Kubernetes Benchmark) i operatora Trivy
  • Włącz logowanie audytowe w serwerze API Kubernetes i przesyłaj logi do SIEM
  • Regularnie odświeżaj skróty (digesty) obrazów i automatyzuj aktualizacje zależności za pomocą Renovate lub Dependabot
#Docker#Kubernetes#container security#DevSecOps#cloud