İçeriğe geç
Sedat Özdemir
Yazılar

container-security

Gemi Su Alıyor mu? Konteyner Katmanları Arasında Kaybolan Güvenlik ve Sahadan Dersler

Konteynerler hayatımızı kolaylaştırdı evet, ama aynı zamanda saldırganlar için yepyeni bir oyun alanı yarattı. İzolasyonun bir kale olmadığını anlama vakti geldi.

Sedat Özdemir
· 4 dk okuma

Selamlar, kahveler hazırsa bugün biraz 'modern' dertlerimizden konuşalım. Eskiden güvenliği fiziksel bir kale inşa etmek gibi düşünürdük; sağlam bir firewall, sıkı bir IDS/IPS ve kapıda duran bir 'bouncer' (WAF). Ama dünya değişti. Artık kimse monolitik devasa sunucuların peşinde koşmuyor, her şeyi parçalara ayırıp küçük paketlere (container) dolduruyoruz. Peki, bu küçük paketlerin içindeki dünyada işler gerçekten göründüğü kadar steril mi? Yoksa sadece sorunlarımızı daha küçük kutulara mı hapsettik?

Bir trendden bahsederek başlayalım: Bir dönem 'sanal makinem (VM) varsa izoleyim' kafası çok meşhurdu. Şimdi ise 'konteyner kullanıyorum, zaten ephemeral (geçici), saldırgan içeri girse ne olur ki?' yanılgısı popüler. Sahada gördüğümüz acı gerçek şu; saldırganlar o geçici konteynerin içinden çıkıp (escape), senin tüm cluster’ını bir oyun alanına çevirmek için sadece saniyeler harcıyor. Gelin, testCompany bünyesinde yaptığımız testlerden ve gerçek hayat senaryolarından yola çıkarak bu gemi neden su alıyor, bir bakalım.

1. 'Root' Olma Takıntısı ve İlizyonlar

Konteyner dünyasındaki en büyük yanılgı, konteyner içindeki root kullanıcısının dışarıdaki root ile aynı güçte olmadığına inanmaktır. Teknik olarak, Linux namespace'leri sayesinde bir izolasyon var evet, ama bu izolasyon pamuk ipliğine bağlı. Eğer bir Dockerfile yazarken en alt satıra USER belirten bir komut eklemediyseniz, o uygulama varsayılan olarak root yetkileriyle çalışır.

Bir saldırgan olarak en sevdiğim senaryo nedir biliyor musunuz? Dışarıya açık bir web uygulamasında RCE (Remote Code Execution) bulup içeri girdiğimde whoami yazdığımda root cevabını almak. Neden? Çünkü konteyner içinde root isem, çekirdek açıklarını zorlayıp 'container escape' yapmak için elimde her türlü yetki var demektir.

Hatalı Dockerfile Örneği (Zararsızlaştırılmış):

FROM node:14
WORKDIR /app
COPY . .
RUN npm install
# USER tanımlanmamış, uygulama root olarak çalışıyor!
CMD ["node", "app.js"]

Doğru Yaklaşım:

FROM node:14-slim
# Gereksiz araçları sildik, sadece ihtiyacımız olanları bıraktık
RUN groupadd -r appuser && useradd -r -g appuser appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
USER appuser
CMD ["node", "app.js"]

2. Supply Chain: Truva Atını Kendi Ellerinizle İçeri Almak

Sadece kendi yazdığınız koda güvenmek yetmiyor. FROM python:3.9 dediğinizde aslında o imajın içindeki yüzlerce kütüphaneye ve işletim sistemi katmanına da 'evet' demiş oluyorsunuz. Geçenlerde bir Red Team senaryosunda, sadece imajın içinde unutulan ve kullanılmayan eski bir curl sürümü üzerinden nasıl yanal hareket (lateral movement) yapabildiğimizi gördük.

İmajlar katmanlıdır. Bir katmanda sildiğiniz hassas veri (örneğin bir API key), bir önceki katmanda hala kabak gibi duruyor olabilir. docker history komutunu hiç kendi imajlarınız üzerinde denediniz mi? Deneyin, bazen orada bir 'hardcoded credential' faciası görebilirsiniz.

