DOCKER SECURITY VE IMAGE SCAN
Docker Hub'daki popüler public image'ler üzerinde düzenli yapılan taramalar, bunların önemli bir kısmının yayımlandıkları gün bile yüksek veya kritik seviyede bilinen güvenlik açıkları içerdiğini ortaya koyuyor. Bir Node.js veya Python uygulamasını "official" bir image'in üstüne kurup production'a iten ekip, farkında olmadan onlarca CVE'yi de paketin içine taşımış olur. Image scan bu yüzden bugün container yaşam döngüsünde test ve build kadar temel bir adım sayılıyor. Bu yazı geliştirici, DevOps mühendisi veya sistem yöneticisi olarak Docker ile production çalıştıran herkesin image güvenlik taramasını net bir zihin haritasıyla kavraması için yazıldı.
Image Scan Neyi, Nasıl Tarar?
Image scan basitçe şu sorunun cevabıdır: "Bu image'ın içindeki paketlerin hangileri bilinen güvenlik açıklarına sahip?" Scanner image'i bir tarball olarak açar, içindeki dosya sistemini gezer ve birkaç farklı kaynaktan paket envanteri çıkarır:
- OS paket yöneticisi metadata'sı (
/var/lib/dpkg/status,/var/lib/rpm,/lib/apk/db/installed) - Dil ekosistemine özgü manifest dosyaları (
package-lock.json,requirements.txt,go.sum,pom.xml) - Binary'lerden çıkarılan versiyon imzaları — Go ile static derlenmiş binary'lerin içine gömülü modül listesi gibi
Bu envanter sonra public CVE veritabanlarıyla karşılaştırılır. Ana referans ulusal açık güvenlik veritabanı ve onun üzerine kurulu dağıtım-spesifik feed'lerdir: Debian Security Tracker, Alpine secdb, Red Hat OVAL, GitHub Advisory Database. Her bulgu CVE numarası, etkilenen versiyon aralığı, fix versiyonu ve CVSS puanı ile raporlanır. Yani scan aslında fingerprint + lookup operasyonudur — yeni bir saldırı keşfeder gibi davranmaz, sadece zaten bilinen açıkların image'da bulunup bulunmadığına bakar.
Base Image Seçimi Yüzey Alanını Belirler
Bir scan raporunun çıktısı büyük ölçüde base image seçimi tarafından belirlenir. ubuntu:22.04 üstüne kurulan bir Node.js uygulaması; uygulamanın hiç dokunmadığı yüzlerce pakete (curl, gcc, perl, openssl tooling, locales) maruz kalır. Aynı uygulama node:20-alpine üstüne kurulduğunda paket sayısı bir büyüklük mertebesi düşer; gcr.io/distroless/nodejs üstüne kurulduğunda neredeyse sadece runtime kalır — shell bile yoktur.
Genel pratik kalıp:
- Production final: distroless veya minimal alpine — paket sayısı az, scan raporu temiz
- Build aşaması: tam dağıtım image'i (debian, ubuntu) — derleme araçlarına ihtiyaç var
- Final image: multi-stage build ile yalnızca çalışma için gerekli binary'ler kopyalanır
Multi-stage yaklaşımı, scan'in çıktısını birkaç saatte 200 critical CVE'den 0-3 critical'a indirebilir. Yüzey alanı küçüldükçe taranacak yüzey ve patch yükü beraber azalır. Distroless image'ın bir başka pratik etkisi de saldırgan içeri girse bile elinde shell, curl, paket yöneticisi olmadığı için pivot yapmasının zorlaşmasıdır.

