iptables ile Gelişmiş Güvenlik Duvarı Kuralları

Sunucunu internete açtığın anda saat başlar. Botlar, tarayıcılar, brute-force denemeleri… Hepsi kapını çalmaya başlar. Bu noktada iptables, Linux’un en güçlü savunma araçlarından biri olarak devreye girer. Evet, firewalld var, ufw var, nftables var. Ama iptables’ı anlamadan bunların hiçbirini gerçek anlamda kontrol edemezsin. Bugün sadece temel kuralları değil, production ortamlarında gerçekten işe yarayan gelişmiş senaryoları konuşacağız.

iptables Mimarisini Anlamak

Önce zihinsel modeli kuralım. iptables üç ana kavram üzerine inşa edilmiş:

  • Tables (Tablolar): filter, nat, mangle, raw, security
  • Chains (Zincirler): INPUT, OUTPUT, FORWARD, PREROUTING, POSTROUTING
  • Rules (Kurallar): Paketlerin hangi aksiyona tabi tutulacağını belirler

Günlük işlerimizde çoğunlukla filter tablosunu kullanırız. NAT işlemleri için nat tablosu, paket başlıklarını manipüle etmek için mangle tablosu devreye girer.

Bir paket sunucuna geldiğinde şu yolu izler: PREROUTING -> INPUT (eğer bu makine hedefse) ya da PREROUTING -> FORWARD -> POSTROUTING (eğer routing yapılıyorsa). Bunu kafaya yerleştirirsen kural yazmak çok daha mantıklı gelmeye başlar.

Temel Kural Yapısı ve Sık Kullanılan Parametreler

Kural yazarken kullandığımız temel parametreler şunlar:

-A: Zincire kural ekler (append) -I: Zincirin başına kural ekler (insert) -D: Kural siler -L: Kuralları listeler -n: Sayısal çıktı (DNS çözümlemesi yapmaz, hızlı) -v: Verbose mod, paket/byte sayaçlarıyla -p: Protokol (tcp, udp, icmp) -s: Kaynak IP/subnet -d: Hedef IP/subnet –dport: Hedef port –sport: Kaynak port -j: Jump, yani kural eşleşirse ne yapılacak (ACCEPT, DROP, REJECT, LOG) -m: Modül kullan (state, multiport, recent, limit…)

Mevcut kuralları görmek için:

iptables -L -n -v --line-numbers
# NAT tablosunu görmek için:
iptables -t nat -L -n -v

Temiz Bir Başlangıç: Default Policy Stratejisi

Güvenlik duvarı tasarımında iki yaklaşım var: whitelist (her şeyi engelle, sadece izin verdiklerini geçir) ve blacklist (her şeye izin ver, sadece yasakladıklarını engelle). Production sunucular için whitelist yaklaşımı şart.

#!/bin/bash
# Tüm zincirleri temizle
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

# Default policy: her şeyi düşür
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Loopback arayüzüne izin ver (localhost trafiği)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Mevcut bağlantıları koru (established/related)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SSH erişimi (dikkat: önce bunu yaz, yoksa kilitlenirsin!)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Bu scripti çalıştırmadan önce consol erişiminin olduğundan emin ol. Remote sunucularda yanlış kural yazınca kendin kilitleyebilirsin.

Connection State Tracking ile Akıllı Kurallar

State modülü iptables’ın en değerli özelliklerinden biri. Stateless paket filtrelemesi yerine bağlantı durumunu takip ederek çok daha akıllı kararlar alabiliyorsun.

State değerleri:

  • NEW: Yeni bir bağlantı başlatma isteği
  • ESTABLISHED: Halihazırda kurulmuş bağlantı
  • RELATED: Mevcut bağlantıyla ilişkili yeni bağlantı (FTP data kanalı gibi)
  • INVALID: Geçersiz/tanımsız durum, bu paketleri hep düşür
