sunucu.com.tr
Güvenlik

Docker UFW sorunu: Ubuntu 24.04'te açık kalan konteyner portlarını DOCKER-USER zinciri ve ufw-docker ile kapatma

Docker UFW sorunu yüzünden ufw status aktif görünürken MySQL, Redis ya da panel portları internete açık kalabilir. Nedenini paket yolu üzerinden görün, sunucunuzu dışarıdan test edin. Sonra portları 127.0.0.1 bağlaması, kalıcı DOCKER-USER kuralları ya da ufw-docker yöntemiyle kapatın.

sunucu.com.tr Ekibi13 dk okuma

Ubuntu sunucunuzda ufw status "active" diyor, 3306 için bir kural da yok. Yine de MySQL konteynerinize internetten bağlanılabiliyor. Bilinen docker ufw sorunu budur: Docker'ın yayınladığı portlar UFW kurallarından hiç geçmez. Bu rehber, Ubuntu 24.04 üzerinde Docker çalıştıran sistem yöneticileri ve KOBİ geliştiricileri için hazırlandı. Önce sorunun nereden çıktığına bakacağız. Ardından sunucunuzu dışarıdan test edip portları üç farklı yöntemle kalıcı olarak kapatacağız.

Docker UFW sorunu nedir: ufw status aktif derken portlar neden açık?

UFW, iptables'ın (Ubuntu 24.04'te iptables-nft arka ucu) üzerinde çalışan bir ön yüzdür. ufw allow ya da ufw deny ile yazdığınız kurallar çoğunlukla INPUT zincirine uygulanır, yani sunucunun kendisine gelen trafiğe.

docker run -p 3306:3306 çalıştırdığınızda Docker kendi iptables kurallarını ekler. Bu kurallar, UFW'nin hiç bakmadığı bir yoldan işler. Bu yüzden ufw deny 3306 yazsanız bile port açık kalır. Bu bir Docker hatası değil. Docker'ın ağ modeli böyle tasarlandı ve resmi belgelerde de açıkça anlatılıyor: Docker ve paket filtreleme belgesi.

Sorun özellikle şu durumlarda tehlikelidir:

  • Compose dosyasında ports: - "3306:3306" ya da "6379:6379" gibi veritabanı ve önbellek portları
  • Yönetim panelleri (Portainer, phpMyAdmin, Adminer) ve geliştirme arayüzleri
  • "Bu portu benden başkası bilmez" düşüncesiyle standart dışı bir porta taşınmış servisler

Paket yolu: PREROUTING DNAT, FORWARD zinciri ve UFW'nin INPUT'a bakması

Dışarıdan 192.0.2.10:3306 adresine gelen bir paket şu yolu izler:

  1. nat tablosu, PREROUTING: Docker'ın DOCKER zincirindeki DNAT kuralı, hedef adresi konteynerin iç adresiyle değiştirir (ör. 172.17.0.2:3306).
  2. Yönlendirme kararı: Hedef artık sunucunun kendisi değil, bir köprü arayüzünün arkasındaki konteyner. Bu yüzden paket INPUT yerine FORWARD zincirine gider.
  3. filter tablosu, FORWARD: Paketi Docker'ın kuralları kabul eder. UFW'nin ufw-user-input zincirindeki kurallar burada devreye girmez.

Buradan iki önemli sonuç çıkar:

  • Filtreleme yapmak istiyorsanız FORWARD zincirinde, Docker'ın kendi kurallarından önce araya girmeniz gerekir. Docker bunun için DOCKER-USER zincirini ayırır ve FORWARD'da ilk sıraya koyar.
  • DNAT'tan sonra paketin hedef portu artık konteyner portudur. -p 8080:80 ile yayınlanan bir serviste FORWARD zincirinde --dport 8080 eşleşmez, 80 eşleşir. Yayınlanan host portuna göre süzmek için conntrack modülünün --ctorigdstport seçeneği kullanılır.

Sunucunuzu test edin: açık konteyner portlarını bulma

Önce sunucunun içinden hangi portların tüm arayüzlere yayınlandığına bakın. Aşağıdaki betik yalnızca okuma yapar, hiçbir ayarı değiştirmez. Ubuntu 24.04 ve Debian 12 için hazırlandı. Geri alınacak bir şey yok.

