Docker'yi üretimde aylarca hiçbir görünür sorun olmadan çalıştırabilirsiniz. Container'lar başlar, uygulamalar yanıt verir, hiçbir şey bozulmaz. Sonra açık kalan bir port ya da yanlış yapılandırılmış tek bir izin, bir saldırganın zorlanmadan elde ettiği bir dayanak noktasına dönüşür. Docker güvenlik hatalarının çoğu, bir şeyler ters gidene kadar hata gibi görünmez.
Bu makale, container ortamlarını riske atan belirli yapılandırmaları, her birinin saldırgana ne kazandırdığını ele alıyor ve bugün kendi kurulumunuza karşı çalıştırabileceğiniz bir kontrol listesiyle sona eriyor.
Docker Güvenliği Neden Göründüğünden Daha Zordur
Container'lar izole hissi verir. Birini başlatırsınız, kendi process alanında çalışır ve içeriden bakıldığında bir sonraki container sanki yoktur. Evet, bir izolasyon elde edersiniz, ama bu izolasyon kısmidir. Container'lar host'un kernel'ını paylaşır; bu da belirli koşullar altında bir container içindeki process'in host sisteme tamamen ulaşabilmesi anlamına gelir.
Docker, geliştirici kolaylığı için yapılandırılmış olarak gelir, üretim ortamı sertleştirmesi için değil. Root erişimi açık. Tüm portlar tüm arayüzlere bağlanabilir. Runtime izlemesi yok. Geliştiricilerin büyük çoğunluğu bu ayarları olduğu gibi kabul eder, container'ı deploy eder ve geçer. Başlangıç için makul bir yaklaşımdır; ama olgun bir güvenlik duruşu değildir.
Kaynak göre Red Hat'nin 2024 Kubernetes Güvenlik Durumu raporuKuruluşların %67'si, container veya Kubernetes güvenlik endişeleri nedeniyle uygulama dağıtımını geciktirdi ya da yavaşlattı. Bu sürtüşme genellikle saldırılardan kaynaklanmaz. Container kurulumlarının baştan dahil edilmemiş bir sertleştirmeye ihtiyaç duyduğunu keşfeden ekiplerden kaynaklanır.
Container'ların üretimde, bir geliştiricinin yerel makinesindeki yapılandırmanın aynısıyla çalıştığını sıklıkla görüyoruz. Docker güvenlik hataları da tam burada, sessiz sedasız birikir; denetlenene ya da bir şeyler bozulana kadar hiçbir belirti vermez.
Bu boşlukları yaratan hatalar belirli, öngörülebilir ve büyük ölçüde önlenebilir niteliktedir; üstelik yapılandırma düzeyinden başlar.
Yaygın Docker Yapılandırma Hataları
Container ihlallerinin çoğu sıfırıncı gün açığıyla başlamaz. İlk günde, ağ maruziyeti veya yetki kapsamı pek düşünülmeden yapılan bir yapılandırmayla başlar.
Varsayılan Docker ayarları çalışmak üzere tasarlanmıştır. İşlevsellik ile güvenlik arasındaki bu boşluk, Docker container güvenlik risklerinin biriktiği yerdir; özellikle deploy edildikten sonra bir daha gözden geçirilmeyen kendi kendine barındırılan kurulumlarda.
Bu kalıpla sık sık karşılaşıyoruz: genel IP'li sunucularda çalışan container'lar, port bağlamaları, kullanıcı ayarları ve ağ yapılandırmalarıyla ilk deploy anından farksız şekilde duruyor.
Container'ları Root Olarak Çalıştırmak
Bir kullanıcı belirtmeden Docker container'ı başlattığınızda, container root olarak çalışır. Bu, uygulamanız dahil container içindeki her process'in, container'ın namespace'i içinde root düzeyinde ayrıcalıklara sahip olduğu anlamına gelir.