Checklist:

  • distroless imajları kullanmayı deneyin. İçinde shell bile olmayan bir imajda saldırganın işi çok zordur.
  • İmajlarınızı CI/CD sürecinde mutlaka tarayın (Trivy, Grype gibi araçlarla).

3. Docker Socket: Krallığın Anahtarını Paspasın Altına Koymak

İşte bu benim favorim. Bazen monitoring araçları veya CI/CD agent'ları düzgün çalışsın diye konteynere /var/run/docker.sock dosyasını mount ederler. Bu ne demek biliyor musunuz? 'Al bu anahtarı, git bu host üzerindeki tüm Docker dünyasını yönet' demektir.

Eğer bir saldırgan bu sokete erişimi olan bir konteyneri ele geçirirse, host üzerinde yeni bir konteyner başlatıp, host'un tüm dosya sistemini o konteynere mount edebilir. Oyun biter.

Tehlikeli Çalıştırma Komutu: docker run -v /var/run/docker.sock:/var/run/docker.sock example-app (Lütfen bunu gerçek sistemlerinizde yapmayın, yapıyorsanız da nedenini iki kez düşünün.)

4. Runtime Security: Kim Ne Yapıyor?

Konteyner ayağa kalktıktan sonra içeride neler olup bittiğini kim izliyor? Bir web sunucusu konteyneri neden aniden apt-get update komutu çalıştırsın? Veya neden durup dururken 127.0.0.1 dışında garip bir IP'ye (örneğin c2-server.example.com) outbound bağlantı kurmaya çalışsın?

Saldırganlar içeri girdikten sonra genelde sessiz kalmaya çalışmazlar (en azından ilk aşamada). Araç indirmek, network taraması yapmak isterler. Eğer bir 'Runtime Security' çözümünüz (Falco gibi) yoksa, ruhunuz bile duymaz.

Örnek Falco Kuralı Mantığı (Pseudo Code):

rule: Unauthorised Shell in Container
condition: container.id != host and proc.name = bash and not user.name in (allowed_users)
output: "Uyarı: %container.id konteynerinde beklenmedik shell açıldı! (user=%user.name)"
priority: CRITICAL

5. Network Segmentasyonu: Herkes Herkesle Konuşmamalı

Konteyner ağları genelde düzdür (flat). Yani A microservice'i, B microservice'i ile konuşabilir. Peki ya frontend konteyneriniz ele geçirilirse ve doğrudan production veritabanınıza (internal-db.example.com) erişebilirse?

Kubernetes tarafında 'Network Policies' kullanarak trafiği kısıtlamak lüks değil, zorunluluktur. 'Zero Trust' prensibini sadece insanlar için değil, servisler için de uygulayın. Sadece ihtiyacı olan portu, sadece ihtiyacı olan yere açın.

Bir Red Teamer Gözüyle Tavsiyeler

Arkadaşlar, işin özü şu: Konteyner teknolojisi bize hız kazandırdı ama hırsızın da hızını artırdı. Bir konteynerin güvenliğini sağlamak için şu üç temel prensibi asla unutmayın:

  1. En Az Yetki (Least Privilege): Konteyner root çalışmasın, sadece gereken capabilities tanımlansın (örneğin --cap-drop all --cap-add net_bind_service).
  2. Değişmezlik (Immutability): Konteynerin dosya sistemini read-only olarak bağlayın. Saldırgan içeride bir dosya oluşturup çalıştıramazsa, kalıcılık (persistence) sağlayamaz.
  3. Görünürlük (Observability): Ne olduğunu bilmediğiniz bir şeyi koruyamazsınız. Loglarınızı merkezi bir yere toplayın ve anormallikleri takip edin.

Unutmayın, biz testCompany'de sistemleri kırarken genelde kapıyı kırmıyoruz; zaten aralık bırakılmış pencereleri kullanıyoruz. O pencereleri kapatmak ise sizin elinizde.

Siber dünyada kalın, ama güvenli tarafta kalın!

İlgili yazılar