bash
#!/usr/bin/env bash
# docker-port-denetimi.sh
# Tüm arayüzlere (0.0.0.0 ve [::]) yayınlanmış konteyner portlarını listeler.
# Yalnızca okuma yapar. sudo ile çalıştırın.
set -euo pipefail

echo "== Tüm arayüzlere yayınlanmış konteyner portları =="
# 127.0.0.1 ile bağlanan portlar bu listede çıkmaz, çıkması gereken de onlar değil.
docker ps --format '{{.Names}}\t{{.Ports}}' \
  | grep -E '0\.0\.0\.0:|\[::\]:|:::' \
  || echo "Tüm arayüzlere yayınlanmış port bulunamadı."

echo
echo "== UFW durumu =="
ufw status verbose || true

echo
echo "== Docker DNAT kuralları (nat tablosu) =="
iptables -t nat -L DOCKER -n 2>/dev/null | grep DNAT || echo "IPv4 DNAT kuralı yok."

echo
echo "== DOCKER-USER zincirinin mevcut içeriği =="
iptables -L DOCKER-USER -n -v --line-numbers 2>/dev/null || echo "DOCKER-USER zinciri yok."

Asıl kanıt dışarıdan yapılan testtir. Sunucuyla aynı ağda olmayan bir makineden nmap çalıştırın. Bu, evdeki bilgisayarınız ya da başka bir sunucu olabilir:

bash
# Sık kullanılan konteyner portlarını hızlıca tarar
nmap -Pn -sT -p 3306,5432,6379,8080,9000,9443,27017 192.0.2.10

# Tüm TCP portları (daha uzun sürer)
nmap -Pn -sT -p- 192.0.2.10

Kapatmak istediğiniz bir port open görünüyorsa aynı sorun sizde de var. Düzgün korunan bir port filtered görünür. Taramayı yalnızca kendi sunucunuza yapın.

Çözüm 1: Portları 127.0.0.1'e bağlama

En basit ve en sağlam yöntem, dışarıya açılması gerekmeyen portları dış arayüze hiç yayınlamamaktır. Aynı sunucudaki Nginx, uygulama ya da SSH tüneli bu portlara yine erişebilir.

bash
# Yanlış: tüm arayüzlere, IPv4 ve IPv6'ya yayınlar
# docker run -d --name ORNEK_MYSQL -p 3306:3306 mysql:8

# Doğru: yalnız yerel döngü arayüzüne yayınlar
docker run -d --name ORNEK_MYSQL -p 127.0.0.1:3306:3306 \
  -e MYSQL_ROOT_PASSWORD=ORNEK_PAROLA mysql:8

Compose dosyasında da mantık aynı:

yaml
services:
  db:
    image: mysql:8
    ports:
      - "127.0.0.1:3306:3306"   # yalnız yerelden erişim
  redis:
    image: redis:7
    # Yalnız diğer konteynerler kullanıyorsa ports hiç yazmayın;
    # aynı Compose ağındaki servisler redis:6379 adıyla erişir.

Konteynerlerin birbiriyle konuşması için port yayınlamanız gerekmez. Uygulama konteyneriniz veritabanına servis adıyla (db:3306) bağlanabilir. Port yayınlamak yalnız host'tan ya da dışarıdan erişim için gerekir.

Tüm yeni yayınların varsayılan olarak yerele bağlanmasını isterseniz /etc/docker/daemon.json dosyasına "ip": "127.0.0.1" ekleyebilirsiniz. Bundan sonra dışarı açılması gereken portları (ör. 80 ve 443) açıkça 0.0.0.0:80:80 biçiminde yazmanız gerekir. Değişikliği sudo systemctl restart docker ile uygularsınız ve bu sırada konteynerler yeniden başlar, o yüzden bakım penceresinde yapın. Geri almak için satırı silip Docker'ı yeniden başlatmanız yeterli.

Bu yöntemin tek zayıf yanı insan hatasına açık olmasıdır. Yeni eklenen bir Compose dosyasında 127.0.0.1 unutulursa port yine açılır. Bu yüzden ikinci bir katman olarak DOCKER-USER kurallarını öneriyoruz.

Çözüm 2: DOCKER-USER zincirinde izinli IP ve conntrack kuralları

