Konteyner Güvenliği: Docker ve Kubernetes Ortamlarında Sıkılaştırma (Hardening)
Konteynerler hız kazandırır ama varsayılan ayarlarla bırakıldığında saldırgana da hız kazandırır. İmajdan çalışma zamanına kadar dört katmanda sıkılaştırmayı ve bunun için kullanılan açık kaynak araçları karşılaştırıyoruz.
Konteynerler, uygulamayı bağımlılıklarıyla birlikte paketleyip her ortamda aynı şekilde çalıştırmayı sağladı. Kubernetes ise bu konteynerleri ölçekte yönetmenin fiili standardı hâline geldi. Ancak hız ve esneklik, varsayılan ayarlarla bırakıldığında güvenlik borcu da biriktirir: root olarak çalışan konteynerler, yüzlerce bilinen açık içeren temel imajlar, birbirleriyle serbestçe konuşan pod'lar.
Konteyner güvenliğini dört katmanda düşünmek işi netleştirir: imaj, yapılandırma, küme ve çalışma zamanı.
Katman 1: İmaj güvenliği
Minimal temel imaj kullanın
Bir imajdaki her paket, potansiyel bir açık demektir. Tam bir işletim sistemi dağıtımı yerine alpine, distroless veya "slim" varyantlarını tercih edin. Çok aşamalı (multi-stage) derleme ile derleme araçlarını son imaja taşımayın.
# Çok aşamalı derleme: derleme araçları son imajda yok
FROM golang:1.23 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app ./cmd/api
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]
İmajları tarayın
İmaj taraması, imajdaki paketleri bilinen açık veritabanlarıyla karşılaştırır. Bunu hem CI hattında (derleme anında) hem de kayıt deposunda (sonradan yayımlanan açıklar için) düzenli yapın.
# Kritik veya yüksek açık varsa CI'yı durdur
trivy image --severity CRITICAL,HIGH --exit-code 1 sirket/api:1.4.2
İmajları imzalayın
Sigstore cosign ile imajları imzalayıp kümeye yalnızca imzalı imajların girmesine izin vermek, tedarik zinciri saldırılarına karşı güçlü bir önlemdir.
Katman 2: Konteyner yapılandırması
- Root olarak çalıştırmayın:
USERdirektifi verunAsNonRoot: truekullanın. - Salt okunur dosya sistemi: Uygulamanın yazması gereken yerler için ayrı birimler bağlayın.
- Yetenekleri (capabilities) düşürün: Varsayılan Linux yeteneklerinin tümünü kaldırıp yalnızca gerekeni ekleyin.
- Ayrıcalık yükseltmeyi kapatın:
allowPrivilegeEscalation: false. privileged: truekullanmayın: Ayrıcalıklı bir konteyner, pratikte ana makineye root erişimi demektir.- Kaynak sınırları koyun: CPU ve bellek limitleri, bir konteynerin tüm düğümü tüketmesini engeller.
apiVersion: v1
kind: Pod
metadata:
name: api
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: sirket/api:1.4.2@sha256:...
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
resources:
limits: { cpu: "500m", memory: "256Mi" }
Katman 3: Küme güvenliği
Pod Security Standards
Kubernetes'in yerleşik Pod Security Admission denetleyicisi, ad alanı (namespace) düzeyinde üç profil sunar: privileged, baseline ve restricted. Uygulama ad alanları için restricted hedeflenmelidir.
kubectl label namespace uretim \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/warn=restricted
RBAC ile en az yetki
cluster-admin rolünü yalnızca gerçekten gerekenlere verin. Servis hesaplarına yalnızca ihtiyaç duydukları kaynaklarda, ihtiyaç duydukları eylemleri tanıyın; API erişimi gerekmeyen pod'larda automountServiceAccountToken: false kullanın.
Ağ politikaları
Varsayılan olarak Kubernetes'te her pod her pod ile konuşabilir. "Varsayılan olarak reddet" politikası uygulayıp yalnızca gerekli trafiğe izin verin; böylece ele geçirilen bir pod'dan yanal hareket zorlaşır.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: varsayilan-reddet
namespace: uretim
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
Sırlar (secrets)
Kubernetes Secret nesneleri varsayılan olarak yalnızca base64 kodludur, şifreli değildir. etcd'de şifrelemeyi açın veya harici bir kasa (Vault, bulut sağlayıcı sır yöneticisi) ile External Secrets Operator kullanın.
Katman 4: Çalışma zamanı güvenliği
Önceki katmanlar saldırı yüzeyini küçültür; çalışma zamanı güvenliği ise bir şey ters gittiğinde onu fark etmenizi sağlar. Örneğin bir web konteynerinde aniden bir kabuk (shell) açılması veya /etc/shadow dosyasının okunması, neredeyse her zaman bir saldırı işaretidir.
Falco gibi araçlar, çekirdek düzeyindeki sistem çağrılarını izleyip bu tür davranışlar için kural tabanlı alarm üretir.
Açık kaynak araç karşılaştırması
| Araç | Katman | Ne yapar? |
|---|---|---|
| Trivy | İmaj, yapılandırma | İmaj, dosya sistemi, IaC ve Kubernetes manifest taraması; SBOM üretimi |
| Grype + Syft | İmaj | Syft ile SBOM çıkarma, Grype ile açık taraması |
| Cosign (Sigstore) | Tedarik zinciri | İmaj imzalama ve doğrulama |
| Kyverno / OPA Gatekeeper | Küme | Politika motoru: imzasız veya root çalışan imajları kümeye almaz |
| kube-bench | Küme | Kümeyi CIS Kubernetes Benchmark'a göre denetler |
| Kubescape | Küme, yapılandırma | NSA/CISA ve MITRE çerçevelerine göre risk taraması |
| Falco | Çalışma zamanı | Sistem çağrısı tabanlı anormal davranış tespiti |
Küçük bir ekipseniz: CI'ya Trivy ekleyin, uygulama ad alanlarında restricted Pod Security uygulayın ve varsayılan-reddet ağ politikası yazın. Bu üç adım, riskin büyük kısmını birkaç gün içinde azaltır.
DevSecOps akışında konteyner güvenliği
- Geliştirme: Dockerfile ve manifestler için IDE eklentileri ve pre-commit kontrolleri.
- CI: İmaj ve IaC taraması, SBOM üretimi, imzalama.
- Kabul (admission): Politika motoru ile uygunsuz iş yüklerinin reddedilmesi.
- Çalışma zamanı: Davranış izleme, merkezi log ve alarm.
- Sürekli: Kayıt deposundaki imajların periyodik yeniden taranması.
Sonuç
Konteyner güvenliği tek bir araçla çözülmez; her katman bir öncekinin kaçırdığını yakalar. İyi haber şu ki araçların büyük kısmı açık kaynak ve CI/CD akışına kolayca eklenebilir. Kubernetes ortamınızın güvenlik denetimi veya DevSecOps süreçlerinizin kurulması için yazılım ve siber güvenlik hizmetlerimizden yararlanabilirsiniz.
Sistemleriniz gerçekten güvende mi?
Ücretsiz ön görüşme için bugün yazın. İhtiyacınızı birlikte değerlendirelim.