CSF Firewall ile Docker ve Konteyner Entegrasyonu

Docker ortamlarında güvenlik duvarı yönetimi, klasik sunucu güvenliğinden oldukça farklı bir tablo çiziyor. Normalde CSF kuruyorsun, birkaç port açıyorsun, bitti. Ama Docker devreye girince iptables kuralları alt üst oluyor, konteynerler kendi ağ arayüzleri oluşturuyor ve CSF bu değişikliklerden habersiz kalıyor. Bu yazıda CSF ile Docker’ı birlikte nasıl düzgün çalıştırabileceğini, hangi tuzaklardan kaçınman gerektiğini ve production ortamı için güvenli bir yapı nasıl kurulur, bunları adım adım ele alacağız.

CSF ve Docker Neden Çatışıyor?

Docker, varsayılan olarak iptables üzerinde kendi kurallarını oluşturur. DOCKER ve DOCKER-USER zincirleri, docker0 köprü arayüzü ve NAT kuralları… Bunların hepsi Docker daemon başladığında otomatik olarak ekleniyor. CSF ise kendi başına çalışan, iptables üzerinde tam kontrol sahibi olmak isteyen bir güvenlik duvarı. Bu iki yapı aynı anda çalışmaya başladığında ortaya ciddi sorunlar çıkabiliyor.

En sık karşılaşılan problem şu: CSF’i yeniden başlatıyorsun, Docker konteynerlerine erişim aniden kesiliyor. Ya da Docker yeni bir konteyner başlatıyor, CSF’in kurallarını bypass ediyor ve teoride kapalı olması gereken portlar dışarıya açılıveriyor. İkinci senaryo özellikle tehlikeli çünkü güvenli olduğunu düşündüğün bir sistemde açıklar oluşabiliyor.

Temel sorun şu noktada: Docker’ın iptables entegrasyonu FORWARD zincirini ve PREROUTING NAT tablolarını kullanıyor. CSF ise bu zincirleri kendi politikalarına göre düzenliyor. İkisi arasında koordinasyon olmazsa kurallar çakışıyor.

Ortam Hazırlığı ve Mevcut Durumu Anlama

Yapılandırmaya geçmeden önce sisteminin mevcut durumunu anlamalısın. Aşağıdaki komutlarla iptables tablolarını inceleyebilirsin:

# Mevcut iptables kurallarını görüntüle
iptables -L -n -v --line-numbers

# NAT tablosunu görüntüle
iptables -t nat -L -n -v

# Docker'ın oluşturduğu zincirleri listele
iptables -L DOCKER -n -v
iptables -L DOCKER-USER -n -v

# Aktif Docker ağlarını listele
docker network ls

# Docker ağ detaylarını görüntüle
docker network inspect bridge

Bu çıktılara bakarak Docker’ın hangi IP aralıklarını kullandığını ve hangi zincirleri oluşturduğunu görebilirsin. Tipik bir kurulumda 172.17.0.0/16 aralığı docker0 arayüzüne atanmış olur.

CSF Yapılandırması: Temel Ayarlar

CSF’in Docker ile uyumlu çalışması için /etc/csf/csf.conf dosyasında bazı kritik değişiklikler yapman gerekiyor.

# csf.conf dosyasını düzenle
nano /etc/csf/csf.conf

Değiştirmen gereken parametreler:

  • DOCKER: 1 olarak ayarla. Bu Docker desteğini aktif eder.
  • ETH_DEVICE: Sunucunun ana ağ arayüzünü belirt (eth0, ens3 vb.)
  • ETH6_DEVICE: IPv6 kullanıyorsan IPv6 arayüzünü belirt.
  • DOCKER_NETWORK: Docker’ın kullandığı ağ aralığını belirt.
# csf.conf içinde bu değerleri güncelle
DOCKER = "1"
ETH_DEVICE = "eth0"
DOCKER_NETWORK = "172.17.0.0/16,172.18.0.0/16,172.19.0.0/16"