Bu yöntemde dış arayüzden konteynerlere gelen yeni bağlantıların hepsi varsayılan olarak düşürülür. Yalnız açık kalmasını istediğiniz portlar ve güvendiğiniz IP blokları geçer. Kurallar yalnız FORWARD trafiğini etkiler. Sunucunun kendi SSH portu INPUT zincirinde olduğu için bu betik SSH bağlantınızı kesmez. Yine de güvenlik duvarıyla çalışırken kendinizi kilitleme riskini her zaman hesaba katın ve sağlayıcınızın web konsoluna (VNC ya da seri konsol) erişebildiğinizden emin olun.

Aşağıdaki betik, Ubuntu 24.04 ve Debian 12 üzerindeki Docker Engine için hazırlandı. Her çalıştığında DOCKER-USER zincirini boşaltıp baştan doldurur, bu yüzden idempotenttir: kaç kez çalıştırırsanız çalıştırın sonuç aynı olur. Değiştirmeniz gereken değerler en üstte.

bash
#!/usr/bin/env bash
# /usr/local/sbin/docker-user-kurallari.sh
# DOCKER-USER zincirinde: dış arayüzden konteynerlere gelen yeni bağlantıları
# varsayılan olarak düşürür, yalnız izinli portları ve kaynakları geçirir.
set -euo pipefail

# ---- DEĞİŞTİRİLECEK DEĞERLER ----
DIS_ARAYUZ="ORNEK_ARAYUZ"              # ip -br link çıktısındaki dış arayüz, ör. eth0 ya da ens3
ACIK_TCP_PORTLARI="80 443"             # Herkese açık YAYINLANAN host portları (8080:80 ise 8080 yazın)
IZINLI_KAYNAKLAR_V4="198.51.100.0/24"  # Tüm konteyner portlarına erişebilecek ofis/VPN ağları, boş olabilir
IZINLI_KAYNAKLAR_V6=""                 # IPv6 için aynı mantık, boş olabilir
# ---------------------------------

if ! ip link show "$DIS_ARAYUZ" >/dev/null 2>&1; then
  echo "Hata: $DIS_ARAYUZ arayüzü bulunamadı." >&2
  exit 1
fi

kurallari_uygula() {
  local komut="$1"       # iptables ya da ip6tables
  local kaynaklar="$2"

  # Zincir yoksa (Docker henüz başlamadıysa ya da IPv6 kapalıysa) atla
  if ! "$komut" -n -L DOCKER-USER >/dev/null 2>&1; then
    echo "$komut: DOCKER-USER zinciri yok, atlanıyor."
    return 0
  fi

  # Zinciri boşalt: betik her çalıştığında aynı sonucu üretir
  "$komut" -F DOCKER-USER

  # 1) Konteynerlerin dışarı açtığı bağlantılara gelen yanıtlar
  "$komut" -A DOCKER-USER -i "$DIS_ARAYUZ" -m conntrack --ctstate RELATED,ESTABLISHED -j RETURN

  # 2) Güvenilen kaynaklar tüm yayınlanmış portlara erişebilir
  for kaynak in $kaynaklar; do
    "$komut" -A DOCKER-USER -i "$DIS_ARAYUZ" -s "$kaynak" -j RETURN
  done

  # 3) Herkese açık portlar: DNAT öncesi hedef porta (host portu) göre eşleştir
  for port in $ACIK_TCP_PORTLARI; do
    "$komut" -A DOCKER-USER -i "$DIS_ARAYUZ" -p tcp \
      -m conntrack --ctorigdstport "$port" --ctdir ORIGINAL -j RETURN
  done

  # 4) Dış arayüzden gelen diğer her şeyi düşür
  "$komut" -A DOCKER-USER -i "$DIS_ARAYUZ" -j DROP

  # 5) Diğer arayüzlerden gelen trafik (konteynerler arası, dışa çıkış) Docker'a devam eder
  "$komut" -A DOCKER-USER -j RETURN

  echo "$komut: DOCKER-USER kuralları uygulandı."
}

kurallari_uygula iptables  "$IZINLI_KAYNAKLAR_V4"
kurallari_uygula ip6tables "$IZINLI_KAYNAKLAR_V6"

Kuralların sırası önemli. RELATED,ESTABLISHED satırı en üstte olmazsa konteynerleriniz dışarıya (paket deposu, API, SMTP) bağlanır ama yanıtlar düşürülür. Sonuçta konteyner içinde apt update takılır. -i ile dış arayüzü belirtmek de bilinçli bir tercih. Böylece konteynerden çıkan trafik ve köprü ağları arasındaki trafik kurala takılmaz.