Açık Kaynak Scanner Araçları
Image taraması için yaygın kullanılan birkaç araç var ve hemen hepsi açık kaynak olarak ücretsiz çalışır. Aralarındaki farklar daha çok ekosistem entegrasyonu ve çıktı formatından kaynaklanır:
- Trivy (Aqua Security)
- En yaygın açık kaynak scanner. OS paketleri, dil bağımlılıkları, Terraform/Kubernetes manifest'leri ve secret'ları tek komutla tarar. Hızlı, CI-dostu çıktı verir.
- Grype (Anchore)
- SBOM-temelli yaklaşımıyla dikkat çeker. Önce Syft ile SBOM çıkarır, sonra Grype onu tarar; CI'da artifact olarak SBOM saklamak isteyen ekipler bu ayrımı sever.
- Docker Scout
- Docker'ın resmi entegre çözümü. Docker Desktop ve Docker Hub'a doğrudan bağlı; en yakın "tek komutla bütünleşik scan" deneyimi sunar. Resmi belgelendirmeyi Docker dokümantasyonunda bulabilirsiniz.
- Clair
- Quay/Red Hat tarafından geliştirilen, registry tarafı tarama için tasarlanmış servis modeli scanner. Self-hosted registry'lerde popüler.
Pratikte hızlı başlamak isteyenler için Trivy en düşük sürtünmeli seçenektir:
trivy image node:20— bir komut, anında rapor--severity HIGH,CRITICAL— sadece yüksek seviyeleri göster--exit-code 1 --severity CRITICAL— CI'da critical bulgu varsa pipeline'ı kır--ignore-unfixed— fix'i olmayan açıkları rapor dışı bırak (gürültü azaltır)
CI/CD'ye Entegrasyon ve Tag Disiplini
Image scan'in gerçek değeri manuel çalıştırmadan değil, build pipeline'ına gömülü olmasından gelir. Tipik bir akış şöyledir:
- Image build edilir
- Build edilen image scan'lenir (Trivy, Scout veya tercih edilen başka bir araç)
- Severity policy'ye göre
exit 1verilir ya da geçilir - Yalnızca policy'yi geçen image registry'ye push edilir
- Production deploy yalnızca taranmış-onaylanmış digest'lerden yapılır
Bu zincirde kritik nokta tag immutability'dir: bir image bir kez tag'lenip push edildikten sonra üzerine farklı bir içerikle aynı tag yazılmamalı. Aksi halde v1.2.3 tag'i bugün temiz, yarın açıklı olabilir ve siz farkına varmadan production'da iki farklı içerik bulundurursunuz. Çözüm: :latest kullanımını yasaklamak, SHA digest pinning (image@sha256:abc...) veya semantic version ile birlikte registry tarafında immutable repo policy kullanmak.
Docker'la production ortamında çalışıyorsanız bu konuların pratiğini bütünsel görmek için Docker eğitimi imaj yapısından registry mimarisine kadar uygulamalı oturumlar içerir.

SBOM ve Severity Politikası
SBOM (Software Bill of Materials), bir image'ın içindeki tüm paketlerin makine okunabilir listesidir. Tedarik zinciri saldırılarına karşı son birkaç yılda fiili standart haline geldi; ABD'de federal yazılım alımları artık SBOM zorunluluğu içeriyor. Syft veya Trivy ile JSON, SPDX ya da CycloneDX formatında üretilir; image ile birlikte registry'de saklanır (cosign attestation). Bunun pratik faydası şu: bir CVE bugün yayımlandığında, hangi image'lardan etkilendiğinizi yeniden tarama yapmadan SBOM üzerinde sorgulayabilirsiniz.
Severity politikası ise her ekibin kendi bağlamına göre kalibre ettiği bir eşiktir. Yaygın bir kademe örneği:
- Critical: Build kırılır, push engellenir
- High: Build geçer, ticket otomatik açılır, sprint içinde patch'lenir
- Medium: Aylık review
- Low / Negligible: Yıllık audit, çoğunlukla kabul edilir
Mutlak "sıfır CVE" hedefi pratikte çoğu zaman gerçekçi değildir — özellikle base OS bağımlılıkları için. Hedef, yamalanabilir olanı zamanında yamalamak; istisnaları gerekçeleriyle birlikte belgelemek olmalıdır. Belirsizlik bırakan tek satırlık "kabul edildi" notları, denetim sırasında en zayıf halkadır.
Pratik Önlemler ve Sık Hatalar
Image güvenliği tek başına scan ile bitmez; scanner'ın doğru raporlayacağı bir tasarımı sağlamak da onun kadar önemlidir:
- Versiyonu sabitle:
FROM node:20yerineFROM node:20.11.1-alpine3.19. Latest tag'i unutulması gereken bir tuzaktır. - Multi-stage kullan: Build araçları final image'a sızmamalı. Derleme aşaması ayrı, runtime aşaması ayrı olmalı.
- Root kullanma:
USER nodeile non-root kullanıcıya düş. Container içinde root, host'ta tam kullanıcı olmasa da pod escape senaryolarında saldırı yüzeyini büyütür. - Secret commit etme: Layer'lar değişmezdir. Bir layer'a yazılan secret silinemez, sadece üstüne ekleme yapılır.
--secretmount veya buildkit secret disiplini gerekir. - Düzenli yeniden build: Otuz gün önce build ettiğiniz image bugün açıklı olabilir; CI'da haftalık yeniden build cron'u kurulmalı.
- Registry tarafında rescan: Push anındaki tarama bir an'lık fotoğraftır; registry üzerinde periyodik rescan ve yeni CVE alarmı gerekir.
Son nokta sık atlanır: bir image scan'i bir an'lık fotoğraftır. Bugün temiz raporlanan image yarın yeni bir CVE yayımlandığında açıklı hale gelebilir. Bu yüzden registry tarafında periyodik rescan, runtime tarafında ise Kubernetes için OPA Gatekeeper veya Kyverno ile admission policy birlikte kurulduğunda scan gerçekten koruyucu bir katmana dönüşür. Tek başına bir CI adımı olarak görüldüğünde, taranmamış hot-fix image'lerinin manuel deploy'larıyla kolayca atlanabilen bir yumuşak engele dönüşür.