DOCKER_NETWORK parametresine birden fazla ağ aralığı girebilirsin, virgülle ayırman yeterli. Özellikle çok sayıda Docker ağı oluşturuyorsan bu önemli. Sisteminizde hangi ağların kullanıldığını docker network ls ve ip addr show komutlarıyla doğrulayabilirsin.

Docker Daemon Yapılandırması

CSF ile uyumlu çalışmak için Docker daemon’ının da bazı ayarları değiştirmen gerekebilir. /etc/docker/daemon.json dosyası bu iş için kullanılıyor:

{
  "iptables": true,
  "ip-forward": true,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "default-address-pools": [
    {"base": "172.17.0.0/12", "size": 24}
  ]
}

Bazı kaynaklar Docker’da "iptables": false ayarını öneriyor. Bu yaklaşım Docker’ın iptables’ı hiç değiştirmemesini sağlıyor ama bu durumda NAT ve port yönlendirme kurallarını tamamen manuel yönetmen gerekiyor. Production ortamında bu yöntemi kullanmak oldukça zahmetli. Bunun yerine Docker’ın iptables’ı yönetmesine izin verip CSF ile birlikte çalıştırmanı öneririm.

# daemon.json değişikliklerini uygulamak için Docker'ı yeniden başlat
systemctl restart docker

# CSF'i de yeniden başlat
csf -r

DOCKER-USER Zinciri: En Temiz Çözüm

Docker, özellikle bu tür güvenlik duvarı entegrasyonları için DOCKER-USER zincirini sunuyor. Bu zincire eklediğin kurallar Docker’ın kendi kurallarından önce işleniyor ve Docker daemon yeniden başladığında silinmiyor. CSF ile birlikte kullanmak için en güvenli yöntem bu.

CSF’in /etc/csf/csfpost.sh dosyasına Docker ile ilgili kuralları ekleyebilirsin. Bu dosya CSF başlatıldığında en son çalışır, dolayısıyla kuralların geçerli kalmasını sağlar:

#!/bin/bash
# /etc/csf/csfpost.sh

# Docker ağından gelen trafiğe izin ver
DOCKER_NETWORK="172.17.0.0/16"

# DOCKER-USER zincirine kural ekle
iptables -I DOCKER-USER -i eth0 -d $DOCKER_NETWORK -j ACCEPT
iptables -I DOCKER-USER -s $DOCKER_NETWORK -j ACCEPT

# Docker konteynerler arası iletişime izin ver
iptables -I FORWARD -i docker0 -o docker0 -j ACCEPT
iptables -I FORWARD -i docker0 ! -o docker0 -j ACCEPT
iptables -I FORWARD -o docker0 -j ACCEPT
# Dosyaya çalıştırma izni ver
chmod +x /etc/csf/csfpost.sh

# CSF'i yeniden başlat ve kuralların uygulandığını doğrula
csf -r
iptables -L DOCKER-USER -n -v

Pratik Senaryo: Web Uygulaması Stack’i

Gerçek bir senaryo üzerinden gidelim. Diyelim ki bir sunucuda şu yapıyı çalıştırıyorsun:

  • Nginx reverse proxy (port 80 ve 443)
  • Uygulama konteyner (port 3000, sadece iç ağdan erişilebilir)
  • PostgreSQL (port 5432, sadece iç ağdan erişilebilir)
  • Redis (port 6379, sadece iç ağdan erişilebilir)

Bu senaryoda sadece 80 ve 443 numaralı portların dışarıya açık olması gerekiyor. Diğer portlar Docker iç ağında kalmalı.

Önce Docker Compose ile ağ yapısını düzgün kur:

# docker-compose.yml
version: '3.8'

networks:
  frontend:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/24
  backend:
    driver: bridge
    internal: true
    ipam:
      config:
        - subnet: 172.21.0.0/24

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    networks:
      - frontend
      - backend

  app:
    image: myapp:latest
    networks:
      - backend
    # Port mapping YOK, sadece iç ağdan erişilir

  postgres:
    image: postgres:15
    networks:
      - backend
    # Port mapping YOK

  redis:
    image: redis:alpine
    networks:
      - backend
    # Port mapping YOK