Kuralları kalıcı hale getirme

iptables ile eklenen kurallar yeniden başlatmada kaybolur. Docker başlarken DOCKER-USER zincirini yeniden oluşturabilir. Bu yüzden iptables-persistent ile kayıt almak yerine Docker'a bağlı küçük bir systemd birimi kullanmak daha güvenilirdir. Aşağıdaki kurulum betiği Ubuntu 24.04 için hazırlandı ve tekrar tekrar çalıştırılabilir.

bash
#!/usr/bin/env bash
# DOCKER-USER betiğini Docker ile birlikte başlayan bir systemd birimine bağlar.
set -euo pipefail

# Betiğin yerinde ve çalıştırılabilir olduğunu doğrula
sudo chmod 750 /usr/local/sbin/docker-user-kurallari.sh

sudo tee /etc/systemd/system/docker-user-kurallari.service >/dev/null <<'EOF'
[Unit]
Description=DOCKER-USER guvenlik duvari kurallari
After=docker.service
PartOf=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/docker-user-kurallari.sh
# Durdurulunca zinciri boşalt; IPv6 zinciri yoksa hata yok sayılır
ExecStop=-/usr/sbin/iptables -F DOCKER-USER
ExecStop=-/usr/sbin/ip6tables -F DOCKER-USER

[Install]
WantedBy=docker.service
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now docker-user-kurallari.service
sudo systemctl status docker-user-kurallari.service --no-pager

PartOf ve WantedBy=docker.service sayesinde Docker yeniden başladığında birim de yeniden çalışır. Geri alma: sudo systemctl disable --now docker-user-kurallari.service birimi kapatır ve zinciri boşaltır. Ardından /etc/systemd/system/docker-user-kurallari.service dosyasını kaldırıp sudo systemctl daemon-reload çalıştırabilirsiniz.

Çözüm 3: /etc/ufw/after.rules ve ufw-docker yöntemiyle ufw route kuralları

Kuralları tek yerden, UFW komutlarıyla yönetmek istiyorsanız bu yöntem daha rahattır. Açık kaynak ufw-docker aracının ufw-docker install komutu, /etc/ufw/after.rules dosyasına bir blok ekler. Bu blok DOCKER-USER zincirini UFW'nin ufw-user-forward zincirine yönlendirir. Böylece ufw route allow ile yazdığınız kurallar konteyner trafiğine de uygulanır. Aşağıda aynı bloğu araç kullanmadan, elle ve kontrollü biçimde ekliyoruz. Aracı kullanmayı tercih ederseniz projenin kendi deposundan indirin ve çalıştırmadan önce içeriğini okuyun.

Kendinizi kilitlememek için: UFW henüz etkin değilse ufw enable çalıştırmadan önce mutlaka SSH'a izin verin. Aksi halde mevcut oturumunuz kesilebilir ve sunucuya yalnız sağlayıcının konsolundan ulaşabilirsiniz. Değişikliğe başlamadan önce konsol erişiminizi kontrol edin.

Aşağıdaki betik Ubuntu 24.04 ve UFW için hazırlandı. Blok zaten varsa tekrar eklemez, bu yüzden tekrar çalıştırmak güvenlidir.

bash
#!/usr/bin/env bash
set -euo pipefail

# 1) SSH'a izin ver (kilitlenmeyi önler). Farklı port kullanıyorsanız: sudo ufw allow 2222/tcp
sudo ufw allow OpenSSH

# 2) after.rules dosyasını bir kez yedekle (-n: yedek varsa üzerine yazmaz)
sudo cp -n /etc/ufw/after.rules /etc/ufw/after.rules.yedek

# 3) Blok yoksa dosyanın sonuna ekle (idempotent)
if ! sudo grep -q '# BEGIN UFW AND DOCKER' /etc/ufw/after.rules; then
  sudo tee -a /etc/ufw/after.rules >/dev/null <<'EOF'

# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-docker-logging-deny - [0:0]
:DOCKER-USER - [0:0]
# Önce ufw route kurallarına bak
-A DOCKER-USER -j ufw-user-forward

# Özel ağlardan gelen trafik (konteynerler arası, yerel ağ) serbest
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16

# Konteynerlerin DNS yanıtları
-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN

# Dışarıdan konteyner ağlarına yeni TCP bağlantılarını ve düşük UDP portlarını engelle
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12

-A DOCKER-USER -j RETURN

