İçeriğe Atla
Rehberler · 6 dk okuma · görüntülenme
100%

Docker Container Güvenlik Rehberi

Image supply chain’den runtime hardening’e kadar, Docker container’ları üretimde güvenli çalıştırmak için pratik kontrol listesi ve runbook.

Docker container güvenliği için image, runtime ve host kontrollerini gösteren kapak görseli

Docker güvenliği çoğu ekipte “image scan yaptık, bitti” seviyesinde ele alınıyor. Üretimde ise risk yüzeyi daha geniş: image supply chain, runtime konfigürasyonu ve host/daemon katmanı birlikte düşünülmezse, bir gün “container içinden host’a çıkıldı” vakasıyla uyanırsınız.

Bu rehber, Docker’ı “tek bir tool” değil, bir işletim modeli olarak ele alır. Amacım akademik değil: sahada uygulanabilir, ölçülebilir ve CI/CD’ye bağlanabilir bir kontrol listesi vermek.

Docker container güvenliği için image, runtime ve host kontrollerini gösteren kapak görseli
Güvenli container çalıştırmak: image + runtime + host katmanlarını birlikte kilitlemektir.

1) Tehdit modeli: “Neyi engelliyoruz?”

İlk adım “en iyi pratikler” listesi değil; kendi tehdit modeliniz. Docker güvenliğinde en sık gördüğüm senaryolar:

  • Supply chain: Base image’e zehirli layer, dependency typosquatting, CI’da sızan token.
  • Secrets sızıntısı: ENV, build arg, layer history, log, crash dump.
  • Yetki yükseltme: --privileged, CAP_SYS_ADMIN, docker.sock mount, kernel escape.
  • Lateral movement: Aynı host’ta başka container’lara geçiş, iç ağ keşfi, metadata servisleri.
  • Operasyonel risk: Yanlış tag/pin, rollback yok, drift var, “benim makinemde çalışıyordu”.

Kendinize şu 4 soruyu sorun:

SoruAmaçTipik kontrol
Container içi kod kötü niyetliyse host’a çıkar mı?Escape riskini azaltmakRootless, seccomp, caps drop
Image’e zararlı bağımlılık girdiyse prod’a çıkar mı?Supply chain’i kapatmakSBOM, scan, sign, policy gate
Secret’lar nereye sızabilir?“Kaza” riskini azaltmakBuild secrets, runtime injection, audit
Incident’ta hızlı triage yapabilir miyiz?Hasarı sınırlamakLog/metric, immutable image, runbook

2) Image katmanı: Build-time güvenlik ve hijyen

Üretimdeki pek çok incident, runtime’dan önce başlar: image’in içine giren paketler, build sırasında kullanılan credential’lar, base image seçimi…

Benim minimum standardım:

  1. Minimal base image (attack surface küçük)
  2. Digest pinleme (tag drift engeli)
  3. Multi-stage build (build toolchain runtime’a taşınmaz)
  4. Non-root user (default olarak root çalışmaz)
  5. Deterministic build (lockfile + reproducibility)

Örnek: “güvenli varsayılan” Dockerfile

# syntax=docker/dockerfile:1.7
FROM node:22-alpine AS build
WORKDIR /app

# 1) Kilitli bağımlılıklar
COPY package.json package-lock.json ./
RUN npm ci

# 2) Kaynak + build
COPY . .
RUN npm run build

# Runtime image: daha küçük, daha az paket
FROM node:22-alpine AS runtime
WORKDIR /app

# 3) Non-root user
RUN addgroup -S app && adduser -S app -G app
USER app

# 4) Sadece gerekli artefact’lar
COPY --from=build /app/dist ./dist

ENV NODE_ENV=production
CMD ["node", "dist/server/entry.mjs"]

Bu örnek “en iyi” değil; “en güvenli varsayılanı” hedefliyor. Daha ileri gidecekseniz:

  • node:alpine yerine distroless (tooling/debug trade-off)
  • apk add gibi paket ekleme minimal ve audit’li
  • Sürüm pinleme: FROM node@sha256:... (her build aynı base)