# Invalid paketleri düşür, bunlar genellikle port scan veya saldırı belirtisi
iptables -A INPUT -m state --state INVALID -j DROP

# Sadece NEW ve ESTABLISHED SYN paketlerine izin ver
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

# FTP için related bağlantılara izin ver (passive FTP gerektirir)
modprobe nf_conntrack_ftp
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Port Knocking ile Gizli SSH Erişimi

Bu gerçek dünya senaryosu. SSH portunu tamamen kapatıp, belirli bir port dizisine “knock” yapan istemcilere açmak istiyorsun. Brute-force saldırılarını neredeyse sıfıra indiriyor.

# Port knocking için recent modülünü kullan
# Sequence: 7000, 8000, 9000 portlarına sırayla dokunulunca SSH açılır

# 7000 portuna dokunulunca listeye ekle
iptables -A INPUT -p tcp --dport 7000 -m recent --set --name KNOCK1 -j DROP

# 8000 portuna dokunulunca, KNOCK1 listesindeyse KNOCK2'ye ekle
iptables -A INPUT -p tcp --dport 8000 -m recent --rcheck --seconds 10 --name KNOCK1 
  -m recent --set --name KNOCK2 -j DROP

# 9000 portuna dokunulunca, KNOCK2 listesindeyse SSH'ı aç
iptables -A INPUT -p tcp --dport 9000 -m recent --rcheck --seconds 10 --name KNOCK2 
  -m recent --set --name KNOCK3 -j DROP

# KNOCK3 listesindeki IP'ye SSH izni ver (60 saniye geçerli)
iptables -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 60 --name KNOCK3 -j ACCEPT

İstemci tarafında knockd veya basit bir bash scriptiyle knock yapabilirsin:

# Basit knock scripti
for port in 7000 8000 9000; do
    nmap -Pn --host-timeout 201ms --max-retries 0 -p $port SUNUCU_IP > /dev/null 2>&1
    sleep 0.5
done
ssh kullanici@SUNUCU_IP

Rate Limiting ile Brute Force Koruması

recent ve limit modülleri birlikte kullanıldığında brute-force saldırılarına karşı çok etkili bir savunma oluşturuyor.

# SSH brute force koruması
# 60 saniyede 4'ten fazla bağlantı denemesi yapan IP'yi engelle
iptables -A INPUT -p tcp --dport 22 -m state --state NEW 
  -m recent --set --name SSH_BRUTEFORCE

iptables -A INPUT -p tcp --dport 22 -m state --state NEW 
  -m recent --update --seconds 60 --hitcount 4 --name SSH_BRUTEFORCE 
  -j LOG --log-prefix "SSH_BRUTEFORCE: " --log-level 4

iptables -A INPUT -p tcp --dport 22 -m state --state NEW 
  -m recent --update --seconds 60 --hitcount 4 --name SSH_BRUTEFORCE 
  -j DROP

# HTTP/HTTPS için connection limit
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 
  --connlimit-mask 32 -j REJECT --reject-with tcp-reset

iptables -A INPUT -p tcp --dport 443 -m connlimit --connlimit-above 50 
  --connlimit-mask 32 -j REJECT --reject-with tcp-reset

SYN Flood Koruması

DDoS saldırılarının klasiği. SYN paketlerini rate limiting ile sınırlamak temel önlem:

# SYN flood koruması
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

# Kernel seviyesinde de SYN cookies aktif et
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
echo 2048 > /proc/sys/net/ipv4/tcp_max_syn_backlog
echo 1 > /proc/sys/net/ipv4/tcp_synack_retries

# Kalıcı hale getirmek için sysctl.conf'a ekle
cat >> /etc/sysctl.conf << EOF
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
EOF
sysctl -p

Multiport ile Temiz Kural Yönetimi

Her port için ayrı kural yazmak yerine multiport modülü kullanmak hem performans hem okunabilirlik açısından iyi:

