WireGuard ile Çoklu WAN Bağlantısında Yük Dengeleme ve Yedeklilik Yapılandırması

Birden fazla internet bağlantısı olan bir yapıda WireGuard çalıştırmak, kulağa karmaşık gelebilir ama doğru yapılandırıldığında hem yük dengeleme hem de kesintisiz çalışma için oldukça güçlü bir çözüm ortaya çıkıyor. Bu yazıda gerçek dünya senaryolarına dayanan bir çoklu WAN yapılandırmasını adım adım inceleyeceğiz.

Senaryo ve Altyapı Tanımı

Elimizde şu yapı olduğunu varsayalım: Bir merkez ofis (hub) ve buna bağlı şube ofisler. Merkez ofiste iki ayrı ISP bağlantısı var. Birincisi fiber 500 Mbps, ikincisi ADSL yedek hat olarak kullanılıyor. Şube ofislerden gelen VPN trafiğini her iki hat üzerinden dengelemek ve birisi çöktüğünde otomatik olarak diğerine geçmek istiyoruz.

Sunucu yapısı şu şekilde:

  • WAN1: 203.0.113.1 – Fiber hat (eth0)
  • WAN2: 198.51.100.1 – ADSL hat (eth1)
  • WireGuard Arayüzü: wg010.10.0.1/24
  • İşletim Sistemi: Ubuntu 22.04 LTS

WireGuard Kurulumu ve Temel Yapılandırma

Önce WireGuard’ı kuralım ve anahtar çiftimizi oluşturalım.

apt update && apt install -y wireguard wireguard-tools
cd /etc/wireguard
umask 077
wg genkey | tee server_private.key | wg pubkey > server_public.key
cat server_private.key
cat server_public.key

Şimdi çift WAN için temel WireGuard yapılandırmasını oluşturalım. Bu noktada kritik bir karar vermemiz gerekiyor: WireGuard her iki IP’de de dinleyecek mi, yoksa her hat için ayrı interface mi kullanacağız? Ben ayrı interface kullanmayı tercih ediyorum çünkü yönetimi çok daha temiz oluyor.

# wg0 - Fiber hat için (WAN1)
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
# Fiber hat üzerinden çıkış için policy routing tablosu
Table = off
PostUp = ip rule add from 10.10.0.0/24 table 100 priority 100
PostUp = ip route add default via 203.0.113.254 table 100
PostDown = ip rule del from 10.10.0.0/24 table 100

[Peer]
# Şube 1
PublicKey = <SUBE1_PUBLIC_KEY>
AllowedIPs = 10.10.0.2/32, 192.168.10.0/24
PersistentKeepalive = 25

[Peer]
# Şube 2
PublicKey = <SUBE2_PUBLIC_KEY>
AllowedIPs = 10.10.0.3/32, 192.168.20.0/24
PersistentKeepalive = 25
EOF

# wg1 - ADSL hat için (WAN2)
cat > /etc/wireguard/wg1.conf << 'EOF'
[Interface]
Address = 10.10.1.1/24
ListenPort = 51821
PrivateKey = <SERVER_PRIVATE_KEY>
Table = off
PostUp = ip rule add from 10.10.1.0/24 table 101 priority 101
PostUp = ip route add default via 198.51.100.254 table 101
PostDown = ip rule del from 10.10.1.0/24 table 101

[Peer]
# Şube 1 - yedek bağlantı
PublicKey = <SUBE1_PUBLIC_KEY>
AllowedIPs = 10.10.1.2/32, 192.168.10.0/24
PersistentKeepalive = 25

[Peer]
# Şube 2 - yedek bağlantı
PublicKey = <SUBE2_PUBLIC_KEY>
AllowedIPs = 10.10.1.3/32, 192.168.20.0/24
PersistentKeepalive = 25
EOF

Policy Routing ile Çoklu WAN Yapılandırması

Linux’ta çoklu WAN yönetiminin kalbi policy routing’dir. iproute2 ile her hat için ayrı routing tablosu oluşturacağız.

# /etc/iproute2/rt_tables dosyasına tablolarımızı ekleyelim
echo "100 wan1" >> /etc/iproute2/rt_tables
echo "101 wan2" >> /etc/iproute2/rt_tables

