iptables ile Çoklu WAN ve Yük Dengeleme

Birden fazla internet bağlantısı yönetmek, özellikle küçük ve orta ölçekli işletmelerde hem bant genişliği optimizasyonu hem de yüksek erişilebilirlik açısından kritik bir ihtiyaç haline geldi. iptables bu işi yapmak için her ne kadar tek başına yeterli olmasa da, iproute2 araçlarıyla birlikte çalıştığında gerçekten güçlü bir çoklu WAN çözümü ortaya çıkıyor. Bu yazıda sıfırdan bir çoklu WAN yapısı kuracak, yük dengelemeyi devreye alacak ve en sık karşılaşılan sorunları nasıl çözeceğini göreceğiz.

Temel Kavramlar ve Senaryo

Önce ne yapmak istediğimizi netleştirelim. Elimizde şu ortam var:

  • eth0: LAN arayüzü, 192.168.1.1/24
  • eth1: ISP-1 (Türk Telekom fiber), 203.0.113.2/30, gateway 203.0.113.1
  • eth2: ISP-2 (kablo internet), 198.51.100.2/30, gateway 198.51.100.1

Hedefimiz:

  • Gelen trafiği her iki bağlantı üzerinden dengelemek
  • Bir bağlantı düştüğünde otomatik olarak diğerine geçmek
  • Belirli servisleri (örneğin VoIP) hep aynı bağlantı üzerinden göndermek
  • NAT ve firewall kurallarını doğru şekilde uygulamak

Linux çekirdeğinin yük dengeleme mekanizması iptables’tan değil, ip route komutunun nexthop özelliğinden gelir. iptables ise bu yapının üstüne NAT, MARK ve politika tabanlı yönlendirme kurallarını ekler. İkisi birlikte çalışınca gerçek bir kurumsal çözüm elde ediyoruz.

Sistem Hazırlığı

Önce gerekli modüllerin yüklü olduğunu kontrol edelim:

# Gerekli kernel modüllerini yükle
modprobe ip_tables
modprobe iptable_nat
modprobe ip_conntrack
modprobe xt_mark
modprobe xt_multiport

# Modüllerin yüklü olduğunu doğrula
lsmod | grep -E "ip_tables|xt_mark|ip_conntrack"

# IP forwarding'i etkinleştir
echo 1 > /proc/sys/net/ipv4/ip_forward

# Kalıcı hale getir
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.rp_filter = 0" >> /etc/sysctl.conf
echo "net.ipv4.conf.eth1.rp_filter = 0" >> /etc/sysctl.conf
echo "net.ipv4.conf.eth2.rp_filter = 0" >> /etc/sysctl.conf
sysctl -p

rp_filter’ı neden kapatıyoruz? Reverse path filtering, bir paketi aldığı arayüzden yanıt verilmesini bekler. Çoklu WAN’da paket eth1’den gelip eth2’den çıkabilir, bu durum rp_filter açıkken paketlerin düşürülmesine yol açar.

iproute2 ile Politika Tabanlı Yönlendirme

Bu adım iptables ile birlikte çalışacak olan yönlendirme tablolarını kurar. Linux’ta 255 ayrı yönlendirme tablosu tanımlayabilirsiniz.

# /etc/iproute2/rt_tables dosyasına özel tablolar ekle
echo "100 isp1" >> /etc/iproute2/rt_tables
echo "200 isp2" >> /etc/iproute2/rt_tables

# ISP-1 tablosunu yapılandır
ip route add 203.0.113.0/30 dev eth1 src 203.0.113.2 table isp1
ip route add default via 203.0.113.1 table isp1

# ISP-2 tablosunu yapılandır
ip route add 198.51.100.0/30 dev eth2 src 198.51.100.2 table isp2
ip route add default via 198.51.100.1 table isp2

# Ana yönlendirme tablosuna her iki ISP rotasını ekle
ip route add 203.0.113.0/30 dev eth1 src 203.0.113.2
ip route add 198.51.100.0/30 dev eth2 src 198.51.100.2