internal: true ayarı olan ağlar dışarıya route edilmiyor. Bu sayede PostgreSQL ve Redis için ekstra iptables kuralına gerek kalmıyor. Ama Nginx’in bağlı olduğu frontend ağı için CSF tarafında gerekli izinlerin verilmesi lazım.

CSF tarafında bu senaryoyu desteklemek için /etc/csf/csf.conf dosyasında şunları yapıyorsun:

# Dışarıya açık portlar
TCP_IN = "22,80,443"
TCP_OUT = "80,443,53,43,21,20,25,587,465,110,995,143,993"

# Gerekirse UDP portları
UDP_IN = ""
UDP_OUT = "53"

Konteyner IP’lerini CSF ile Yönetmek

Konteynerler her başladığında IP adresi değişebiliyor. Bu durum whitelist veya izin kuralları yazarken sorun çıkarıyor. Bunu aşmak için iki yöntem var.

Birinci yöntem: Docker ağlarının tamamına izin vermek. csf.conf içinde DOCKER_NETWORK parametresine ilgili subnet’i eklemek genellikle yeterli oluyor.

İkinci yöntem: Konteynerlere statik IP atamak. Docker Compose ile bu oldukça kolay:

services:
  nginx:
    image: nginx:alpine
    networks:
      frontend:
        ipv4_address: 172.20.0.10
  
  app:
    image: myapp:latest
    networks:
      backend:
        ipv4_address: 172.21.0.10

Statik IP kullandığında CSF’e bu IP’leri özellikle tanıtabilirsin:

# /etc/csf/csf.allow dosyasına Docker konteyner IP'leri ekle
echo "172.20.0.10  # nginx konteyner" >> /etc/csf/csf.allow
echo "172.21.0.0/24  # backend network" >> /etc/csf/csf.allow

# Değişiklikleri uygula
csf -r

LFD ve Docker Log Kirliliği

CSF ile birlikte gelen LFD (Login Failure Daemon), Docker’ın iç ağ trafiğini bazen şüpheli aktivite olarak işaretleyebiliyor. Özellikle health check’ler veya yoğun iç trafik LFD loglarını gereksiz yere şişirebiliyor.

Bunu engellemek için Docker subnet’ini LFD’nin ignore listesine alman gerekiyor:

# /etc/csf/csf.ignore dosyasına Docker subnet ekle
echo "172.17.0.0/16" >> /etc/csf/csf.ignore
echo "172.18.0.0/16" >> /etc/csf/csf.ignore
echo "172.20.0.0/24" >> /etc/csf/csf.ignore

# Ayrıca csf.conf içinde IGNORE_ALLOW parametresini kontrol et
# IGNORE_ALLOW = "1" olmalı

LFD’nin Docker log dosyalarını parse etmesini de durdurabilirsin. /etc/csf/csf.conf içindeki LOGPATH parametresinden Docker log yollarını çıkarmak bu konuda yardımcı oluyor.

Kubernetes veya Swarm Ortamları için Ek Notlar

Docker Swarm kullanıyorsan tablo daha da karmaşıklaşıyor. Swarm kendi overlay ağlarını oluşturuyor ve ingress adında özel bir ağ ekliyor. Bu durumda ek subnet’lerin de tanımlanması gerekiyor:

# Swarm overlay ağ subnet'ini bul
docker network inspect ingress | grep Subnet

# csf.conf güncelle
# DOCKER_NETWORK = "172.17.0.0/16,10.0.0.0/8"

Swarm ortamında portlar 0.0.0.0 üzerinde dinleniyor ve Docker Swarm routing mesh devreye giriyor. Bu yapıda CSF kuralları yazarken özellikle dikkatli olman gerekiyor, zira kural yanlış yazılırsa tüm Swarm trafiği etkilenebiliyor.

# csfpost.sh içine Swarm için ek kurallar
#!/bin/bash

# Swarm overlay ağı için
iptables -I FORWARD -d 10.0.0.0/8 -j ACCEPT
iptables -I FORWARD -s 10.0.0.0/8 -j ACCEPT