Container içinde root olmak, host'ta root olmakla aynı şey değildir; ama ayrım mutlak da değildir. İyi belgelenmiş runc CVE-2019-5736 ve benzer runtime açıkları gibi, runtime'ı hedef alan yetki yükseltme exploitleri çoğunlukla başarılı olmak için root container process'i gerektirir.
Root olmayan container'lar, bu exploitlerin dayandığı root process koşulunu ortadan kaldırır ve söz konusu zafiyet sınıfı için saldırı yüzeyini önemli ölçüde daraltır; ancak container kaçış riskini tamamen ortadan kaldırmaz.
Bunu çözmek için Dockerfile dosyanıza bir USER direktifi eklemeniz yeterli. Bazı resmi imajlar, USER direktifiyle etkinleştirebileceğiniz ayrıcalıksız bir kullanıcıyla gelir. Ancak pek çoğu hâlâ root olarak çalışır ve hazır bir uygulama kullanıcısı sunmaz. Bu durumlarda, kullanıcıya geçmeden önce onu Dockerfile içinde oluşturursunuz. Kendi kendine barındırılan kurulumların büyük çoğunluğu için bu tek değişiklik, yetki yükseltme riskinin tüm bir kategorisini ortadan kaldırır.
Çok Fazla Portu Genel İnternete Açmak
Docker ile bir port yayımladığınızda, Docker kendi iptables kurallarını doğrudan yazar. Bu kurallar, sunucu düzeyindeki güvenlik duvarı kurallarından önce çalışır. Bu durum, topluluk tarafından raporlanan ve iyi bilinen bir davranıştır ve Docker'nin paket filtreleme kılavuzunda belgelenmiştir; bir yanlış yapılandırma değildir ve UFW ile benzer araçların, Docker'nin zaten açtığı trafiği engelleyemeyeceği anlamına gelir.

Docker, pek çok Linux sunucusunda UFW ve firewalld'ı atlayarak doğrudan iptables'a yazar. Bu, 0.0.0.0'a bağlı bir portun, güvenlik duvarınız yapılandırılmış görünse bile kamuya açık olabileceği anlamına gelir. Bulut güvenlik grupları ve DOCKER-USER zinciri kuralları bu trafiği engelleyebilir; dolayısıyla gerçek maruz kalma durumu, ağ kurulumunuza göre değişir.
Mümkün olan her yerde servisleri 127.0.0.1'e bağlayın, dışarıya açık trafiği bir reverse proxy üzerinden yönlendirin ve yalnızca gerçekten dış erişim gerektirenleri yayımlayın. Sunucudan ne kadarının dışarıya açıldığını kontrol etmenin en güvenilir yolu reverse proxy kullanmaktır.
Konteynerler Arasındaki Ağ İzolasyonunu Göz Ardı Etmek
O ağdaki her konteyner, aynı ağdaki diğer konteynerlere hiçbir kısıtlama olmadan ulaşabilir. Varsayılan bridge, aynı ağı paylaşan konteynerler arasında herhangi bir trafik filtrelemesi uygulamaz ve çoğu kurulum bu yapılandırmayı hiç değiştirmez.

Bir konteyner ele geçirilirse, bu açık iletişim yatay hareket için bir saldırı yolu haline gelir. Bir frontend konteyneri, aynı varsayılan bridge ağında bulunan bir veritabanına, dahili bir API'ye veya başka herhangi bir şeye, bu erişim hiç planlanmamış olsa bile, ulaşabilir.
Kullanıcı tanımlı ağlar, hangi konteynerlerin iletişim kurabileceği üzerinde size doğrudan kontrol sağlar. Ancak tüm servislerinizin paylaştığı tek bir özel ağ, konteynerler arası trafiği yine de serbest bırakır. Gerçek izolasyon, birbirleriyle konuşmaması gereken servisleri ayrı ağlara koymayı gerektirir. Varsayılan bridge'i devre dışı bırakmak bir başlangıç noktasıdır, bitiş değil.
Docker Soketini Gözden Kaçırmak
/var/run/docker.sock konumundaki Docker soketi, tüm Docker motorunun kontrol arabirimidir. Onu bir konteynere bağlamak, o konteynere sunucu üzerinde çalışan daemon'a doğrudan API erişimi verir.