# Yük dengeleme için multipath default route
# weight değerleri bant genişliğine göre ayarlanabilir
ip route add default 
    nexthop via 203.0.113.1 dev eth1 weight 1 
    nexthop via 198.51.100.1 dev eth2 weight 1

Buradaki weight parametresi önemli. 100 Mbps fiber ve 50 Mbps kablo bağlantın varsa weight değerlerini sırasıyla 2 ve 1 yaparak bant genişliğiyle orantılı dağıtım sağlayabilirsin.

Politika Kuralları (ip rule)

Kaynak IP’ye göre hangi tablonun kullanılacağını belirleyen kurallar:

# ISP-1 IP'sinden gelen yanıtlar ISP-1 üzerinden gitsin
ip rule add from 203.0.113.2 table isp1 priority 100
ip rule add from 198.51.100.2 table isp2 priority 200

# Firewall mark'larına göre yönlendirme (sonraki adımda iptables ile entegre)
ip rule add fwmark 0x1 table isp1 priority 300
ip rule add fwmark 0x2 table isp2 priority 400

# Kuralları listele
ip rule show

iptables NAT Kuralları

Şimdi asıl kritik kısma geliyoruz. Her iki arayüz için ayrı NAT kuralları tanımlamalıyız:

#!/bin/bash
# /etc/firewall/multiwan.sh

# Değişkenler
LAN_IF="eth0"
ISP1_IF="eth1"
ISP2_IF="eth2"
LAN_NET="192.168.1.0/24"
ISP1_IP="203.0.113.2"
ISP2_IP="198.51.100.2"
ISP1_GW="203.0.113.1"
ISP2_GW="198.51.100.1"

# Mevcut kuralları temizle
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X
iptables -t nat -X
iptables -t mangle -X

# Default politikalar
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Loopback trafiğine izin ver
iptables -A INPUT -i lo -j ACCEPT

# Established/related bağlantılara izin ver
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# LAN'dan WAN'a yönlendirme
iptables -A FORWARD -i $LAN_IF -o $ISP1_IF -j ACCEPT
iptables -A FORWARD -i $LAN_IF -o $ISP2_IF -j ACCEPT

# ISP-1 üzerinden NAT (MASQUERADE yerine SNAT daha verimli çalışır)
iptables -t nat -A POSTROUTING -o $ISP1_IF -j SNAT --to-source $ISP1_IP
iptables -t nat -A POSTROUTING -o $ISP2_IF -j SNAT --to-source $ISP2_IP

echo "NAT kuralları uygulandı"

MASQUERADE ile SNAT arasındaki fark: MASQUERADE her paket için arayüzün IP’sini dinamik olarak sorgular. SNAT sabit IP belirttiği için çok daha hızlı çalışır. Statik IP adresleriniz varsa her zaman SNAT tercih edin.

Mangle Tablosu ile Trafik İşaretleme

Bu bölüm gerçek sihrin yaşandığı yer. mangle tablosu paketleri işaretleyerek iproute2’nin onları doğru tabloya yönlendirmesini sağlar:

# mangle tablosu kuralları - aynı script içine ekle

# Bağlantı takibi ile mevcut oturumları koru
# Bir bağlantı hangi ISP üzerinden başladıysa orada kalsın
iptables -t mangle -A PREROUTING -m conntrack --ctstate ESTABLISHED,RELATED 
    -j CONNMARK --restore-mark

# Yeni bağlantıları yük dengeleme için işaretle
# Statistic modülü ile round-robin dağıtım
iptables -t mangle -A PREROUTING -i $LAN_IF 
    -m conntrack --ctstate NEW 
    -m statistic --mode nth --every 2 --packet 0 
    -j MARK --set-mark 0x1

iptables -t mangle -A PREROUTING -i $LAN_IF 
    -m conntrack --ctstate NEW 
    -m mark --mark 0x0 
    -j MARK --set-mark 0x2

# Mark'ları bağlantıya kaydet (sonraki paketlere de uygulanması için)
iptables -t mangle -A PREROUTING -i $LAN_IF 
    -m conntrack --ctstate NEW 
    -j CONNMARK --save-mark

