Bir Docker imajı, sizin yazdığınız kodun yanı sıra genellikle onlarca (bazen yüzlerce) başkasının yazdığı paketi de içinde taşır: taban işletim sistemi katmanları, programlama dili çalışma zamanı, kütüphaneler… Bunların herhangi birinde bilinen bir güvenlik açığı varsa, o açık sizin imajınıza da geçer. Container image güvenliği, bu riski build aşamasında yakalamak ve olabildiğince küçültmekle ilgilidir.
1. Küçük ve güncel taban imaj seçin
Bir imajın güvenlik açığı sayısı, çoğunlukla içindeki paket sayısıyla doğru orantılıdır. ubuntu:latest gibi genel amaçlı, büyük bir taban imaj yerine daha dar kapsamlı alternatifler seçmek, saldırı yüzeyini doğrudan küçültür:
| Taban imaj | Yaklaşık boyut | Not |
|---|---|---|
ubuntu:24.04 |
~80 MB | Genel amaçlı, çok paket içerir |
node:20 |
~380 MB | Debian tabanlı, geliştirme araçları dahil |
node:20-slim |
~180 MB | Gereksiz araçlar çıkarılmış |
node:20-alpine |
~50 MB | Minimal Alpine Linux tabanlı |
gcr.io/distroless/nodejs20 |
~120 MB | Kabuk (shell) bile içermez |
“Distroless” imajlar en uçtaki seçenektir: içlerinde paket yöneticisi, kabuk (sh/bash) hatta çoğu zaman temel Linux komutları bile yoktur — bir saldırgan container’a sızsa bile elinde çalıştırabileceği neredeyse hiçbir araç kalmaz.
2. İmajı etiket sabitleyerek (pin) kullanın, :latest‘ten kaçının
# Kaçının — hangi sürümü çektiğiniz belirsiz, güncellemede ne değişti bilinmez
FROM node:latest
# Tercih edin — üretilebilir (reproducible), denetlenebilir
FROM node:20.15.1-alpine3.20
Sabit bir sürüm etiketi, “dün çalışan build bugün neden bozuldu?” sorununu önler ve bir güvenlik taramasının sonucunu tekrar üretilebilir kılar.
3. Zafiyet taraması (vulnerability scanning) yapın
İmajınızı push etmeden önce, içindeki paketleri bilinen güvenlik açığı veritabanlarıyla (CVE) karşılaştıran bir tarayıcıdan geçirin. En yaygın açık kaynak araç Trivy‘dir:
# Trivy kurulumundan sonra tek komutla tarama
trivy image benim-uygulamam:1.0
# Sadece "yüksek" ve "kritik" seviyeli açıkları göster,
# böyle bir açık bulunursa CI/CD adımını başarısız say
trivy image --severity HIGH,CRITICAL --exit-code 1 benim-uygulamam:1.0
Bu taramayı CI/CD pipeline’ınıza (örneğin her docker build‘dan sonra) eklemek, güvenlik açığı olan bir imajın production’a hiç ulaşmamasını sağlar.
Docker Hub, GitHub Container Registry ve çoğu bulut sağlayıcının kendi registry’si de push edilen imajları otomatik olarak tarayabilir — bu özelliği registry ayarlarınızdan etkinleştirmek, ek bir araç kurmadan temel bir güvenlik katmanı sağlar.
4. Gizli bilgileri (secret) imaja asla gömmeyin
API anahtarları, veritabanı parolaları gibi gizli bilgileri ENV veya ARG ile doğrudan Dockerfile’a yazmak yaygın ama tehlikeli bir hatadır — bu değerler imajın katmanlarında kalıcı olarak saklanır ve docker history ile kolayca görülebilir:
# Yapmayın — parola imaj katmanına kalıcı olarak gömülür
ARG DB_PASSWORD=gizli123
ENV DB_PASSWORD=$DB_PASSWORD
# Bunun yerine: çalışma zamanında dışarıdan enjekte edin
# docker run -e DB_PASSWORD=gizli123 ...
# veya Docker Compose'da bir .env dosyası / secrets kullanın
5. Gereksiz katmanları ve dosyaları build bağlamından çıkarın
Multi-stage build (bkz. Dockerfile Yazmaya Giriş yazımız) ile build araçlarını nihai imajdan tamamen ayırmak, hem boyutu küçültür hem de derleyici, test araçları gibi gereksiz yazılımların üretim imajında bulunmasını önler — bu yazılımlardaki olası açıklar da böylece devreye girmez.
Hızlı kontrol listesi
- Küçük, minimal bir taban imaj kullanıyor musunuz? (
alpine,slim, distroless) - Taban imaj sürümünü sabitlediniz mi,
:latestkullanmıyor musunuz? - İmajı CI/CD içinde otomatik olarak tarıyor musunuz? (Trivy, Grype, registry’nin kendi tarayıcısı)
- Container root olmayan bir kullanıcıyla mı çalışıyor? (bkz. Rootless container yazımız)
- Gizli bilgiler imaja gömülü değil, çalışma zamanında mı enjekte ediliyor?
- Multi-stage build ile build araçları nihai imajdan ayrıştırılmış mı?
Bu portaldaki Dockerfile Kontrolcüsü aracı, bu kontrol listesindeki maddelerin çoğunu (taban imaj etiketi, USER talimatı, gömülü sır tespiti gibi) Dockerfile’ınızı yapıştırdığınız anda otomatik olarak kontrol eder — imajı build etmeden önce hızlı bir ön kontrol için kullanabilirsiniz.