Konteyner teknolojileri uygulama dağıtımını kökten değiştirdi ancak güvenlik konusunda yeni sorumluluklar da getirdi. Docker ortamında güvenlik açığı oluşabilecek pek çok nokta vardır: imaj içindeki zafiyetli paketler, yanlış yapılandırılmış runtime ayarları, aşırı yetkilendirilmiş konteynerler ve güvenli olmayan ağ yapılandırmaları bunların başında gelir. Docker güvenliğini ciddiye almak, konteyner hale getirdiğiniz uygulamanın ve üzerinde koştuğu altyapının bütünlüğünü korumak demektir.
İmaj Güvenliği: Temelden Başlamak
Docker güvenliğinin ilk halkası konteyner imajlarıdır. Kullandığınız base image ne kadar temizse, saldırı yüzeyiniz o kadar dar olur. Alpine Linux gibi minimal imajlar, Ubuntu veya Debian tabanlı imajlara kıyasla çok daha az paket içerir ve dolayısıyla potansiyel zafiyet sayısını ciddi oranda azaltır. Bir karşılaştırma yapmak gerekirse, standart python:3.11 imajı yaklaşık 900 MB boyutundayken python:3.11-alpine yaklaşık 50 MB’dir. Bu boyut farkı yalnızca depolama değil, güvenlik açısından da önemlidir.
Multi-stage build kullanmak hem imaj boyutunu küçültür hem de güvenliği artırır. Build aşamasında kullanılan derleyiciler, paket yöneticileri ve geliştirme araçları final imaja dahil edilmez. Örneğin bir Go uygulaması için build stage’de kaynak kodu derlenir, ikinci stage’de yalnızca derlenmiş binary scratch veya distroless imaj üzerine kopyalanır. Final imajda ne shell ne paket yöneticisi ne de gereksiz herhangi bir araç bulunur.
İmaj Taraması
Kullandığınız imajları düzenli olarak zafiyet taramasından geçirmek zorunludur. Trivy, Snyk Container veya Azure Defender for Containers gibi araçlar imaj katmanlarındaki paketleri CVE veritabanlarıyla karşılaştırır. CI/CD pipeline’ınıza entegre bir tarama adımı ekleyerek, zafiyetli imajların production ortamına ulaşmasını engelleyebilirsiniz. Kritik (Critical) veya yüksek (High) seviye zafiyet tespit edildiğinde pipeline’ı otomatik olarak durdurmalısınız.
Runtime Güvenliği
Konteyner çalışma zamanında alınması gereken önlemler imaj güvenliği kadar önemlidir.
Root Olarak Çalıştırmayın
Dockerfile’da USER direktifi ile uygulamanızı root olmayan bir kullanıcıyla çalıştırın. Root olarak çalışan bir konteynerden host sisteme sızma riski çok daha yüksektir. Konteyner runtime’ı bir güvenlik sınırı olsa da, kernel zafiyetleri veya yanlış yapılandırmalar bu sınırı aşılabilir hale getirebilir.
Read-Only Filesystem
Konteyneri --read-only flag’i ile başlatmak, dosya sistemine yazma işlemlerini engeller. Uygulama log veya geçici dosya yazması gerekiyorsa, yalnızca belirli dizinleri tmpfs olarak mount edebilirsiniz. Bu yaklaşım, bir saldırganın konteynere sızdıktan sonra zararlı dosya yerleştirmesini büyük ölçüde engeller.
Capability Kısıtlaması
Linux kernel capabilities, root yetkisini granüler parçalara böler. Docker varsayılan olarak bazı capability’leri kaldırır ama hepsi yeterli olmayabilir. --cap-drop=ALL ile tüm capability’leri kaldırıp yalnızca uygulamanızın gerektirdiklerini --cap-add ile eklemek en güvenli yaklaşımdır. Örneğin bir web sunucusu genellikle yalnızca NET_BIND_SERVICE capability’sine ihtiyaç duyar.
Secret Yönetimi
Konteyner ortamında hassas bilgiler (veritabanı şifreleri, API anahtarları, sertifikalar) nasıl yönetilir? İlk kural: secret’ları kesinlikle imaj içine gömmemelisiniz. Dockerfile’a ENV DB_PASSWORD=gizli123 yazmak veya .env dosyasını imaja kopyalamak ciddi bir güvenlik hatasıdır çünkü imaj katmanları incelendiğinde bu bilgiler herkes tarafından görülebilir.
Doğru yaklaşım, Docker Swarm kullanıyorsanız Docker Secrets, Kubernetes kullanıyorsanız Kubernetes Secrets veya harici secret yönetim araçları (HashiCorp Vault, Azure Key Vault) kullanmaktır. Runtime’da volume mount veya environment variable üzerinden secret’ları konteynere aktarın ancak mümkünse volume mount tercih edin çünkü environment variable’lar docker inspect ile okunabilir.
Ağ Güvenliği
Docker varsayılan olarak tüm konteynerleri aynı bridge ağında oluşturur ve konteynerler birbirleriyle serbestçe iletişim kurabilir. Üretim ortamında her uygulama bileşeni için ayrı Docker network tanımlayın. Web sunucusu, uygulama katmanı ve veritabanı farklı ağlarda olmalı ve yalnızca gereken bağlantılara izin verilmelidir. Bu yaklaşım, bir konteynerin ele geçirilmesi durumunda yanal hareket (lateral movement) riskini sınırlar.
Konteyner portlarını yayınlarken -p 8080:80 yerine -p 127.0.0.1:8080:80 kullanarak yalnızca localhost erişimini açın. Eğer konteyner bir reverse proxy arkasındaysa portu dış dünyaya açmanıza gerek yoktur. Gereksiz yere açılan portlar saldırı yüzeyini genişletir.
CI/CD Pipeline Entegrasyonu
Güvenlik kontrollerini kalkınma sürecinizin her aşamasına entegre etmek en etkili yaklaşımdır. Dockerfile linting (hadolint), imaj tarama (Trivy), secret tarama (git-leaks, truffleHog) ve runtime politika kontrolü (OPA/Gatekeeper) adımlarını pipeline’a ekleyin. Shift-left prensibiyle güvenlik sorunlarını production’a ulaşmadan, geliştirme aşamasında yakalayın.
Dockerfile Güvenlik Kontrol Listesi
Her Dockerfile yazarken aşağıdaki güvenlik kontrol listesini uygulayın. Bu liste temel kuralları içerir ve çoğu projeye doğrudan uygulanabilir.
Base image seçimi: Resmi (official) imajları tercih edin ve mutlaka belirli bir versiyon etiketi kullanın. python:latest yerine python:3.11.7-slim-bookworm gibi sabitlenmiş bir versiyon tercih edin. Latest etiketi bilinmeyen güncellemeler getirebilir ve build tekrarlanabilirliğini bozar. Mümkünse Alpine veya distroless varyantlarını kullanarak imaj boyutunu ve saldırı yüzeyini minimize edin.
Katman optimizasyonu: Her RUN komutu yeni bir katman oluşturur. Paket yükleme ve temizleme işlemlerini tek bir RUN komutunda birleştirin. Örneğin: RUN apt-get update && apt-get install -y --no-install-recommends pkg1 pkg2 && rm -rf /var/lib/apt/lists/*. Bu yaklaşım hem imaj boyutunu küçültür hem de paket yöneticisi cache dosyalarının katmanda kalmasını önler.
COPY vs ADD: Mümkün olduğunca COPY kullanın. ADD komutu tarball açma ve URL’den dosya indirme gibi ek özellikler sunar ancak bu özellikler beklenmeyen davranışlara yol açabilir. URL’den dosya indirmeniz gerekiyorsa RUN komutuyla curl veya wget kullanmak ve ardından checksum doğrulaması yapmak daha güvenlidir.
HEALTHCHECK tanımlayın: Konteynerin sağlığını izlemek için HEALTHCHECK direktifi ekleyin. Orchestrator (Docker Swarm, Kubernetes) bu bilgiyi kullanarak sağlıksız konteynerleri yeniden başlatır veya trafikten çıkarır. Örneğin bir web uygulaması için: HEALTHCHECK --interval=30s --timeout=5s CMD curl -f http://localhost:8080/health || exit 1.
Container Registry Güvenliği
İmajlarınızı depoladığınız registry de güvenlik zincirinin önemli bir halkasıdır. Azure Container Registry (ACR) veya benzeri kurumsal registry’ler kullanarak public registry’lere bağımlılığı azaltın. ACR’de content trust özelliğini etkinleştirerek imajların imzalanmasını zorunlu kılabilirsiniz. Bu sayede yalnızca yetkili kişilerin push ettiği ve imzaladığı imajları kullanabilirsiniz.
ACR Tasks özelliğiyle base image güncellendiğinde otomatik olarak üzerine inşa edilen imajları yeniden build edebilirsiniz. Örneğin Alpine 3.18 için bir güvenlik yaması yayınlandığında, bu base image’ı kullanan tüm uygulama imajlarınız otomatik olarak yeniden build edilir ve registry’ye push edilir. Bu otomasyon güvenlik yamalarının geciktirilmeden uygulanmasını sağlar.
Runtime Güvenlik İzleme
Konteynerlerin çalışma zamanında güvenliklerini izlemek için runtime security araçları kullanılmalıdır. Falco, Sysdig Secure veya Azure Defender for Containers gibi araçlar konteyner içindeki şüpheli aktiviteleri gerçek zamanlı olarak tespit eder. Beklenmeyen process başlatma, dosya sistemi değişiklikleri, ağ bağlantı girişimleri ve privilege escalation teşebbüsleri gibi olaylar alarm tetikler.
Örneğin bir web uygulaması konteynerinde /bin/bash process’inin başlatılması veya /etc/passwd dosyasına yazma girişimi olması anormal bir durumdur ve potansiyel bir sızma işareti olabilir. Runtime security aracı bu tür olayları yakalar, loglar ve yapılandırmaya göre konteyneri durdurabilir veya güvenlik ekibine alarm gönderebilir.
Docker Compose Güvenlik Ayarları
Geliştirme ve test ortamlarında Docker Compose yaygın olarak kullanılır. Compose dosyasında güvenlik ayarlarını tanımlamak production ortamına geçişi kolaylaştırır ve geliştirme aşamasında güvenlik kültürünü yerleştirir.
Compose servislerinde security_opt: [no-new-privileges:true] ayarıyla konteyner içinde privilege escalation’ı engelleyin. read_only: true ile dosya sistemini salt okunur yapın. mem_limit ve cpus ile kaynak limitleri belirleyerek bir konteynerin host kaynaklarını tüketmesini önleyin. networks ile servisleri izole ağlara yerleştirin, yalnızca gerekli servislerin birbiriyle iletişim kurmasına izin verin.
Image Signing ve Supply Chain Security
Yazılım tedarik zinciri güvenliği son yıllarda kritik önem kazandı. SolarWinds ve codecov gibi olaylar gösterdi ki saldırganlar doğrudan uygulamaları hedeflemek yerine build sürecini veya bağımlılıkları hedef alabilir. Docker imajlarında bu riski azaltmak için birkaç önlem alınabilir.
Cosign ile imajlarınızı imzalayın ve deploy sürecinde imza doğrulaması yapın. SBOM (Software Bill of Materials) oluşturarak imajınızdaki tüm bileşenleri ve versiyonlarını belgeleyin. Syft veya Trivy ile SBOM oluşturabilirsiniz. Kubernetes’te admission controller (OPA Gatekeeper veya Kyverno) kullanarak yalnızca imzalı ve taranmış imajların cluster’a deploy edilmesine izin verin.
Sıkça Sorulan Sorular
Docker Hub’dan çekilen imajlara güvenilebilir mi? Resmi (Official) imajlar Docker tarafından doğrulanır ve düzenli olarak güncellenir, bunlara makul düzeyde güvenilebilir. Ancak community imajları herhangi biri tarafından yayınlanabilir ve güvenlik garantisi yoktur. Production ortamında yalnızca kendi registry’nizde taranmış ve doğrulanmış imajlar kullanın.
Rootless Docker nedir? Docker daemon’ını root olmayan bir kullanıcı olarak çalıştırmaktır. Bu sayede daemon’un ele geçirilmesi durumunda saldırganın host üzerindeki yetkisi sınırlı kalır. Docker Engine 20.10 ve üzerinde rootless mod desteklenmektedir. Podman alternatif olarak varsayılan olarak rootless çalışır.
Docker Bench Security nedir? CIS Docker Benchmark’a göre Docker host ve daemon yapılandırmanızı denetleyen açık kaynaklı bir araçtır. Çalıştırdığınızda host konfigürasyonu, daemon yapılandırması, konteyner güvenlik ayarları ve imaj güvenliği konularında puan ve öneriler sunar. Production ortamına geçmeden önce Docker Bench çalıştırıp uyarıları gidermek iyi bir pratiktir.
Sonuç
Docker güvenliği, imaj oluşturmadan runtime yapılandırmasına, secret yönetiminden ağ izolasyonuna kadar çok katmanlı bir yaklaşım gerektirir. Her katmanda alınan önlemler bir sonraki katmanı daha güvenli kılar. Minimum imaj boyutu, root olmayan kullanıcı, read-only filesystem, capability kısıtlaması ve ağ segmentasyonu gibi temel pratikleri uyguladığınızda konteyner ortamınızın güvenlik duruşu önemli ölçüde güçlenir.
Cloudspark konteyner güvenliği danışmanlığı ve DevSecOps hizmetlerimizle Docker ortamlarınızı güvenli hale getirmenize yardımcı oluyoruz.