Bu erişimle bir konteyner yeni konteynerler başlatabilir, sunucu dizinlerini bağlayabilir, çalışan konteynerleri inceleyip değiştirebilir ve pratikte sunucu makinesini kontrol edebilir. Saldırı yüzeyi, sunucu üzerinde root erişimiyle eşdeğerdir. Bu yüzden soket erişimi gerektiren her araç dikkatli bir değerlendirmeyi hak eder.
Çoğu kullanım senaryosu için daha güvenli alternatifler mevcuttur: kapsamlı API'ler veya Docker yönetim araçları soket erişimi gerektirmeyen seçeneklerdir. Docker-in-Docker yöntemi kendi güvenlik ve operasyonel ödünleşimlerini beraberinde getirir ve doğrudan bir alternatif değildir.
Yapılandırma hataları başlangıçtaki açığı oluşturur. İmaj ve bağımlılık tercihleri ise bu açığın zamanla nasıl büyüyeceğini belirler.
Konteyner Ömrünü Aşan İmaj ve Gizli Bilgi Hataları
Bir konteyneri durdurduğunuzda, içindeki yapılandırma hataları da durur. Ancak bir güvenlik açığı veya sabit kodlanmış bir kimlik bilgisi taşıyan imajdan yeniden derlediğinizde, sorun konteynerle birlikte yeniden başlar. İmaj düzeyindeki hatalar, her dağıtım arasında sıfırlanmaz.
İmajı çeken her ortama, onu depolayan her kayıt defterine ve çalıştıran her ekip üyesine imajla birlikte taşınırlar. Bu kalıcılık, imaj ve gizli bilgi yönetimini ayrı bir risk kategorisi haline getirir ve yapılandırmadan bağımsız olarak ayrıca denetlenmesi gerekir.
Bu kalıbı sık görüyoruz: proje başında dikkatle seçilen bir imaj, bir daha yeniden oluşturulmadan bırakılıyor ve başlangıçta temsil ettiği güvenlik temelinden yavaş yavaş uzaklaşıyor.
Güvenilmez veya Güncel Olmayan İmajların Kullanımı
Herkese açık registry'ler herkese açıktır. Kötü niyetli imajlar, katman geçmişine gömülü kripto-madenci yazılımları ve arka kapılar taşıyan Docker Hub aracılığıyla dağıtılmıştır; bu tehditler container yeniden başlatmalarında da varlığını sürdürür. Özellikle resmi olmayan veya bilinmeyen yayıncıların imajları söz konusu olduğunda, çekmeden önce doğrulama yapmak kritik önem taşır.

Ayrı bir sorun da güncelliğini yitirmiş olmaktır. Altı ay önce çektiğiniz ve bir daha yeniden oluşturmadığınız resmi bir imaj, paketlerine karşı açıklanan her CVE ile birlikte yamalanmamış Docker güvenlik açıkları biriktirmeye devam etmektedir. İmaj bozuk değil. Sadece artık güncel değil.
Sonatype'ın 2024 State of the Software Supply Chain raporu güvenlik açığı içeren bir bileşenin kullanıldığı durumların %95'inde düzeltilmiş bir sürümün zaten mevcut olduğunu ve uygulama bağımlılıklarının %80'inin bir yılı aşkın süre boyunca güncellenmediğini ortaya koymuştur. Bu durum, aynı açık kaynak paketlerine dayandığından Docker temel imajları için de geçerlidir.
Doğrulanmış yayıncıların resmi imajlarını kullanın ve "latest" etiketine güvenmek yerine belirli sürüm etiketleri sabitleyin. İmajlarınızı güncel tutmak için düzenli bir yeniden derleme takvimi oluşturun.
Docker Dosyalarına ve Compose Dosyalarına Gizli Bilgilerin Sabit Kodlanması
Bir Docker dosyasının ENV veya ARG talimatına yazılan, Compose environment bloğuna sabit kodlanan, build argümanı olarak geçirilen ya da sürüm kontrolüne commit edilmiş bir .env dosyasında saklanan kimlik bilgileri, container'ı durdurduğunuzda ortadan kalkmaz. İmaj katmanı geçmişinde veya kaynak kontrolünde kalır ve bu kaynaklara erişebilen herkes tarafından görülebilir.