# Engellenen paketleri sınırlı sayıda günlüğe yaz, sonra düşür
-A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] "
-A ufw-docker-logging-deny -j DROP

COMMIT
# END UFW AND DOCKER
EOF
fi

# 4) UFW'yi etkinleştir ve kuralları yeniden yükle
sudo ufw enable
sudo systemctl restart ufw

Bu bloktan sonra dış dünyadan konteynerlere gelen yeni bağlantılar varsayılan olarak kapalıdır. Erişim açmak için ufw route kullanın:

bash
# DİKKAT: burada KONTEYNER portu yazılır (8080:80 ise 80)
sudo ufw route allow proto tcp from any to any port 443
sudo ufw route allow proto tcp from any to any port 80

# Veritabanını yalnız ofis ağına aç
sudo ufw route allow proto tcp from 198.51.100.0/24 to any port 3306

# ufw-docker aracı kuruluysa konteyner adıyla da izin verilebilir:
# sudo ufw-docker allow ORNEK_WEB 80

sudo ufw status numbered

ufw route kuralları DNAT'tan sonra değerlendirilir, bu yüzden port numarası konteynerin iç portudur. Çözüm 2'deki betik ise host portuna bakar. Karışıklığın en sık nedeni bu farktır.

Geri alma: sudo cp /etc/ufw/after.rules.yedek /etc/ufw/after.rules ve ardından sudo systemctl restart ufw. Eklediğiniz route kurallarını sudo ufw status numbered ile görüp sudo ufw delete NUMARA ile silebilirsiniz.

Çözüm 2 ile Çözüm 3'ü aynı sunucuda birlikte kullanmayın. İkisi de DOCKER-USER zincirini yönetir ve birbirinin kurallarını ezebilir. Tek bir yöntem seçin.

Docker sürümleri ve IPv6 notu

Docker'ın iptables düzeni sürümler arasında değişebiliyor. Docker 28 serisinde FORWARD zincirinin yapısı yeniden düzenlendi ve yeni ara zincirler eklendi. Belgelere göre DOCKER-USER, Docker'ın kendi kurallarından önce işlenen kullanıcı zinciri olmaya devam ediyor. Yine de her büyük sürüm yükseltmesinden sonra şu komutla sırayı kontrol edin:

bash
sudo iptables -L FORWARD -n --line-numbers | head -n 5

İlk satırlarda DOCKER-USER hedefini görmelisiniz. Sürpriz yaşamamanın en kolay yolu, yükseltmeden önce değişiklik notlarını okumaktır.

IPv6 ayrı bir konu. Sunucunuzun genel bir IPv6 adresi varsa ve Docker'da IPv6 etkinse, -p 3306:3306 portu [::] üzerinden de yayınlar. Güncel Docker sürümleri ip6tables kurallarını varsayılan olarak yönetiyor. Bu yüzden Çözüm 2'deki betik aynı kuralları ip6tables ile de uyguluyor. nmap testini IPv6 adresinize de yapın (nmap -6 -Pn -sT -p 3306 2001:db8::10). 127.0.0.1 bağlaması ise yalnız IPv4 yerel adresine yayınladığı için IPv6 tarafını da kendiliğinden kapatır.

Doğrulama

Hangi yöntemi seçerseniz seçin, işi bitti saymadan önce şu kontrolleri yapın:

  1. Dış bir makineden nmap -Pn -sT -p 3306,6379,80,443 192.0.2.10 çalıştırın. Açık kalması gereken portlar open, diğerleri filtered görünmeli.
  2. İzinli ofis IP'sinden veritabanına bağlanmayı deneyin.
  3. Konteynerin dışarı çıkabildiğini doğrulayın: docker exec ORNEK_WEB getent hosts example.com.
  4. Sunucuyu yeniden başlatıp 1. adımı tekrarlayın. Kalıcılık sorunları genelde ancak bu testte ortaya çıkar.
  5. Kural sayaçlarını izleyin: sudo iptables -L DOCKER-USER -n -v. DROP satırındaki paket sayısı artıyorsa kural çalışıyor demektir.

Sık yapılan hatalar

"iptables": false ayarı. İnternette sık önerilir ama Docker'ın ağ kurallarını tamamen kapatır. Konteynerler dışarı çıkamaz, yayınlanan portlar çalışmaz, NAT kurallarını elle yazmanız gerekir. Belgeler de bu ayarı çoğu kurulum için önermiyor.