# WAN1 (Fiber) için routing tablosunu yapılandır
ip route add default via 203.0.113.254 dev eth0 table wan1
ip route add 203.0.113.0/24 dev eth0 src 203.0.113.1 table wan1
ip rule add from 203.0.113.1 table wan1 priority 100

# WAN2 (ADSL) için routing tablosunu yapılandır
ip route add default via 198.51.100.254 dev eth1 table wan2
ip route add 198.51.100.0/24 dev eth1 src 198.51.100.1 table wan2
ip rule add from 198.51.100.1 table wan2 priority 101

# Bu ayarları kalıcı yapmak için netplan veya /etc/network/interfaces kullanabilirsiniz
# Ubuntu 22.04 için netplan örneği:
cat > /etc/netplan/01-multiwan.yaml << 'EOF'
network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - 203.0.113.1/24
      routes:
        - to: default
          via: 203.0.113.254
          metric: 100
          table: 100
      routing-policy:
        - from: 203.0.113.1
          table: 100
          priority: 100
    eth1:
      addresses:
        - 198.51.100.1/24
      routes:
        - to: default
          via: 198.51.100.254
          metric: 200
          table: 101
      routing-policy:
        - from: 198.51.100.1
          table: 101
          priority: 101
EOF
netplan apply

Yük Dengeleme için ECMP Yapılandırması

ECMP (Equal-Cost Multi-Path) routing ile gelen trafiği iki hat arasında dağıtabiliriz. Ancak WireGuard ile kullanırken dikkatli olmak gerekiyor, çünkü UDP bağlantılarının simetrik akması kritik.

# ECMP ile çift default route
ip route add default 
  nexthop via 203.0.113.254 dev eth0 weight 5 
  nexthop via 198.51.100.254 dev eth1 weight 1

# Bunu /etc/rc.local veya systemd service ile kalıcı hale getirin
cat > /etc/systemd/system/multiwan-routes.service << 'EOF'
[Unit]
Description=Multi-WAN Route Configuration
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/setup-multiwan.sh
ExecStop=/bin/true

[Install]
WantedBy=multi-user.target
EOF

cat > /usr/local/bin/setup-multiwan.sh << 'EOF'
#!/bin/bash
# Önce eski ECMP route'u temizle
ip route del default 2>/dev/null

# Fiber hat 5 birim ağırlık, ADSL 1 birim
ip route add default 
  nexthop via 203.0.113.254 dev eth0 weight 5 
  nexthop via 198.51.100.254 dev eth1 weight 1

# Policy routing tablolarını kur
ip route add default via 203.0.113.254 dev eth0 table wan1 2>/dev/null
ip route add default via 198.51.100.254 dev eth1 table wan2 2>/dev/null

ip rule add from 203.0.113.1 table wan1 priority 100 2>/dev/null
ip rule add from 198.51.100.1 table wan2 priority 101 2>/dev/null
EOF

chmod +x /usr/local/bin/setup-multiwan.sh
systemctl enable multiwan-routes
systemctl start multiwan-routes

Hat İzleme ve Otomatik Failover

İşte asıl iş bu noktada başlıyor. Hat düşüşlerini tespit edip otomatik geçiş yapacak bir script yazacağız. Bu scripti cron veya systemd timer ile her dakika çalıştırabiliriz.

cat > /usr/local/bin/wan-monitor.sh << 'EOF'
#!/bin/bash

# Yapılandırma
WAN1_GW="203.0.113.254"
WAN2_GW="198.51.100.254"
WAN1_DEV="eth0"
WAN2_DEV="eth1"
CHECK_HOST1="8.8.8.8"
CHECK_HOST2="1.1.1.1"
LOG_FILE="/var/log/wan-monitor.log"
STATE_FILE="/var/run/wan-state"

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

check_wan() {
    local dev=$1
    local gw=$2
    # 3 kez dene, 2 saniye timeout
    ping -I $dev -c 3 -W 2 -q $CHECK_HOST1 > /dev/null 2>&1 || 
    ping -I $dev -c 3 -W 2 -q $CHECK_HOST2 > /dev/null 2>&1
    return $?
}

get_state() {
    cat $STATE_FILE 2>/dev/null || echo "both_up"
}

set_state() {
    echo $1 > $STATE_FILE
}

current_state=$(get_state)

check_wan $WAN1_DEV $WAN1_GW
WAN1_UP=$?