echo "Mangle kuralları uygulandı"

Servis Bazlı Yönlendirme

Gerçek dünya senaryolarında bazı servislerin hep aynı bağlantıdan gitmesi gerekir. Örneğin VoIP için düşük gecikmeli bağlantıyı, büyük dosya transferleri için yüksek bantlı bağlantıyı kullanmak:

# VoIP trafiğini (SIP ve RTP) her zaman ISP-1'den gönder
# ISP-1 daha düşük gecikme süresi sunuyor
VOIP_SUBNET="192.168.1.50/32"    # VoIP sunucusu
SIP_PORT="5060"
RTP_LOW="10000"
RTP_HIGH="20000"

# SIP trafiğini işaretle
iptables -t mangle -A PREROUTING -i $LAN_IF 
    -s $VOIP_SUBNET 
    -p udp --dport $SIP_PORT 
    -j MARK --set-mark 0x1

# RTP trafiğini işaretle
iptables -t mangle -A PREROUTING -i $LAN_IF 
    -s $VOIP_SUBNET 
    -p udp --dport $RTP_LOW:$RTP_HIGH 
    -j MARK --set-mark 0x1

# CONNMARK ile oturumu kaydet
iptables -t mangle -A PREROUTING -i $LAN_IF 
    -s $VOIP_SUBNET 
    -j CONNMARK --save-mark

# Yönetim trafiğini (SSH, RDP) ISP-2'den gönder
MGMT_SUBNET="192.168.1.100/28"

iptables -t mangle -A PREROUTING -i $LAN_IF 
    -s $MGMT_SUBNET 
    -p tcp -m multiport --dports 22,3389 
    -j MARK --set-mark 0x2

iptables -t mangle -A PREROUTING -i $LAN_IF 
    -s $MGMT_SUBNET 
    -p tcp -m multiport --dports 22,3389 
    -j CONNMARK --save-mark

echo "Servis bazlı yönlendirme kuralları uygulandı"

Failover: Otomatik Bağlantı Değişimi

Yük dengeleme güzel ama bir bağlantı düştüğünde sistem ne yapacak? Basit bir monitoring scripti ile bunu otomatikleştirebiliriz:

#!/bin/bash
# /usr/local/bin/wan-monitor.sh

ISP1_GW="203.0.113.1"
ISP2_GW="198.51.100.1"
ISP1_IF="eth1"
ISP2_IF="eth2"
ISP1_IP="203.0.113.2"
ISP2_IP="198.51.100.2"
LOG_FILE="/var/log/wan-monitor.log"
PING_COUNT=3
PING_TIMEOUT=2

# Bağlantı durumu dosyaları
ISP1_STATUS="/tmp/isp1_status"
ISP2_STATUS="/tmp/isp2_status"

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a $LOG_FILE
}

check_connection() {
    local gw=$1
    local iface=$2
    ping -c $PING_COUNT -W $PING_TIMEOUT -I $iface $gw > /dev/null 2>&1
    return $?
}

update_routes() {
    local isp1_up=$1
    local isp2_up=$2

    # Mevcut default route'u kaldır
    ip route del default 2>/dev/null

    if [ "$isp1_up" = "1" ] && [ "$isp2_up" = "1" ]; then
        log "Her iki ISP aktif - yük dengeleme modu"
        ip route add default 
            nexthop via $ISP1_GW dev $ISP1_IF weight 1 
            nexthop via $ISP2_GW dev $ISP2_IF weight 1
    elif [ "$isp1_up" = "1" ]; then
        log "Sadece ISP-1 aktif"
        ip route add default via $ISP1_GW dev $ISP1_IF
    elif [ "$isp2_up" = "1" ]; then
        log "Sadece ISP-2 aktif"
        ip route add default via $ISP2_GW dev $ISP2_IF
    else
        log "KRITIK: Her iki ISP de erişilemez durumda!"
    fi
}

# Ana döngü
ISP1_PREV=""
ISP2_PREV=""