Yeniden başlatmada kaybolan kurallar. Komut satırından eklenen DOCKER-USER kuralları sunucu yeniden açılınca kaybolur. systemd birimi ya da after.rules kullanın.

Yanıt trafiğini unutmak. DROP kuralını RELATED,ESTABLISHED satırı olmadan ve arayüz belirtmeden yazarsanız konteynerlerin giden bağlantıları kırılır.

Yanlış port numarası. FORWARD zincirinde --dport konteyner portudur. Host portuna göre süzmek için --ctorigdstport gerekir.

ufw deny 3306 ile yetinmek. Bu kural INPUT zincirine yazılır ve Docker trafiğini etkilemez.

Ana makinede yönlendirme yapan başka servisler. Aynı sunucuda LXC, KVM ya da WireGuard gibi dış arayüzden yönlendirme yapan servisler varsa DROP kuralı onları da etkileyebilir. Böyle bir durumda kuralları bu ağlar için ayrıca düzenleyin.

Portları kapattıktan sonra SSH tarafını da sıkılaştırmak isterseniz OpenSSH yamalı sürüm doğrulama ve sshd_config sertleştirme yazısına göz atabilirsiniz. Ollama gibi bir API'yi Docker'da çalıştırıyorsanız Ollama API'sini internete açmadan uzaktan erişim rehberi aynı sorunu Nginx ters vekille birlikte ele alıyor.

Sık sorulan sorular

Docker UFW sorunu yalnız Ubuntu'da mı var?

Hayır. Docker, iptables kullanan her dağıtımda yayınlanan portları FORWARD zincirinden geçirir. Debian, Rocky Linux ve AlmaLinux'ta da aynı mantık geçerlidir. firewalld kullanan sistemlerde Docker kendi bölgesini oluşturur. Oradaki yöntem farklı olduğu için ayrıca incelenmelidir.

Sunucu sağlayıcımın ağ güvenlik duvarı yeterli olmaz mı?

Sağlayıcı panelindeki ağ güvenlik duvarı trafik sunucuya ulaşmadan önce çalışır ve Docker'dan etkilenmez, yani iyi bir ek katmandır. Yine de sunucu üzerindeki kuralları korumak gerekir. Panelde yapılan bir hata ya da yeni bir sunucuya taşıma, portları yeniden açabilir. En güvenli yol iki katmanı birlikte kullanmaktır.

Reverse proxy kullanıyorum, yine de bu ayarlar gerekli mi?

Nginx ya da Traefik yalnız 80 ve 443'ü açıyor olsa bile, arka uç konteynerlerin portları ports: ile yayınlanmışsa bunlara dışarıdan doğrudan erişilebilir. Arka uçları ya hiç yayınlamayın ya da 127.0.0.1 üzerine yayınlayın. Ek güvence için DOCKER-USER kurallarını da ekleyin.

Rootless Docker'da da aynı sorun var mı?

Rootless kipte Docker iptables kurallarını değiştiremez. Port yayını kullanıcı alanındaki bir ağ yığınıyla yapılır ve trafik normal INPUT yolundan geçer. Bu yüzden UFW kuralları genellikle çalışır. Yine de dışarıdan nmap testi yapmadan bundan emin olmayın.

Hangi yöntemi seçmeliyim?

Tek sunuculu, az servisli kurulumlarda en sade sonucu 127.0.0.1 bağlaması ile DOCKER-USER betiği birlikte verir. Kuralları ekipteki herkesin bildiği ufw komutlarıyla yönetmek istiyorsanız after.rules ve ufw-docker yöntemi daha rahattır.

Sonuç

Docker'ın UFW'yi atlaması bir yapılandırma hatası değil, paket yolunun doğal sonucu. Çözüm de katmanlı olmalı. Gerekmeyen portları dışarıya hiç yayınlamayın. Kalanları DOCKER-USER zincirinde ya da after.rules ile süzün. IPv6'yı unutmayın ve her değişiklikten sonra dışarıdan test edin. Konteynerlerinizi temiz bir ortamda baştan kurmak isterseniz aynı adımları bir bulut sunucu üzerinde de uygulayabilirsiniz.

  • #docker
  • #ufw
  • #iptables
  • #ubuntu 24.04
  • #güvenlik duvarı
  • #docker-user
  • #ufw-docker

İlgili yazılar

Güvenlik yazıları