check_wan $WAN2_DEV $WAN2_GW
WAN2_UP=$?

if [ $WAN1_UP -eq 0 ] && [ $WAN2_UP -eq 0 ]; then
    if [ "$current_state" != "both_up" ]; then
        log "Her iki hat da aktif - ECMP routing devreye aliniyor"
        ip route del default 2>/dev/null
        ip route add default 
          nexthop via $WAN1_GW dev $WAN1_DEV weight 5 
          nexthop via $WAN2_GW dev $WAN2_DEV weight 1
        # wg0 ve wg1 her ikisi de aktif
        wg-quick up wg0 2>/dev/null
        wg-quick up wg1 2>/dev/null
        set_state "both_up"
    fi

elif [ $WAN1_UP -ne 0 ] && [ $WAN2_UP -eq 0 ]; then
    if [ "$current_state" != "wan2_only" ]; then
        log "UYARI: WAN1 (Fiber) DOWN - WAN2 (ADSL) uzerinden devam ediliyor"
        ip route del default 2>/dev/null
        ip route add default via $WAN2_GW dev $WAN2_DEV
        # wg0'ı durdur, wg1 aktif kalsın
        wg-quick down wg0 2>/dev/null
        wg-quick up wg1 2>/dev/null
        # Şubelere bildirim gönder (opsiyonel)
        logger -t wan-monitor "WAN1 DOWN - Failover WAN2"
        set_state "wan2_only"
    fi

elif [ $WAN1_UP -eq 0 ] && [ $WAN2_UP -ne 0 ]; then
    if [ "$current_state" != "wan1_only" ]; then
        log "UYARI: WAN2 (ADSL) DOWN - WAN1 (Fiber) uzerinden devam ediliyor"
        ip route del default 2>/dev/null
        ip route add default via $WAN1_GW dev $WAN1_DEV
        wg-quick up wg0 2>/dev/null
        wg-quick down wg1 2>/dev/null
        set_state "wan1_only"
    fi

else
    log "KRITIK: Her iki hat da DOWN!"
    set_state "both_down"
fi
EOF

chmod +x /usr/local/bin/wan-monitor.sh

# Systemd timer ile her 30 saniyede bir çalıştır
cat > /etc/systemd/system/wan-monitor.service << 'EOF'
[Unit]
Description=WAN Monitor Check
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/wan-monitor.sh
EOF

cat > /etc/systemd/system/wan-monitor.timer << 'EOF'
[Unit]
Description=WAN Monitor Timer
After=network.target

[Timer]
OnBootSec=60
OnUnitActiveSec=30s

[Install]
WantedBy=timers.target
EOF

systemctl enable wan-monitor.timer
systemctl start wan-monitor.timer

Şube Tarafı Yapılandırması

Şube ofislerde WireGuard istemcisinin her iki WAN IP’sini bilmesi gerekiyor. Bu noktada wg-quick ile birden fazla endpoint tanımlamak doğrudan mümkün değil, ama bir endpoint değişim scripti yazabiliriz.

# Şube 1 - Birincil bağlantı (WAN1 üzerinden)
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
Address = 10.10.0.2/24
PrivateKey = <SUBE1_PRIVATE_KEY>
DNS = 10.10.0.1

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = 203.0.113.1:51820
AllowedIPs = 10.10.0.0/24, 192.168.0.0/16
PersistentKeepalive = 25
EOF

# Şube tarafında endpoint kontrolü ve değiştirme scripti
cat > /usr/local/bin/wg-endpoint-check.sh << 'EOF'
#!/bin/bash

PRIMARY_ENDPOINT="203.0.113.1:51820"
SECONDARY_ENDPOINT="198.51.100.1:51821"
PEER_PUBKEY="<SERVER_PUBLIC_KEY>"
WG_IFACE="wg0"
LOG="/var/log/wg-endpoint.log"

log() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG
}

# Mevcut handshake zamanını kontrol et
LAST_HANDSHAKE=$(wg show $WG_IFACE latest-handshakes | awk '{print $2}')
NOW=$(date +%s)
ELAPSED=$((NOW - LAST_HANDSHAKE))