# Web sunucusu için
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# Belirli IP aralığından yönetim portlarına erişim
iptables -A INPUT -s 192.168.1.0/24 -p tcp 
  -m multiport --dports 22,3306,6379,27017 -j ACCEPT

# Mail sunucusu portları
iptables -A INPUT -p tcp -m multiport --dports 25,465,587,110,995,143,993 -j ACCEPT

# DNS
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT

ICMP Yönetimi

ICMP’yi tamamen kapatmak hata ayıklamayı zorlaştırır. Akıllıca yönetmek gerekiyor:

# ICMP kuralları - ping'e izin ver ama flood'u engelle
iptables -A INPUT -p icmp --icmp-type echo-request 
  -m limit --limit 1/s --limit-burst 5 -j ACCEPT

# Önemli ICMP tipleri
iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT

# Diğer tüm ICMP düşür
iptables -A INPUT -p icmp -j DROP

# Ping flood koruması için alternatif yaklaşım
iptables -A INPUT -p icmp --icmp-type echo-request 
  -m recent --set --name PING
iptables -A INPUT -p icmp --icmp-type echo-request 
  -m recent --update --seconds 1 --hitcount 10 --name PING -j DROP

Gelişmiş Logging ve Monitoring

Engellenen trafiği loglamak, saldırı örüntülerini anlamak için kritik. Ama her şeyi loglarsan disk dolar, log trafiğini de sınırla:

# Engellenen paketleri logla (rate limited)
iptables -A INPUT -m limit --limit 5/min --limit-burst 10 
  -j LOG --log-prefix "IPT_DROP: " --log-level 4

iptables -A INPUT -j DROP

# Özel bir logging chain oluştur
iptables -N LOGGING
iptables -A INPUT -j LOGGING
iptables -A LOGGING -m limit --limit 2/min 
  -j LOG --log-prefix "IPT_INPUT_DROP: " --log-level 7
iptables -A LOGGING -j DROP

# Log seviyelerini /etc/rsyslog.conf'ta ayarla
# kern.warning /var/log/iptables.log

# Sadece yeni bağlantıları logla (daha az gürültü)
iptables -A INPUT -m state --state NEW 
  -m limit --limit 1/min 
  -j LOG --log-prefix "NEW_CONN: " --log-level 4

Logları analiz etmek için:

# En çok drop edilen IP'ler
grep "IPT_DROP" /var/log/kern.log | 
  grep -oP 'SRC=K[d.]+' | sort | uniq -c | sort -rn | head -20

# Port taraması yapan IP'ler
grep "IPT_DROP" /var/log/kern.log | 
  grep -oP 'DPT=K[d]+' | sort | uniq -c | sort -rn | head -20

Kuralları Kalıcı Hale Getirmek

iptables kuralları sistem yeniden başlatınca sıfırlanır. Bunun için iki yöntem var:

# Mevcut kuralları kaydet
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

# Debian/Ubuntu için iptables-persistent
apt install iptables-persistent
# Yüklerken mevcut kuralları kaydetmek ister

# Manuel yükleme
iptables-restore < /etc/iptables/rules.v4

# systemd service ile
cat > /etc/systemd/system/iptables-restore.service << EOF
[Unit]
Description=Restore iptables rules
Before=network-pre.target
Wants=network-pre.target