while true; do
    if check_connection $ISP1_GW $ISP1_IF; then
        ISP1_CURRENT="1"
    else
        ISP1_CURRENT="0"
    fi

    if check_connection $ISP2_GW $ISP2_IF; then
        ISP2_CURRENT="1"
    else
        ISP2_CURRENT="0"
    fi

    # Durum değişikliği var mı?
    if [ "$ISP1_CURRENT" != "$ISP1_PREV" ] || [ "$ISP2_CURRENT" != "$ISP2_PREV" ]; then
        log "Durum değişikliği tespit edildi: ISP1=$ISP1_CURRENT, ISP2=$ISP2_CURRENT"
        update_routes $ISP1_CURRENT $ISP2_CURRENT
        ISP1_PREV=$ISP1_CURRENT
        ISP2_PREV=$ISP2_CURRENT
    fi

    sleep 10
done

Bu scripti systemd servisi olarak çalıştıralım:

# /etc/systemd/system/wan-monitor.service
cat > /etc/systemd/system/wan-monitor.service << 'EOF'
[Unit]
Description=WAN Baglanti Izleme ve Failover
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/wan-monitor.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

chmod +x /usr/local/bin/wan-monitor.sh
systemctl daemon-reload
systemctl enable wan-monitor
systemctl start wan-monitor

Güvenlik Duvarı Kurallarını Tamamlama

Çoklu WAN yapısında güvenlik kuralları biraz farklı düşünülmeli. Her iki arayüz için de gelen bağlantıları filtrelemek gerekiyor:

# Her iki WAN arayüzünden gelen istenmeyen trafiği engelle
for IF in $ISP1_IF $ISP2_IF; do
    # Spoofed LAN adreslerini engelle
    iptables -A INPUT -i $IF -s 192.168.0.0/16 -j DROP
    iptables -A INPUT -i $IF -s 10.0.0.0/8 -j DROP
    iptables -A INPUT -i $IF -s 172.16.0.0/12 -j DROP

    # ICMP flood koruması
    iptables -A INPUT -i $IF -p icmp 
        -m limit --limit 5/second --limit-burst 10 -j ACCEPT
    iptables -A INPUT -i $IF -p icmp -j DROP

    # SYN flood koruması
    iptables -A INPUT -i $IF -p tcp --syn 
        -m limit --limit 20/second --limit-burst 30 -j ACCEPT
    iptables -A INPUT -i $IF -p tcp --syn -j DROP

    # Port scan tespiti
    iptables -A INPUT -i $IF -p tcp --tcp-flags ALL NONE -j DROP
    iptables -A INPUT -i $IF -p tcp --tcp-flags ALL ALL -j DROP
done

# SSH sadece ISP-1'den kabul et (yönetim erişimi)
iptables -A INPUT -i $ISP1_IF -p tcp --dport 22 
    -m conntrack --ctstate NEW 
    -m recent --set --name SSH_BRUTE

iptables -A INPUT -i $ISP1_IF -p tcp --dport 22 
    -m conntrack --ctstate NEW 
    -m recent --update --seconds 60 --hitcount 4 --name SSH_BRUTE 
    -j DROP

iptables -A INPUT -i $ISP1_IF -p tcp --dport 22 -j ACCEPT

Yapılandırmayı Kalıcı Hale Getirme

iptables kuralları reboot sonrası kaybolur. Kalıcı hale getirmenin en temiz yolu iptables-save ve systemd kombinasyonu:

# Mevcut kuralları kaydet
iptables-save > /etc/iptables/rules.v4
ip route save > /etc/iproute2/rt_rules.backup

# Systemd ile yükleme servisi
cat > /etc/systemd/system/iptables-restore.service << 'EOF'
[Unit]
Description=iptables Kural Yukleme
Before=network.target