# 3 dakikadan uzun süredir handshake yoksa endpoint değiştir
if [ $ELAPSED -gt 180 ]; then
    CURRENT=$(wg show $WG_IFACE endpoints | grep $PEER_PUBKEY | awk '{print $2}')
    
    if [ "$CURRENT" = "$PRIMARY_ENDPOINT" ]; then
        log "Primary endpoint yanıt vermiyor, secondary'e geçiliyor: $SECONDARY_ENDPOINT"
        wg set $WG_IFACE peer $PEER_PUBKEY endpoint $SECONDARY_ENDPOINT
    else
        log "Secondary endpoint deneniyor, primary'e geçiliyor: $PRIMARY_ENDPOINT"
        wg set $WG_IFACE peer $PEER_PUBKEY endpoint $PRIMARY_ENDPOINT
    fi
fi
EOF

chmod +x /usr/local/bin/wg-endpoint-check.sh

Firewall ve NAT Yapılandırması

Çoklu WAN yapısında iptables kuralları doğru yazılmazsa asimetrik routing sorunları yaşanır.

cat > /usr/local/bin/setup-firewall.sh << 'EOF'
#!/bin/bash

# Temel ileri yönlendirme
echo 1 > /proc/sys/net/ipv4/ip_forward

# Kalıcı hale getir
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.d/99-wireguard.conf
sysctl -p /etc/sysctl.d/99-wireguard.conf

# iptables kurallarını temizle
iptables -F
iptables -t nat -F
iptables -t mangle -F

# WireGuard portlarını aç
iptables -A INPUT -p udp --dport 51820 -j ACCEPT
iptables -A INPUT -p udp --dport 51821 -j ACCEPT

# WireGuard arayüzleri arasında forward izni
iptables -A FORWARD -i wg0 -j ACCEPT
iptables -A FORWARD -i wg1 -j ACCEPT
iptables -A FORWARD -o wg0 -j ACCEPT
iptables -A FORWARD -o wg1 -j ACCEPT

# WAN1 için NAT
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# WAN2 için NAT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

# Asimetrik routing sorununu önlemek için connection tracking ile source routing
iptables -t mangle -A PREROUTING -i eth0 -j CONNMARK --set-mark 1
iptables -t mangle -A PREROUTING -i eth1 -j CONNMARK --set-mark 2
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m connmark --mark 1 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -m connmark --mark 2 -j MARK --set-mark 2

# Mark'a göre routing tablosu seç
ip rule add fwmark 1 table wan1 priority 90 2>/dev/null
ip rule add fwmark 2 table wan2 priority 91 2>/dev/null

# Kuralları kaydet
iptables-save > /etc/iptables/rules.v4
EOF

chmod +x /usr/local/bin/setup-firewall.sh
bash /usr/local/bin/setup-firewall.sh

İzleme ve Durum Takibi

Yapılandırmanızın sağlıklı çalışıp çalışmadığını düzenli olarak kontrol etmeniz gerekiyor. Bunun için birkaç kullanışlı komut ve bir durum özeti scripti yazalım.

# Anlık durum özeti scripti
cat > /usr/local/bin/wan-status.sh << 'EOF'
#!/bin/bash

echo "========== WAN DURUM RAPORU =========="
echo "Tarih: $(date)"
echo ""

echo "--- Aktif Routing Tablosu ---"
ip route show

echo ""
echo "--- WAN1 (Fiber) WireGuard Durumu ---"
wg show wg0 2>/dev/null || echo "wg0 aktif degil"

echo ""
echo "--- WAN2 (ADSL) WireGuard Durumu ---"
wg show wg1 2>/dev/null || echo "wg1 aktif degil"

echo ""
echo "--- Peer Handshake Zamanlari ---"
for iface in wg0 wg1; do
    echo "[$iface]"
    wg show $iface latest-handshakes 2>/dev/null | while read peer ts; do
        elapsed=$(( $(date +%s) - ts ))
        echo "  Peer: ${peer:0:12}... - Son handshake: ${elapsed}s once"
    done
done

echo ""
echo "--- Baglanti Testi ---"
echo -n "WAN1 (8.8.8.8 via eth0): "
ping -I eth0 -c 2 -W 2 -q 8.8.8.8 > /dev/null 2>&1 && echo "OK" || echo "FAIL"

echo -n "WAN2 (8.8.8.8 via eth1): "
ping -I eth1 -c 2 -W 2 -q 8.8.8.8 > /dev/null 2>&1 && echo "OK" || echo "FAIL"