Bu, Docker güvenliğinde en çok göz ardı edilen hatalardan biridir; çünkü geliştirme sürecinde görünür bir soruna yol açmaz. ENV talimatındaki bir API anahtarı doğru çalışır. Ancak aynı zamanda repository'nizde kayıtlıdır, imajınıza işlenmiştir ve o imajın gittiği her yere taşınır.
Modern Docker Compose, kimlik bilgilerini imaja işlemeden çalışma zamanında bağlayan yerel bir secrets mekanizması sunar. Docker'nin secrets API'si ve harici secrets yöneticileri de aynı prensiple çalışır. Kimlik bilgilerini build çıktılarından ve commit edilmiş dosyalardan tamamen uzak tutmanın yolu bu seçeneklerdir.
Çalışma zamanı ortam değişkenleri, sabit kodlanmış kimlik bilgilerine kıyasla bir iyileştirme sağlar; ancak Docker inspect çıktısı, loglar ve çökme dökümleri aracılığıyla yine de açığa çıkabilirler. Sabit kodlanmış gizli bilgilerden bir adım öteye geçer, ama bu tek başına yeterli bir çözüm değildir.
Container İmajlarını Düzenli Olarak Güncellememe
Aylarca aynı imajı çalıştırmak yaygın bir alışkanlıktır. Yeni bir güvenlik açığı açıklandıktan sonra yeniden derleme yapılmadan geçen her gün, container'larınızdaki maruziyet penceresi görünür bir değişiklik olmaksızın büyümeye devam eder.
Tutarlı bir yeniden derleme takvimi oluşturun. Bu süreci mümkün olduğunca otomatize edin ve mevcut imajlarınıza karşı periyodik olarak bir güvenlik açığı tarayıcısı çalıştırın. Amaç mükemmellik değil. Bir yamanın yayınlanması ile devreye alınması arasındaki süreyi kısaltmaktır.
Hızlı dağıtımlarda erişim kontrolü ve izleme ikinci plana itilir. Öte yandan olayların en uzun süre fark edilmeden kaldığı kategoriler de tam olarak bunlardır.
Erişim Kontrolü ve Görünürlük Açıkları
Bir container sağlam bir yapılandırma ve güncel imajlarla çalışır hale geldikten sonra geriye iki başarısızlık kategorisi kalır. Her ikisi de doğası gereği görünmezdir: zayıf bir erişim kontrolü sorununu ancak biri onu kullandığında fark edersiniz, izleme açığını ise hiç loglanmamış bir aktiviteyi araştırmanız gerektiğinde.
Aynı Red Hat 2024 araştırması ekiplerin %42'sinin container güvenliği ve ilgili tehditlere yönelik yeterli kapasiteden yoksun olduğunu ortaya koymuştur.
İzleme açıklarının genellikle olay araştırmaları sırasında gün yüzüne çıktığını, öncesinde değil, görüyoruz. Görünürlük bir öncelik haline geldiğinde çoğunlukla önlem almak için değil, bir şeye yanıt vermek için geç kalınmış oluyor.
Zayıf Kimlik Doğrulama ve Açıkta Kalan Yönetim Panelleri
Kimlik doğrulaması olmadan genel bir IP üzerinde erişilebilen bir container yönetim panosu, gelişmiş bir saldırgan gerektirmez. Sadece adresi bilmek yeterlidir. Bu, çoğu ekibin fark ettiğinden çok daha düşük bir engeldir.