[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables/rules.v4
ExecStart=/usr/local/bin/multiwan-routes.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

# iproute2 kuralları için ayrı script
cat > /usr/local/bin/multiwan-routes.sh << 'EOF'
#!/bin/bash
# Politika tabloları ve kuralları yükle
ip route add 203.0.113.0/30 dev eth1 src 203.0.113.2 table isp1
ip route add default via 203.0.113.1 table isp1
ip route add 198.51.100.0/30 dev eth2 src 198.51.100.2 table isp2
ip route add default via 198.51.100.1 table isp2
ip rule add from 203.0.113.2 table isp1 priority 100
ip rule add from 198.51.100.2 table isp2 priority 200
ip rule add fwmark 0x1 table isp1 priority 300
ip rule add fwmark 0x2 table isp2 priority 400
ip route add default 
    nexthop via 203.0.113.1 dev eth1 weight 1 
    nexthop via 198.51.100.1 dev eth2 weight 1
EOF

chmod +x /usr/local/bin/multiwan-routes.sh
systemctl enable iptables-restore

Sorun Giderme ve İzleme

Bir şeyler ters gittiğinde nereye bakacağını bilmek çok önemli:

# Aktif bağlantı sayısını ISP'ye göre gör
iptables -t mangle -L PREROUTING -n -v | grep -E "mark|MARK"

# Yönlendirme tablolarını kontrol et
ip route show table isp1
ip route show table isp2
ip route show table main

# Politika kurallarını listele
ip rule show

# Belirli bir kaynaktan paketin hangi yolu izleyeceğini test et
ip route get 8.8.8.8 from 192.168.1.10 iif eth0

# Bağlantı takibini izle
conntrack -L | grep -E "ESTABLISHED" | wc -l

# Her arayüzden geçen trafik miktarı
watch -n 2 "ip -s link show eth1; ip -s link show eth2"

# NAT tablosunu kontrol et
iptables -t nat -L POSTROUTING -n -v

# Mangle tablısundaki işaretli paketler
iptables -t mangle -L -n -v --line-numbers

Sık Karşılaşılan Sorunlar

Asimetrik yönlendirme problemi: Paket eth1’den gelip eth2’den yanıt vermeye çalışıyorsa bağlantı kesilir. Çözüm: Her ISP için ayrı politika tablosu ve ip rule ile kaynak IP’ye göre tablo seçimi, yukarda tam olarak bunun için yapıldı.

CONNMARK kaybı: Sistem yeniden başladığında mevcut bağlantılar yeni mark almak zorunda kalır. Bu geçici bir kargaşa yaratır ama yeni bağlantılar oluştukça düzelir.

NAT bağlantılarının ISP değiştirmesi: Bir bağlantı ISP-1 üzerinden başladıktan sonra ISP-2’ye geçerse NAT tablosundaki kayıt geçersiz kalır. CONNMARK –restore-mark kullanımı bu sorunu büyük ölçüde giderir.

weight ile adil dağıtım yapılmaması: Linux çekirdeği multipath route kararını flow hash’e göre verir, paket bazında değil. Bu aslında iyi bir şey çünkü aynı bağlantının paketleri aynı yoldan gider. Ama bazı durumlarda dağıtım eşitsiz görünebilir.

Sonuç

iptables ve iproute2 kombinasyonu, ticari çözümlerle boy ölçüşebilecek bir çoklu WAN altyapısı kurmanı sağlar. Burada anlattığımız yapı; yük dengeleme, otomatik failover, servis bazlı yönlendirme ve güvenlik duvarı özelliklerini tek bir Linux kutusunda birleştiriyor.

Kurulumun en kritik noktaları şunlar: rp_filter’ı doğru kapatmak, her ISP için ayrı yönlendirme tablosu kullanmak, CONNMARK ile oturum bütünlüğünü korumak ve wan-monitor scriptiyle failover’ı otomatikleştirmek. Bu dört noktayı doğru kurarsanız gerisi neredeyse kendi kendine çalışır.

Üretim ortamına almadan önce her adımı test ortamında dene. Özellikle failover senaryolarını elle simüle et; bir arayüzü ip link set eth1 down ile kapat ve sistemin nasıl davrandığını gözlemle. Sistemin beklenen şekilde tepki verdiğini gördükten sonra canlı ortama geçebilirsin.

Yorum yapın