Blog
Güven Yanılgısı: Çok Kiracılı Docker Kurulumumuzun Veri Sızdırması (Ve Nasıl Düzelttik)
Bir ekibin saf Docker kurulumunun kiracılar arası veri sızıntısına nasıl yol açtığını ve bunu önleyen katmanlı izolasyon stratejisini öğrenin.
Özet
Docker konteynerleri varsayılan olarak izole değildir—ana bilgisayar çekirdeğini paylaşırlar ve bilinçli bir yapılandırma olmadan kiracılar birbirine müdahale edebilir. Bu makale, çok kiracılı bir barındırma sağlayıcısının, paylaşılan ağ ve zayıf güvenlik varsayımları nedeniyle müşteri konteynerlerinin birbirlerinin veritabanlarına erişebildiğini keşfettiği gerçek bir senaryoyu ele alıyor. İhlali düzelten adım adım değişiklikleri gösteriyoruz: kiracı başına kullanıcı tanımlı ağlar, root olmayan kullanıcılar, düşürülmüş yetenekler, salt okunur dosya sistemleri ve seccomp profilleri. Yaygın bir varsayım, konteynerlerin doğal olarak güçlü izolasyon sağladığıdır; biz, VM'lerin neden hala daha zor bir sınır sunduğunu ve hibrit bir yaklaşımın ne zaman düşünülmesi gerektiğini açıklayarak buna meydan okuyoruz. Sonuç, izolasyonun tek bir onay kutusu değil, katmanlı bir egzersiz olduğunu vurguluyor.
Olay: Konteynerler Çok Fazla Konuştuğunda
Tek bir ana bilgisayarda birden fazla müşteri web sitesini çalıştırmak için Docker kurdunuz. Her müşterinin kendi konteyneri var—düzenli, izole bir ortam, değil mi? Biz de öyle düşünmüştük. Ta ki rutin bir güvenlik denetimi, A Müşterisi'nin konteynerinin aynı ana bilgisayardaki B Müşterisi'nin konteynerinin MySQL soketini okuduğunu ortaya çıkarana kadar. Varsayılan bridge ağını paylaşıyorlardı. Daha da kötüsü, konteynerler root olarak çalışıyordu, bu nedenle bir konteyneri ele geçiren bir saldırgan, ana bilgisayarın Docker soketine veya başka bir konteynerin dosya sistemine müdahale edebilirdi. İhlal karmaşık bir istismar değildi; temel bir yanlış yapılandırmaydı. Veri sızdı. Güven kayboldu.
Başarısızlık senaryosu nadir değildir. Birçok ekip, Docker'ın ad alanlarının ve cgroup'ların otomatik olarak kiracıları ayırdığını varsayar, ancak varsayılan olarak kaç tane kaçış kapağının açık kaldığını hafife alırlar. Varsayılan köprü ağları, konteynerler arasında ağ izolasyonu sunmaz. Root olarak çalışmak, konteynere ihtiyaç duyulandan daha fazla güç verir. Ve açık kaynak sınırları olmadan, gürültülü bir komşu diğerlerinin CPU veya belleğini aç bırakabilir.
Adım 1: Tek Bir Ağı Paylaşmayı Durdurun
İlk düzeltmemiz, her kiracıya kendi kullanıcı tanımlı Docker ağını vermek oldu. Bu, konteynerlerin birbirine erişmesini, siz açıkça bağlamadıkça engeller. Her kiracı için özel bir ağ başlatan ve uygulama konteynerini buna bağlayan bir komut dosyası oluşturduk. Veritabanı konteyneri aynı kiracı ağında yaşar, ancak yalnızca kiracı içi iletişim için bir iç ağ da ekledik. Artık kiracılar arası gözetleme yok.
Veritabanlarını da ayrı konteynerlerde, aynı kiracı ağında ve ayrı veri birimleri kullanarak izole ettik. Bu, bir saldırgan uygulama konteynerine girse bile başka bir kiracının veritabanı trafiğini koklayamamasını sağladı.
Ağ izolasyon stratejileri hakkında daha derin bir inceleme için Çok Kiracılı Barındırma İçin Pratik Docker İzolasyon Güvenlik Kontrol Listesi adresine bakın.
Adım 2: Gereksiz Ayrıcalıkları Kaldırın
Varsayılan olarak, Docker konteynerleri sınırlı bir dizi Linux yeteneğiyle çalışır, ancak yine de çoğu uygulamanın ihtiyaç duyduğundan daha fazlasına sahiptir. Konteynerlerimiz root olarak çalışıyordu, bu da içindeki işlemlerin dosya sistemlerini bağlama veya çekirdek parametrelerini değiştirme gibi eylemler gerçekleştirmesine izin veriyordu. Uygulamayı konteyner içinde root olmayan bir kullanıcı olarak çalıştırmaya geçtik (Dockerfile'da USER yönergesini kullanarak) ve kesinlikle gerekli olanlar dışındaki tüm yetenekleri düşürdük. Tipik bir web uygulaması için bu, yalnızca NET_BIND_SERVICE (1024'ün altındaki bağlantı noktalarına bağlanmak için) ve CHOWN (diziniere yazmak için) olabilir. Ayrıca ayrıcalık yükseltmeyi önlemek için --security-opt no-new-privileges ekledik.
Bu adım tek başına birçok yaygın konteyner kaçış vektörünü ortadan kaldırdı. Web sunucusunu ele geçiren bir saldırgan, işlem CAP_SYS_ADMIN veya CAP_DAC_OVERRIDE yeteneklerine sahip olmadığı için paket yükleyemez, sistem ikili dosyalarını değiştiremez veya ana bilgisayarın Docker soketine erişemez.
Adım 3: Dosya Sistemini Kilitleyin
Yazılabilir dosya sistemleri yaygın bir saldırı yüzeyidir. Tüm konteynerler için kök dosya sistemini salt okunur yaptık (--read-only) ve yazma erişimi gereken dizinler için geçici dosya sistemleri (tmpfs) bağladık, örneğin /tmp ve uygulamanın önbellek dizini gibi. Bu, bir saldırganın uygulama kodunu değiştirmesini veya kötü amaçlı ikili dosyaları kalıcı hale getirmesini önler.
Ek olarak, Docker soketi gibi hassas dizinleri yalnızca kesinlikle gerekli olduğunda bağlamak için Docker'ın --mount seçeneğini kullandık—ve asla üretim konteynerlerinde. İlke: konteynerin bir yola yazması gerekmiyorsa, salt okunur yapın.
Adım 4: Seccomp ve AppArmor Profilleri Uygulayın
Varsayılan seccomp profilleri zaten birçok tehlikeli sistem çağrısını engeller, ancak uygulamamızın gerçekten ihtiyaç duyduğu sistem çağrılarını yalnızca beyaz listeye almak için bunları daha da özelleştirdik. Bu, uygulamanın profillenmesini gerektirdiği için bir ödünleşimdir. Daha basit bir yaklaşım, Docker'ın varsayılan seccomp profilini kullanmak ve daha katı kurallara ihtiyacınız varsa --security-opt seccomp=path/to/profile.json eklemektir. Benzer şekilde, AppArmor profilleri konteyner işlemlerini belirli dosya yolları ve yeteneklerle sınırlayabilir. AppArmor'u etkinleştirdik ve yalnızca uygulamanın veri dizinlerine erişimi kısıtlayan özel bir profil kullandık.
Bu sertleştirme adımları hakkında kapsamlı bir kılavuz için Çok Kiracılı Barındırma İçin Docker Konteynerlerini Sertleştirme: Adım Adım İzolasyon Rehberi adresine bakın.
Karşıt Görüş: Bazen VM'lere İhtiyacınız Var
Ne kadar sertleştirilmiş olursa olsun, konteynerler ana bilgisayarın çekirdeğini paylaşır. Bir çekirdek güvenlik açığı tüm izolasyonu bir anda kırabilir. Bu nedenle birçok güvenlik bilincine sahip platform, konteynerleri hafif VM'lerin içinde çalıştırır—her kiracı kendi çekirdeğine sahip olur. Bu, ek yük getirir ancak konteynerlerin tek başına sağlayamayacağı donanım düzeyinde bir sınır sağlar. Kiracılarınız kredi kartı verileri veya sağlık kayıtları işliyorsa, hibrit bir yaklaşım (VM'ler içinde konteynerler) doğru seçim olabilir. Konteyner izolasyonunun tehdit modeliniz için yeterli olduğunu varsaymayın; verilerin hassasiyetini ve düzenleyici gereksinimleri değerlendirin.
İzolasyon seviyelerinin daha derin bir karşılaştırması için Çok Kiracılı Docker Mimarisi Tasarlama: Doğru İzolasyon Seviyesini Seçmek adresini okuyun.
Sonuç: İzolasyon Bir Anahtar Değil, Bir Yığındır
Düzeltme tek bir değişiklik değildi—katmanlamaydı: ağ izolasyonu, sınırlı ayrıcalıklar, salt okunur dosya sistemleri ve sistem çağrısı filtreleme. Yine de, paylaşılan çekirdek konteynerleriyle mükemmel izolasyonun imkansız olduğunu kabul ettik. En yüksek güvenlikli kiracılarımız için onları özel ana bilgisayarlara taşıdık. Ders: hiçbir varsayılana güvenmeyin. Docker kurulumunuzu sanki bir ihlal zaten olmuş gibi denetleyin. Kilitleme zamanı sızıntıdan öncedir, sonra değil.