Kendi kendine barındırılan izleme ve yönetim araçları genellikle tüm ağ arayüzlerinde erişilebilen bir web arayüzüyle gelir. Bunları önünde kimlik doğrulama olmadan genel bir IP üzerinde bırakmak, konteyner dünyasında yönetici panelini kilitsiz açık bırakmakla eşdeğerdir.
Kimlik doğrulama, ters proxy ve özel ağ yerleşimi temel gereksinimlerdir. Erişim denetimi, her yönetim arayüzüne sonradan eklediğiniz bir yapılandırma adımıdır; varsayılan olarak etkin gelmez.
Aynı ilke şunlar için de geçerlidir: Docker CLI ve GUI yönetimi; daemon'a yönetici düzeyinde erişim, arayüzden bağımsız olarak aynı riski taşır.
Konteynerlerinizin Ne Yaptığını İzlememek
Bir konteyner ele geçirildiğinde, saldırganın etkinliği iz bırakır: süreç davranışı değişir, alışılmadık ağ bağlantıları kurulur ve beklenmedik dosya değişiklikleri gerçekleşir. Log toplama mekanizması yoksa bu iz, üzerine hareket edebileceğiniz bir biçimde mevcut olmaz.
Merkezi log toplama, konteyner denetim günlüğü ve çalışma zamanı izleme araçları, anormal etkinliği büyümeden önce tespit etmeniz için gereken veriyi sağlar. Amaç her satırı analiz etmek değil, soruşturma gerektiğinde veriye sahip olmaktır.
Üretim ortamında log hattı ve uyarı mekanizması olmadan sessizce çalışan konteyner kurulumları düşük bakımlı değildir. Denetimsizdir. Bu ikisi farklı operasyonel durumlardır.
Altyapı Ortamının da Önemi
Konteyner güvenliği yapılandırmayla başlar; ancak yapılandırma altyapının üzerinde çalışır. Yanlış yapılandırılmış ağ, paylaşımlı kaynaklar veya ağ düzeyinde filtreleme eksikliği olan bir host, üzerindeki her konteyneri etkileyen koşullar oluşturur. Konteyner kurulumunu doğru yapmak ile sunucu yapılandırmasını doğru yapmak birbirinden ayrı iki görevdir.
Docker güvenlik açıklarının büyük bölümü, konteynerlerin miras aldığı koşullar tarafından derinleştirilir:
- Kiracılar arasında donanım yalıtımı olmayan paylaşımlı kiracılı bir sunucu
- Yama uygulanmamış bir host kernel
- Yerleşik ağ düzeyinde filtreleme bulunmayan bir host
Bu durum, yukarıdaki yapılandırma adımlarına olan ihtiyacı ortadan kaldırmaz; doğru konteyner sertleştirmesi altyapı katmanından bağımsız olarak önemlidir. Yalıtılmış bir altyapıyla başlamak, denklemden bir endişe katmanını kaldırır.
Cloudzy'de, kurulumunuzun gerektirdiğine bağlı olarak iki seçenek sunuyoruz:
- Linux VPS: Docker'yi kendiniz dağıtmak ve bu makaledeki sertleştirme adımlarını uygulamak için temiz bir ortam
- Portainer VPS: Portainer önceden kurulu olarak gelen tek tıklamalık seçenek; sunucu açılır ve siz doğrudan paneldeysinizdir
Her iki seçenek de aynı altyapı üzerinde çalışır: KVM sanallaştırma, 5,7 GHz'e kadar boost clock hızına sahip AMD Ryzen 9 CPU işlemciler, DDR5 bellek, NVMe SSD depolama, 40 Gbps'ye kadar ağ ve BuyVM filtrelemesi üzerinden ücretsiz DDoS koruması; 12 küresel konum ve %99,95 çalışma süresi SLA.
Portainer'yi bir VPS üzerinde çalıştırmaya daha ayrıntılı bakmak için konuyu özel bir makalede ele alıyoruz.
Docker Dağıtımları için Pratik Bir Güvenlik Kontrol Listesi
Yukarıdaki Docker güvenlik hataları çoğunlukla bir kez alınan ve hiç gözden geçirilmeyen tek yapılandırma kararlarından kaynaklanır. Bu kontrol listesini mevcut bir kuruluma karşı çalıştırmak bu açıkları yakalar. Bir dağıtım rehberi değil, denetim aracı olarak işlev görür.
Bu Docker güvenlik en iyi uygulamaları, Docker konteynerlerini yukarıda açıklanan en yaygın yapılandırma hatalarına karşı nasıl koruyacağınızı kapsar.
Hızlı Başvuru: 9 Hatanın Tamamı
| Hata | Kategori | Tek Satırlık Çözüm |
| Root olarak çalışıyor | Yapılandırma | Ekle USER Docker dosyanıza directive ekleyin |
| Portlar 0.0.0.0'a bağlı | Yapılandırma | 127.0.0.1 adresine bağlayın ve reverse proxy üzerinden yönlendirin |
| Ağ izolasyonu yok | Yapılandırma | Servisleri erişim ihtiyacına göre ayrı kullanıcı tanımlı ağlara bölün. |
| Docker socket bağlandı | Yapılandırma | Bağlamayı kaldırın; kapsamlı API'lar veya alternatifler kullanın |
| Güvenilmeyen veya eski imajlar | Görüntü | Sabitlenmiş versiyon etiketleriyle resmi imajlar kullanın |
| Sabit kodlanmış gizli diziler | Görüntü | Kimlik bilgilerini runtime env var'larına veya bir secrets manager'a taşıyın |
| İmaj yeniden oluşturma takvimi yok | Görüntü | Aylık yeniden oluşturma takvimi belirleyin; mümkün olan yerleri otomatikleştirin |
| Kimlik doğrulanmamış panolar | Erişim | Kimlik doğrulama ekleyin ve yönetim arayüzlerini özel ağlara taşıyın |
| Container log toplama yok | Erişim | Merkezi log toplama ve runtime izleme kurun |
Önce mevcut kurulumlar üzerinde çalıştırmanızı öneririz; açıklar büyük olasılıkla zaten orada bulunur.
Root olmayan kullanıcı olarak çalışan container'lar: Docker dosyalarınızda USER directive'i olup olmadığını kontrol edin. Yoksa container root olarak çalışır.
Port bağlamaları localhost ile sınırlı veya proxy üzerinden: docker ps komutunu çalıştırın ve port bağlamalarını inceleyin. 0.0.0.0:PORT girişi; upstream security group, harici firewall veya DOCKER-USER zincir kuralının engellemediği hostlarda dışarıdan erişilebilir olabilir.
Kullanılan özel bridge ağları: Docker'ın varsayılan bridge'indeki container'lar birbirine serbestçe erişebilir. Aynı kullanıcı tanımlı bridge üzerindeki container'lar da birbirleriyle iletişim kurabilir; bu nedenle gerçek izolasyon için servisleri güven sınırına göre ayrı ağlara bölün.
Container'lara Docker socket bağlanmamış: Compose dosyalarını ve çalıştırma argümanlarını kontrol edin. /var/run/docker.sock bir volume olarak görünüyorsa, bunun gerekli ve kasıtlı olduğunu doğrulayın.
Sabitlenmiş versiyonlarla doğrulanmış yayıncılardan temel imajlar: FROM ubuntu:latest komutu, belirtilmemiş ve potansiyel olarak güncel olmayan bir sürümü çeker. Belirli bir sürüme sabitleyin.
Docker dosyalarında, Compose dosyalarında veya build argümanlarında gizli bilgi bulunmamalıdır: İmaj katmanı geçmişi, konteyner silinse bile kimlik bilgilerini saklar. Compose secrets, Swarm secrets, build secret mount'ları veya harici bir secrets yöneticisi kullanın. Çalışma zamanı ortam değişkenleri, kodun içine gömülü değerlere göre daha iyidir; ancak inspect çıktısında ve günlüklerde görünmeye devam eder.
İmaj yeniden derleme takvimi tanımlanmış: Eski imajlar zamanla güvenlik açıkları biriktirir. Aylık bir yeniden derleme döngüsü, çoğu kurulum için risk penceresini yönetilebilir düzeyde tutar.
Yönetim arayüzleri kimlik doğrulamasının arkasında: Genel IP üzerindeki herhangi bir pano, kimlik doğrulaması olmadan açık bir giriş noktasıdır. Mümkün olan durumlarda özel ağ kullanımı tercih edilmelidir.
Konteyner günlükleri toplanıyor: Bir günlük pipeline'ı olmadan, olayları ancak sistemde belirgin bir etki göründüğünde fark edersiniz. Bu, müdahale için oldukça geç bir sinyaldir.
Sonuç
Docker'nin varsayılan yapılandırması kullanım kolaylığı için tasarlanmıştır, güvenlik için değil. Bu makalede ele alınan hataların büyük çoğunluğu, ilk kurulumdan sonra hiç değiştirilmemiş ayarlara dayanır; karmaşık saldırılara değil.
Düzeltmelerin büyük kısmı tek seferlik yapılandırma kararlarıdır: bir USER direktifi, port bağlama değişikliği, özel bir ağ, bir yeniden derleme takvimi. Çoğu kurulum için yeni bir araç gerektirmez.
Konteyner yapılandırmasını doğru şekilde ayarlamak ilk adımdır. Üzerinde çalıştığı altyapı ise ikinci adımdır. Her ikisi de önemlidir ve biri diğerinin yerini tutmaz.