3) Supply chain: SBOM, tarama, imzalama (scan yetmez)

“Scan yaptım” demek, “risk yok” demek değildir. Scan size sadece “bilinen CVE” listesini verir. Üretimde güvenlik için ben 3 parçayı birlikte isterim:

  • SBOM (Software Bill of Materials): “İçinde ne var?”
  • Vulnerability scan: “Bilinen açık var mı?”
  • Signature/attestation: “Bu image’i kim üretti, aynı mı?”

Pratikte “minimum” çizgi:

# SBOM + scan örneği (tool seçimi size ait)
trivy image --scanners vuln,secret --format table myapp@sha256:...

# İmzalama örneği (cosign)
cosign sign --key cosign.key myapp@sha256:...
cosign verify --key cosign.pub myapp@sha256:...

Policy gate mantığı: CI’da “kritik CVE var mı?” + “imza var mı?” + “SBOM üretildi mi?” sorularını merge/deploy kapısına bağlayın.

4) Secrets: Build arg/ENV ile değil, doğru kanalla

Secrets sızıntısı genelde “kötü niyet” değil, yanlış alışkanlık:

  • ARG NPM_TOKEN=... (image history’de kalır)
  • ENV DB_PASSWORD=... (docker inspect ile görünür)
  • .env dosyasını image’e kopyalama

Doğru yaklaşım: Secret’ı image’e gömmemek, runtime’da enjekte etmek.

Build-time secret gerekiyorsa (ör. private registry)

BuildKit ile secret mount kullanın (layer’a yazılmaz):

# syntax=docker/dockerfile:1.7
RUN --mount=type=secret,id=npm_token \
    NPM_TOKEN="$(cat /run/secrets/npm_token)" npm ci

Runtime secret enjekte etme

  • Docker secrets (Swarm) / orchestrator secret store
  • Kubernetes secret + CSI driver / external secret manager
  • Kısa ömürlü token (OIDC) + service identity

5) Runtime hardening: Capabilities, seccomp, read-only FS

Runtime tarafında hedef: container içindeki proses “kötüleşirse” bile etkisini sınırlamak.

Güvenli çalıştırma bayrakları (Docker run)

docker run --rm \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  --pids-limit 256 \
  --memory 512m --cpus 1 \
  --security-opt no-new-privileges:true \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  --user 10001:10001 \
  --network myapp-net \
  myapp@sha256:...

Burada yaptıklarımız:

  • read-only rootfs: dosya yazma kabiliyetini düşürür (persistence zorlaşır)
  • tmpfs: gerekli yazılabilir alanı kontrollü verir (noexec/nosuid)
  • pids/memory/cpu limit: fork bomb / DoS etkisini sınırlar
  • no-new-privileges: setuid gibi “sonradan yetki alma” yollarını kapatır
  • cap-drop: kernel yetkilerini en aza indirir

seccomp / AppArmor / SELinux

Docker’ın default seccomp profili fena değildir ama kritik iş yüklerinde daha sıkı profil gerekir. Minimum yaklaşım:

  • Default seccomp’u kapatma (--security-opt seccomp=unconfined) yasak
  • Mümkünse AppArmor/SELinux açık
  • Prod için “golden profile” çıkar (hangi syscall’lar gerekli?)

6) Host ve daemon: En çok unutulan katman

Container’larınız ne kadar iyi olursa olsun, host tarafı zayıfsa oyun biter.

Benim host tarafında beklediğim minimumlar:

  • Kernel patch seviyesi güncel, reboot disiplini var
  • Docker daemon erişimi sınırlandırılmış (docker grup üyeliği kontrol altında)
  • Rootless mümkünse tercih edilmiş
  • Logging/audit açık ve merkezi
  • Image cache ve registry erişimi kontrollü

Docker daemon için örnek sertleştirme ayarları