# Swarm internal iletişim portları
iptables -I INPUT -p tcp --dport 2377 -j ACCEPT  # Cluster management
iptables -I INPUT -p tcp --dport 7946 -j ACCEPT  # Node communication
iptables -I INPUT -p udp --dport 7946 -j ACCEPT
iptables -I INPUT -p udp --dport 4789 -j ACCEPT  # Overlay network

Sorun Giderme

Yapılandırma sonrasında konteynerlere erişim sorunu yaşıyorsan şu adımları takip et:

# 1. CSF ve Docker kurallarının durumunu kontrol et
csf -l | grep DOCKER
iptables -L FORWARD -n -v

# 2. IP forward'ın aktif olduğunu doğrula
cat /proc/sys/net/ipv4/ip_forward
# 1 görmelisin

# 3. Gerekirse aktif et
echo 1 > /proc/sys/net/ipv4/ip_forward
# ve /etc/sysctl.conf içine ekle:
# net.ipv4.ip_forward = 1
sysctl -p

# 4. Docker ağ yapısını doğrula
docker network inspect bridge | grep -A5 "IPAM"

# 5. Konteyner içinden dışarı çıkışı test et
docker run --rm busybox ping -c3 8.8.8.8

# 6. CSF loglarını izle
tail -f /var/log/lfd.log | grep -i docker

En yaygın sorun IP forward’ın kapalı olması ya da FORWARD zincirindeki DROP politikası. CSF varsayılan olarak FORWARD politikasını DROP olarak ayarlıyor, Docker konteynerlerine olan yönlendirmeler için explicit ACCEPT kuralı eklenmesi şart.

Güvenlik Kontrol Listesi

Yapılandırmayı tamamladıktan sonra şu kontrolleri yapmalısın:

  • Port taraması yap: nmap -sT -p- sunucu_ip_adresi komutuyla açık portları doğrula. Sadece 80, 443 ve SSH portu görünmeli.
  • Konteyner iletişimini test et: Her konteynerin sadece gerekli servislere ulaşabildiğini doğrula.
  • CSF yeniden başlatma testi: csf -r sonrasında Docker konteynerlerinin çalışmaya devam ettiğini kontrol et. Bu test kritik, production’da bunu sıkça görmezden geliyorlar.
  • Reboot testi: Sunucu yeniden başlatıldıktan sonra hem CSF hem Docker kurallarının doğru uygulandığını doğrula.
  • Log temizliği: LFD’nin gereksiz uyarılar üretmediğinden emin ol.
# Hızlı güvenlik kontrolü
nmap -sT -O localhost
iptables -L -n | grep -c ACCEPT
iptables -L -n | grep -c DROP
docker ps --format "table {{.Names}}t{{.Ports}}"

Sonuç

CSF ile Docker’ı birlikte güvenli şekilde çalıştırmak karmaşık görünüyor ama doğru yapılandırmayla oldukça yönetilebilir bir hale geliyor. Temel prensip şu: Docker’ın iptables yönetimini tamamen devre dışı bırakmak yerine, DOCKER-USER zinciri üzerinden CSF kurallarıyla koordineli çalışmasını sağlamak en sağlıklı yaklaşım.

csfpost.sh dosyası bu entegrasyonun kalbi. CSF her yeniden başladığında bu dosyadaki kurallar tekrar uygulanıyor, böylece Docker kurallarının kaybolması ya da çakışması engellenmiş oluyor. Docker Compose tarafında ise internal: true ağlar ve statik IP atamaları güvenlik yönetimini önemli ölçüde kolaylaştırıyor.

Production ortamına geçmeden önce mutlaka test sunucusunda dene. Bir port ya da subnet gözden kaçtığında tüm konteyner ekosistemi erişilemez hale gelebiliyor. Ve her değişiklik sonrasında hem nmap taraması hem de csf -r testi yapmayı alışkanlık haline getir. Küçük bir kontrol rutini, gece yarısı erişim kopukluğu derdinden seni kurtarır.

Yorum yapın