echo ""
echo "--- Son 10 WAN Monitor Logu ---"
tail -10 /var/log/wan-monitor.log 2>/dev/null

echo "======================================"
EOF

chmod +x /usr/local/bin/wan-status.sh

Durum raporunu çalıştırmak için:

bash /usr/local/bin/wan-status.sh

Sık Karşılaşılan Sorunlar ve Çözümleri

Gerçek ortamlarda bu yapıyı kurarken şu sorunlarla karşılaşabilirsiniz:

Asimetrik routing: Paket eth0’dan gelip eth1’den çıkıyor ve yanıt dönmüyor. Bunun çözümü yukarıdaki iptables connmark kurallarıdır. Ekledikten sonra conntrack -L ile bağlantıları inceleyebilirsiniz.

WireGuard handshake başarısız: wg show komutunda latest-handshakes sütununda çok eski bir zaman görüyorsanız, önce tcpdump -i eth0 udp port 51820 ile paketin interface’e ulaşıp ulaşmadığını kontrol edin.

ECMP ile UDP bağlantısı kopuyor: Linux kernel varsayılan olarak UDP akışlarını 5-tuple’a göre hash’ler, ama bazı sürümlerde sorun çıkabilir. net.ipv4.fib_multipath_hash_policy=1 sysctl parametresini aktif edin.

  • net.ipv4.fib_multipath_hash_policy=1: Kaynak ve hedef port dahil 5-tuple hash kullanır
  • net.ipv4.fib_multipath_use_neigh=1: Erişilemeyen next-hop’ları ECMP’den otomatik çıkarır
  • PersistentKeepalive = 25: NAT arkasındaki peer’lar için bağlantıyı canlı tutar
# Bu parametreleri kalıcı hale getirelim
cat >> /etc/sysctl.d/99-wireguard.conf << 'EOF'
net.ipv4.fib_multipath_hash_policy = 1
net.ipv4.fib_multipath_use_neigh = 1
net.core.rps_sock_flow_entries = 32768
EOF
sysctl -p /etc/sysctl.d/99-wireguard.conf

Gerçek Dünya Notları

Bir müşteri ortamında bu yapıyı devreye alırken şunu öğrendim: ISP’lerin modem/router’ları bazen default gateway olarak değil, NAT arkasında çalışıyor. Bu durumda WireGuard’ın gerçek public IP’yi görmesi için Endpoint adresini elle doğru girilmesi gerekiyor. curl -s --interface eth0 ifconfig.me komutu ile hangi public IP’den göründüğünüzü test edin.

Yük dengeleme ağırlıklarını belirlerken bant genişliği oranını değil, gecikme ve paket kaybı oranını dikkate alın. 500 Mbps fiber’in 5 birim, 10 Mbps ADSL’in 1 birim alması mantıklı görünüyor ama ADSL’in latency’si yüksekse yük dengeleme yerine sadece yedek olarak tutmak daha iyi bir fikir olabilir. mtr --report --interface eth1 8.8.8.8 ile her hat için gerçekçi ölçüm yapın.

wg-quick yerine systemd-networkd ve wg komutlarını doğrudan kullanmayı da değerlendirin, özellikle çok sayıda peer ve interface yönetiminde daha esnek bir yapı sunuyor.

Sonuç

WireGuard ile çoklu WAN yapılandırması, görünürde birçok farklı katmanı bir arada yönetmeyi gerektiriyor: policy routing, iptables, WireGuard konfigürasyonu ve izleme scriptleri. Ama her katmanı ayrı ayrı anladıktan sonra bunları bir araya getirmek oldukça sistematik bir hal alıyor.

Temel prensip şu: Linux’un kendi routing altyapısını eksiksiz kullan, WireGuard’ı sadece şifreleme katmanı olarak düşün. ECMP ve policy routing WireGuard’dan bağımsız çalışıyor, bu yüzden önce bu katmanı sağlamlaştırın, sonra WireGuard interface’lerini üstüne oturtun.

Failover süresini minimize etmek istiyorsanız izleme aralığını 30 saniyenin altına indirmekten kaçının, çünkü agresif ping kontrolleri bazen kendisi bir sorun kaynağına dönüşebilir. 30-60 saniyelik bir failover süresi çoğu kurumsal kullanım için kabul edilebilir bir değer.

Bir yanıt yazın

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