{
  "live-restore": true,
  "no-new-privileges": true,
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "5" }
}

Bu dosya genelde /etc/docker/daemon.json altındadır. Her ayarı “kopyala-yapıştır” yapmayın; önce test edin.

7) CI/CD’de güvenlik kapıları: “Deploy hakkı” bir policy kararıdır

Güvenliği “doküman” değil, pipeline kuralı haline getirin:

  1. PR’da: SAST + secret scan
  2. Build’te: SBOM + vulnerability scan
  3. Publish’te: sign + provenance
  4. Deploy’de: policy check (imza var mı? kritik CVE var mı?)

Bu yaklaşımın iyi yanı: “kimseye güvenmek zorunda kalmazsınız”, sistem zaten izin vermez.

8) Kubernetes’e kısa not: Aynı prensip, farklı mekanizma

Docker’da docker run ile yaptığınız çoğu şey Kubernetes’te securityContext ile gelir:

  • runAsNonRoot: true
  • readOnlyRootFilesystem: true
  • allowPrivilegeEscalation: false
  • capabilities: drop: ["ALL"]

Ve politika katmanında:

  • Pod Security Standards / PSA
  • Admission policy (OPA/Gatekeeper, Kyverno)
  • NetworkPolicy ile lateral movement kontrolü

9) Incident runbook: Şüpheli container davranışı

Bir container “garip” davranıyorsa (beklenmeyen outbound, crypto miner şüphesi, spike):

  1. Ağ izolasyonu: Egress’i kes (ilk 2 dakika)
  2. Image + digest: Hangi digest koşuyor? Registry’den aynı mı?
  3. Process list: Beklenmeyen proses var mı? (ps, ss, lsof)
  4. Filesystem writes: read-only değilse hangi path’e yazmış?
  5. Credential exposure: ENV/volume/secrets erişimi logla
  6. Host sinyali: Kernel audit / runtime alerts (Falco/eBPF)
  7. Kök neden: Supply chain mi, misconfig mi, exploit mi?

Sonuç: Minimum güvenli profil (kopyala + uyarlayın)

Eğer “hepsini bir anda yapamam” diyorsanız, sırayı şöyle koyun:

  1. Digest pin + multi-stage + non-root
  2. Secret’ı image’den çıkar (runtime injection)
  3. --cap-drop ALL + no-new-privileges + read-only rootfs
  4. SBOM + scan + sign + policy gate
  5. Host patch + rootless standardı + audit/log pipeline

Güvenlik, tek bir ayar değil; tasarım + otomasyon + operasyon ritmi. En iyi gösterge de şudur: Bir gün “kötü image” geldiğinde sisteminiz onu prod’a sokmuyor mu?

Paylaş:

Bu yazı faydalı oldu mu?

Yükleniyor...

Bu yazı nasıldı?

ME

Mustafa Erbay

Sistem Mimarisi · Network Uzmanı · Altyapı, Güvenlik ve Yazılım

2006'dan bu yana sistem mimarisi, network, sunucu altyapıları, büyük yapıların kurulumu, yazılım ve sistem güvenliği ekseninde çalışıyorum. Bu blogda sahada karşılığı olan teknik deneyimlerimi paylaşıyorum.

Kişisel Notlar

Bu notlar sadece sizde saklanır. Tarayıcınızda yerel olarak tutulur.

Hazır 0 karakter

Yorumlar

Sunucu Taraflı AI Moderasyon

Yorumlar sunucuda yapay zeka ile denetlenir ve kalıcı olarak saklanır.

?
0/2000

Sunucu taraflı AI denetim

Yeni yazılardan haberdar olun

Haftada bir yeni içerikler ve kaynaklar doğrudan e-postanıza gelsin.

Spam yok. Yalnızca yeni ve önemli içerikler için e-posta gönderilir.

Okuma İstatistikleriniz

0

Yazı Okundu

0dk

Okuma Süresi

0

Gün Serisi

-

Favori Kategori

İlgili Yazılar