[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables/rules.v4
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl enable iptables-restore
systemctl start iptables-restore

Web Sunucusu için Komple Güvenlik Duvarı Script’i

Tüm öğrendiklerimizi bir araya getiren gerçek dünya örneği. Nginx/Apache çalıştıran bir VPS için:

#!/bin/bash
# /etc/iptables/setup-firewall.sh
# Web Sunucusu Güvenlik Duvarı Kurulum Scripti

ADMIN_IP="203.0.113.10"  # Senin IP'n
WEB_PORTS="80,443"
SSH_PORT="22"

echo "[*] Kurallar temizleniyor..."
iptables -F && iptables -X && iptables -Z
iptables -t nat -F && iptables -t nat -X
iptables -t mangle -F && iptables -t mangle -X

echo "[*] Default policy ayarlanıyor..."
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

echo "[*] Temel kurallar ekleniyor..."
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP

echo "[*] SSH koruması ayarlanıyor..."
iptables -A INPUT -s $ADMIN_IP -p tcp --dport $SSH_PORT -j ACCEPT
iptables -A INPUT -p tcp --dport $SSH_PORT -m state --state NEW 
  -m recent --set --name SSH_BF
iptables -A INPUT -p tcp --dport $SSH_PORT -m state --state NEW 
  -m recent --update --seconds 60 --hitcount 3 --name SSH_BF 
  -j LOG --log-prefix "SSH_BF_DROP: "
iptables -A INPUT -p tcp --dport $SSH_PORT -m state --state NEW 
  -m recent --update --seconds 60 --hitcount 3 --name SSH_BF -j DROP

echo "[*] Web servisi kuralları ekleniyor..."
iptables -A INPUT -p tcp -m multiport --dports $WEB_PORTS 
  -m connlimit --connlimit-above 100 --connlimit-mask 32 -j DROP
iptables -A INPUT -p tcp -m multiport --dports $WEB_PORTS 
  -m state --state NEW -m limit --limit 30/s --limit-burst 50 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports $WEB_PORTS -j ACCEPT

echo "[*] SYN flood koruması..."
iptables -A INPUT -p tcp --syn -m limit --limit 2/s --limit-burst 6 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

echo "[*] ICMP yönetimi..."
iptables -A INPUT -p icmp --icmp-type echo-request 
  -m limit --limit 1/s -j ACCEPT
iptables -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A INPUT -p icmp -j DROP

echo "[*] Logging..."
iptables -A INPUT -m limit --limit 3/min 
  -j LOG --log-prefix "FW_DROP: " --log-level 4
iptables -A INPUT -j DROP

echo "[*] Kurallar kaydediliyor..."
iptables-save > /etc/iptables/rules.v4

echo "[+] Firewall kurulumu tamamlandi!"
iptables -L -n -v --line-numbers

Kuralları Test Etmek

Canlıya almadan önce test etmek şart:

# Geçici olarak uygula, 30 saniye sonra geri al
# (Kendinizi kilitlerseniz otomatik açılır)
iptables-save > /tmp/iptables-backup
iptables -F
# Yeni kuralları uygula...
# Test et...
# Sorun varsa geri dön:
iptables-restore < /tmp/iptables-backup

# at komutuyla otomatik geri alma (güvenlik ağı)
echo "iptables-restore < /tmp/iptables-backup" | at now + 5 minutes
# Test geçtiyse at job'ı iptal et:
atrm JOB_ID

# Kural sayısını ve hit'leri izle
watch -n 1 'iptables -L -n -v --line-numbers'

Sonuç

iptables öğrenme eğrisi dik görünüyor ama bir kez içselleştirince Linux ağ güvenliğinin tamamı anlam kazanıyor. Anlattığımız yapıyı takip edersen, whitelist yaklaşımı ile başla, state tracking kullan, brute-force korumasını ihmal etme, her şeyi logla ama akıllıca logla.

Gerçek ortamlarda birkaç şeyi aklında tut: Kurallar sırayla değerlendirilir, ilk eşleşen kural işler. Çok fazla kural performansı etkiler, bu yüzden nftables’a geçiş gündemine alınabilir. ipset modülü ile büyük IP listelerini çok daha verimli yönetebilirsin. Ve en önemlisi, her değişiklikten önce yedeğini al.

Firewall sadece bir araç. Güvenliği katmanlı düşünmek gerekiyor: iptables + fail2ban + intrusion detection + düzenli audit. Bu kombinasyon, sunucunu gerçek anlamda korur. Bir sonraki yazıda fail2ban’ı iptables ile entegre etmeyi ve otomatik IP engelleme sistemleri kurmayı ele alacağız.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir