WireGuard ile Çoklu Peer Yönetimi

On peer sayısı ikiye, beşe çıktığında her şey hala yönetilebilir görünür. Ama bir sabah uyandığında 30 remote çalışanın, 5 şube ofisinin ve bir düzine sunucunun VPN bağlantısını tek tek yönetmeye çalıştığında işler çığırından çıkmaya başlar. WireGuard’ın sadeliği bir nimettir, ama bu sadelik büyük ölçekli dağıtımlarda ciddi bir organizasyon disiplini gerektiriyor. Bu yazıda çoklu peer yönetimini gerçek hayat senaryolarıyla, otomasyon araçlarıyla ve güvenli anahtar yönetim pratikleriyle ele alacağız.

WireGuard Çoklu Peer Yönetiminin Temelleri

WireGuard’ın yapısını düşündüğünde her peer aslında hem client hem de server olabilir. Bu simetrik yapı esneklik sağlarken konfigürasyon karmaşıklığını da beraberinde getirir. 50 peer’lı bir ortamda /etc/wireguard/wg0.conf dosyanı elle düzenlemeye çalışmak, kısa sürede bir kabusa dönüşür.

Önce temel kavramları netleştirelim:

  • Interface: WireGuard ağ arayüzü (wg0, wg1 gibi)
  • Peer: VPN’e bağlanan her endpoint
  • AllowedIPs: Bir peer üzerinden yönlendirilecek IP adresleri
  • Endpoint: Peer’ın gerçek IP ve port bilgisi
  • PersistentKeepalive: NAT arkasındaki bağlantıları canlı tutan mekanizma

Temel bir server konfigürasyonu şu şekilde görünür:

# /etc/wireguard/wg0.conf - Temel server konfigürasyonu
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# Remote Calisan - Ahmet
PublicKey = <AHMET_PUBLIC_KEY>
AllowedIPs = 10.10.0.2/32

[Peer]
# Remote Calisan - Ayse
PublicKey = <AYSE_PUBLIC_KEY>
AllowedIPs = 10.10.0.3/32

Bu yapı beş on peer için yeterli olsa da büyüdükçe yönetilemez hale gelir.

Anahtar Yönetimi ve Organizasyon

Çoklu peer ortamında en kritik nokta anahtar yönetimidir. Her peer için private/public key çifti oluşturmanın ve bunları organize etmenin sistematik bir yolu olmalı.

#!/bin/bash
# generate_peer_keys.sh - Toplu peer key üretimi

KEYS_DIR="/etc/wireguard/keys"
mkdir -p "$KEYS_DIR"
chmod 700 "$KEYS_DIR"

generate_peer() {
    local peer_name="$1"
    local peer_dir="$KEYS_DIR/$peer_name"
    
    mkdir -p "$peer_dir"
    
    # Private key olustur
    wg genkey > "$peer_dir/private.key"
    chmod 600 "$peer_dir/private.key"
    
    # Public key turet
    wg pubkey < "$peer_dir/private.key" > "$peer_dir/public.key"
    
    # Preshared key olustur (ek guvenlik katmani)
    wg genpsk > "$peer_dir/preshared.key"
    chmod 600 "$peer_dir/preshared.key"
    
    echo "Peer '$peer_name' icin keyler olusturuldu:"
    echo "  Private: $(cat $peer_dir/private.key)"
    echo "  Public:  $(cat $peer_dir/public.key)"
}

# Ornek kullanim
generate_peer "ahmet-laptop"
generate_peer "ayse-telefon"
generate_peer "istanbul-office"
generate_peer "izmir-office"

Anahtarları düzgün organize etmezsen birkaç ay sonra hangi anahtarın kime ait olduğunu bulmak için saatler harcarsın. Bir dizin yapısı önerisi:

  • /etc/wireguard/keys/ – Ana anahtar dizini
  • /etc/wireguard/keys/peers/ – Her peer için ayrı alt dizin
  • /etc/wireguard/keys/revoked/ – İptal edilmiş anahtarlar
  • /etc/wireguard/configs/ – Üretilen istemci konfigürasyonları

Konfigürasyon Şablonları ile Peer Ekleme Otomasyonu

Her yeni peer eklendiğinde hem server tarafında hem de client tarafında değişiklik yapmak gerekir. Bu süreci bir script ile otomatize etmek zaman kazandırır ve hata payını düşürür.

#!/bin/bash
# add_peer.sh - Yeni peer ekle ve konfigurasyon olustur

WG_INTERFACE="wg0"
WG_CONFIG="/etc/wireguard/${WG_INTERFACE}.conf"
KEYS_DIR="/etc/wireguard/keys/peers"
CLIENT_CONFIGS_DIR="/etc/wireguard/client-configs"
SERVER_PUBLIC_KEY=$(wg show $WG_INTERFACE public-key 2>/dev/null)
SERVER_ENDPOINT="vpn.sirketim.com:51820"
VPN_SUBNET="10.10.0"
DNS_SERVER="10.10.0.1"

# Mevcut en yuksek IP'yi bul
get_next_ip() {
    local last_ip=$(grep "AllowedIPs" $WG_CONFIG | 
        grep -oP '10.10.0.K[0-9]+' | 
        sort -n | tail -1)
    
    if [ -z "$last_ip" ]; then
        echo "2"
    else
        echo $((last_ip + 1))
    fi
}

add_peer() {
    local peer_name="$1"
    local peer_dir="$KEYS_DIR/$peer_name"
    
    if [ -z "$peer_name" ]; then
        echo "Hata: Peer adi belirtilmedi"
        exit 1
    fi
    
    # Key dizini yoksa olustur
    mkdir -p "$peer_dir"
    mkdir -p "$CLIENT_CONFIGS_DIR"
    
    # Keyler mevcut mu kontrol et
    if [ ! -f "$peer_dir/private.key" ]; then
        wg genkey > "$peer_dir/private.key"
        chmod 600 "$peer_dir/private.key"
        wg pubkey < "$peer_dir/private.key" > "$peer_dir/public.key"
        wg genpsk > "$peer_dir/preshared.key"
        chmod 600 "$peer_dir/preshared.key"
    fi
    
    PEER_PRIVATE_KEY=$(cat "$peer_dir/private.key")
    PEER_PUBLIC_KEY=$(cat "$peer_dir/public.key")
    PEER_PSK=$(cat "$peer_dir/preshared.key")
    PEER_IP="${VPN_SUBNET}.$(get_next_ip)"
    
    # Server config'e peer ekle
    cat >> "$WG_CONFIG" << EOF

[Peer]
# $peer_name
PublicKey = $PEER_PUBLIC_KEY
PresharedKey = $PEER_PSK
AllowedIPs = ${PEER_IP}/32
EOF
    
    # Istemci konfigurasyon dosyasini olustur
    cat > "$CLIENT_CONFIGS_DIR/${peer_name}.conf" << EOF
[Interface]
Address = ${PEER_IP}/24
PrivateKey = $PEER_PRIVATE_KEY
DNS = $DNS_SERVER

[Peer]
PublicKey = $SERVER_PUBLIC_KEY
PresharedKey = $PEER_PSK
Endpoint = $SERVER_ENDPOINT
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
EOF
    
    # Canlı ortamda yeni peer'i sıcak ekle (restart gerektirmez)
    wg set $WG_INTERFACE peer "$PEER_PUBLIC_KEY" 
        preshared-key "$peer_dir/preshared.key" 
        allowed-ips "${PEER_IP}/32"
    
    echo "Peer '$peer_name' basariyla eklendi"
    echo "VPN IP: $PEER_IP"
    echo "Konfigurasyon: $CLIENT_CONFIGS_DIR/${peer_name}.conf"
}

add_peer "$1"

Bu script ile yeni bir çalışan için peer eklemek tek satıra iniyor:

sudo bash add_peer.sh mehmet-pc

Dinamik Peer Yönetimi: wg set Komutu

WireGuard’ın en güçlü özelliklerinden biri servisi yeniden başlatmadan peer ekleyip çıkarabilmek. wg set komutu bu işi yapıyor ve canlı ortamlarda müdahaleyi minimuma indiriyor.

# Yeni peer'i canlıya al
wg set wg0 peer <PUBLIC_KEY> 
    allowed-ips 10.10.0.50/32 
    endpoint 203.0.113.45:51820 
    preshared-key /etc/wireguard/keys/peers/yeni-peer/preshared.key

# Mevcut peer'i kaldır
wg set wg0 peer <PUBLIC_KEY> remove

# Peer'in endpoint'ini güncelle (IP degisti)
wg set wg0 peer <PUBLIC_KEY> endpoint 203.0.113.99:51820

# Mevcut tüm peer bilgilerini gör
wg show wg0

# Belirli bir peer'in son handshake zamanini gör
wg show wg0 latest-handshakes

Burada önemli bir detay var: wg set ile yapılan değişiklikler conf dosyasına yansımaz. Kalıcı olması için wg-quick save wg0 komutunu çalıştırman veya değişiklikleri conf dosyasına manuel yazman gerekiyor.

# Mevcut durumu dosyaya kaydet
wg-quick save wg0

# Ya da daha kontrollü bir yöntem
wg showconf wg0 > /etc/wireguard/wg0.conf

Büyük Ölçekli Senaryolar: Şube Ofisleri ve Site-to-Site

30 remote çalışan senaryosu yönetilebilir, ama bir de şube ofisleri eklediğinde topoloji karmaşıklaşır. Örneğin merkez ofis, İstanbul şubesi ve İzmir şubesi arasında tam bağlantı (full mesh) kurmak istiyorsun.

# /etc/wireguard/wg0.conf - Merkez Ofis Hub
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <MERKEZ_PRIVATE_KEY>

# Istanbul Subesi
[Peer]
PublicKey = <ISTANBUL_PUBLIC_KEY>
Endpoint = istanbul-vpn.sirketim.com:51820
AllowedIPs = 10.0.0.2/32, 192.168.1.0/24
PersistentKeepalive = 25

# Izmir Subesi  
[Peer]
PublicKey = <IZMIR_PUBLIC_KEY>
Endpoint = izmir-vpn.sirketim.com:51820
AllowedIPs = 10.0.0.3/32, 192.168.2.0/24
PersistentKeepalive = 25

# Remote Calisanlar (10.0.1.0/24 blogu)
[Peer]
PublicKey = <AHMET_PUBLIC_KEY>
AllowedIPs = 10.0.1.1/32

[Peer]
PublicKey = <AYSE_PUBLIC_KEY>
AllowedIPs = 10.0.1.2/32

İstanbul şubesi tarafında ise şöyle bir konfigürasyon olacak:

# /etc/wireguard/wg0.conf - Istanbul Subesi
[Interface]
Address = 10.0.0.2/24
ListenPort = 51820
PrivateKey = <ISTANBUL_PRIVATE_KEY>
# Lokal subeyi yonlendir
PostUp = ip route add 192.168.2.0/24 via 10.0.0.1
PostDown = ip route del 192.168.2.0/24 via 10.0.0.1

# Merkez Hub
[Peer]
PublicKey = <MERKEZ_PUBLIC_KEY>
Endpoint = merkez-vpn.sirketim.com:51820
# Merkez, Izmir subesi ve remote calisanlar bu peer uzerinden ulasiliyor
AllowedIPs = 10.0.0.0/24, 10.0.1.0/24, 192.168.2.0/24
PersistentKeepalive = 25

Hub-and-spoke topolojisinde AllowedIPs konfigürasyonu kritik önem taşıyor. Yanlış bir subnet tanımı tüm trafiği karıştırabilir.

Peer İzleme ve Sağlık Kontrolleri

50 peer’ın hangisinin bağlı olduğunu, hangisinin son 10 dakikadır handshake yapmadığını takip etmek için monitoring scriptleri şart.

#!/bin/bash
# check_peers.sh - Peer saglik kontrolu

WG_INTERFACE="wg0"
HANDSHAKE_TIMEOUT=180  # 3 dakika
ALERT_EMAIL="[email protected]"

check_peer_health() {
    echo "=== WireGuard Peer Durumu: $(date) ==="
    echo ""
    
    # Tum peer'lerin son handshake zamanlarini al
    wg show $WG_INTERFACE latest-handshakes | while read pubkey timestamp; do
        local current_time=$(date +%s)
        local elapsed=$((current_time - timestamp))
        
        # Peer adini konfig dosyasindan bul
        local peer_name=$(grep -B1 "PublicKey = $pubkey" /etc/wireguard/wg0.conf | 
            grep "^# " | sed 's/# //')
        
        if [ -z "$peer_name" ]; then
            peer_name="Bilinmeyen (${pubkey:0:8}...)"
        fi
        
        if [ "$timestamp" -eq "0" ]; then
            echo "  [HICBIR ZAMAN] $peer_name - Hic baglanmamis"
        elif [ "$elapsed" -gt "$HANDSHAKE_TIMEOUT" ]; then
            local mins=$((elapsed / 60))
            echo "  [UYARI] $peer_name - Son handshake: ${mins} dakika once"
        else
            echo "  [OK] $peer_name - Aktif"
        fi
    done
    
    echo ""
    echo "Toplam peer sayisi: $(wg show $WG_INTERFACE peers | wc -l)"
}

# Transfer istatistikleri
show_transfer_stats() {
    echo "=== Transfer Istatistikleri ==="
    wg show $WG_INTERFACE transfer | while read pubkey rx tx; do
        local peer_name=$(grep -B1 "PublicKey = $pubkey" /etc/wireguard/wg0.conf | 
            grep "^# " | sed 's/# //')
        
        local rx_mb=$((rx / 1024 / 1024))
        local tx_mb=$((tx / 1024 / 1024))
        
        echo "  $peer_name: RX ${rx_mb}MB | TX ${tx_mb}MB"
    done
}

check_peer_health
show_transfer_stats

Bu scripti cron’a ekleyerek düzenli kontrol yapabilirsin:

# crontab -e
# Her 5 dakikada kontrol et
*/5 * * * * /opt/scripts/check_peers.sh >> /var/log/wireguard-health.log 2>&1

# Her gece 23:00'de transfer istatistiklerini arşivle
0 23 * * * /opt/scripts/check_peers.sh 2>&1 | mail -s "WG Daily Stats" [email protected]

Peer Gruplandırma ve Erişim Kontrolü

Gerçek dünyada tüm peer’ların aynı kaynaklara erişmesini istemezsin. Remote çalışanlar sadece ofis uygulamalarına, DevOps ekibi tüm sunuculara, yöneticiler ise her şeye erişebilmeli.

Bunu WireGuard seviyesinde AllowedIPs ile değil, iptables/nftables kurallarıyla yönetmek daha esnek bir yaklaşım:

#!/bin/bash
# setup_access_control.sh - Peer gruplarına göre erişim kontrolü

# Grup IP aralıkları
ADMIN_SUBNET="10.10.1.0/24"
DEVOPS_SUBNET="10.10.2.0/24"
EMPLOYEE_SUBNET="10.10.3.0/24"

# Dahili sunucu grupları
APP_SERVERS="172.16.10.0/24"
DB_SERVERS="172.16.20.0/24"
MGMT_SERVERS="172.16.30.0/24"

setup_rules() {
    # Mevcut WireGuard kurallarini temizle
    iptables -F WIREGUARD_POLICY 2>/dev/null || 
        iptables -N WIREGUARD_POLICY
    
    # Adminler her yere erisebilir
    iptables -A WIREGUARD_POLICY -s $ADMIN_SUBNET -j ACCEPT
    
    # DevOps: App ve DB sunucularina erisebilir, management'a erisemez
    iptables -A WIREGUARD_POLICY -s $DEVOPS_SUBNET -d $APP_SERVERS -j ACCEPT
    iptables -A WIREGUARD_POLICY -s $DEVOPS_SUBNET -d $DB_SERVERS -j ACCEPT
    iptables -A WIREGUARD_POLICY -s $DEVOPS_SUBNET -d $MGMT_SERVERS -j DROP
    
    # Normal calisanlar: Sadece uygulama sunucularina
    iptables -A WIREGUARD_POLICY -s $EMPLOYEE_SUBNET -d $APP_SERVERS -j ACCEPT
    iptables -A WIREGUARD_POLICY -s $EMPLOYEE_SUBNET -d $DB_SERVERS -j DROP
    iptables -A WIREGUARD_POLICY -s $EMPLOYEE_SUBNET -d $MGMT_SERVERS -j DROP
    
    # FORWARD chain'e dahil et
    iptables -A FORWARD -i wg0 -j WIREGUARD_POLICY
    
    echo "Erisim kontrol kurallari yuklendi"
    iptables -L WIREGUARD_POLICY -n --line-numbers
}

setup_rules

WireGuard konfigürasyonunda IP bloklarına göre peer dağılımını da ayarlaman gerekiyor:

# /etc/wireguard/wg0.conf içinde peer gruplaması

# === ADMIN GRUBU ===
[Peer]
# admin-ali
PublicKey = <ALI_PUBLIC_KEY>
AllowedIPs = 10.10.1.1/32

[Peer]
# admin-fatma
PublicKey = <FATMA_PUBLIC_KEY>
AllowedIPs = 10.10.1.2/32

# === DEVOPS GRUBU ===
[Peer]
# devops-kemal
PublicKey = <KEMAL_PUBLIC_KEY>
AllowedIPs = 10.10.2.1/32

# === CALISAN GRUBU ===
[Peer]
# calisan-hasan
PublicKey = <HASAN_PUBLIC_KEY>
AllowedIPs = 10.10.3.1/32

Peer Kaldırma ve Anahtar Rotasyonu

Bir çalışan şirketten ayrıldığında peer’ı hızla ve güvenle kaldırmak kritik. Ayrıca düzenli anahtar rotasyonu güvenlik hijyeninin önemli bir parçası.

#!/bin/bash
# revoke_peer.sh - Peer'i güvenle kaldır

WG_INTERFACE="wg0"
WG_CONFIG="/etc/wireguard/${WG_INTERFACE}.conf"
KEYS_DIR="/etc/wireguard/keys/peers"
REVOKED_DIR="/etc/wireguard/keys/revoked"

revoke_peer() {
    local peer_name="$1"
    local peer_dir="$KEYS_DIR/$peer_name"
    
    if [ ! -d "$peer_dir" ]; then
        echo "Hata: '$peer_name' adinda peer bulunamadi"
        exit 1
    fi
    
    PEER_PUBLIC_KEY=$(cat "$peer_dir/public.key")
    
    # Once canlı bağlantıyı kes
    wg set $WG_INTERFACE peer "$PEER_PUBLIC_KEY" remove
    echo "Canli baglanti kesildi: $peer_name"
    
    # Config dosyasından kaldır
    # Peer bloğunu bul ve sil (yorum satırı dahil)
    python3 << PYEOF
import re

with open('$WG_CONFIG', 'r') as f:
    content = f.read()

# Peer bloğunu regex ile bul ve kaldır
pattern = r'n# $peer_namen[Peer]n(?:.*n)*?(?=n[|Z)'
new_content = re.sub(pattern, '', content)

with open('$WG_CONFIG', 'w') as f:
    f.write(new_content)

print("Config dosyasi guncellendi")
PYEOF
    
    # Anahtar dosyalarini arsivle (silme, audit icin tut)
    mkdir -p "$REVOKED_DIR"
    mv "$peer_dir" "$REVOKED_DIR/${peer_name}-$(date +%Y%m%d)"
    
    echo "Peer '$peer_name' iptal edildi ve arsivlendi"
    echo "Kalan peer sayisi: $(wg show $WG_INTERFACE peers | wc -l)"
}

# Anahtar rotasyonu
rotate_peer_key() {
    local peer_name="$1"
    local peer_dir="$KEYS_DIR/$peer_name"
    
    echo "Anahtar rotasyonu baslıyor: $peer_name"
    
    # Eski keyler yedekle
    cp "$peer_dir/private.key" "$peer_dir/private.key.old"
    cp "$peer_dir/public.key" "$peer_dir/public.key.old"
    
    OLD_PUBLIC_KEY=$(cat "$peer_dir/public.key")
    
    # Yeni key olustur
    wg genkey > "$peer_dir/private.key"
    wg pubkey < "$peer_dir/private.key" > "$peer_dir/public.key"
    
    NEW_PUBLIC_KEY=$(cat "$peer_dir/public.key")
    PEER_IP=$(grep -A3 "PublicKey = $OLD_PUBLIC_KEY" $WG_CONFIG | 
        grep AllowedIPs | awk '{print $3}')
    
    # Eski peer'i kaldır, yeni key ile ekle
    wg set $WG_INTERFACE peer "$OLD_PUBLIC_KEY" remove
    wg set $WG_INTERFACE peer "$NEW_PUBLIC_KEY" allowed-ips "$PEER_IP"
    
    # Config güncelle
    sed -i "s|PublicKey = $OLD_PUBLIC_KEY|PublicKey = $NEW_PUBLIC_KEY|g" $WG_CONFIG
    
    echo "Anahtar rotasyonu tamamlandi: $peer_name"
    echo "Yeni public key: $NEW_PUBLIC_KEY"
    echo "Istemciye yeni konfig gondermeyi unutma!"
}

case "$1" in
    revoke) revoke_peer "$2" ;;
    rotate) rotate_peer_key "$2" ;;
    *) echo "Kullanim: $0 {revoke|rotate} <peer-adi>" ;;
esac

QR Kod ile Mobil Peer Dağıtımı

Mobil cihazlar için WireGuard konfigürasyonunu QR kod olarak paylaşmak hem pratik hem de güvenli bir yöntem. Dosya göndermek yerine QR kod göstererek konfigürasyonu transfer edebilirsin.

# qrencode paketini kur
apt install qrencode   # Debian/Ubuntu
dnf install qrencode   # RHEL/Fedora

# Mobil cihaz için QR kod olustur
qrencode -t ansiutf8 < /etc/wireguard/client-configs/ahmet-telefon.conf

# PNG olarak kaydet (ekrana göstermek yerine dosya olarak)
qrencode -t png -o /tmp/ahmet-qr.png 
    < /etc/wireguard/client-configs/ahmet-telefon.conf

# Terminalde büyük QR kod göster
qrencode -t ansiutf8 -s 1 
    < /etc/wireguard/client-configs/ahmet-telefon.conf

# Islem bittikten sonra geçici dosyayi temizle
rm -f /tmp/ahmet-qr.png

QR kodu oluşturduktan sonra dosyayı hemen silmek güvenlik açısından önemli. Konfigürasyon dosyaları ekranda gösterip kağıda yazılmasını önlemek için terminalde direkt göstermeyi tercih et.

Sonuç

WireGuard çoklu peer yönetimi doğru araçlar ve alışkanlıklarla son derece yönetilebilir bir yapıya dönüşüyor. Birkaç temel prensibi her zaman aklında tut.

Otomasyon vazgeçilmezdir. On peer’dan fazlasında manual konfigürasyon hataya açıktır. Peer ekleme, kaldırma ve anahtar rotasyonunu script’lerle otomatize et.

Anahtar organizasyonu kritiktir. Her peer için ayrı dizin, düzenli yedekleme ve revoke işlemlerinde gerçek silme yerine arşivleme. Bir güvenlik olayında hangi anahtarın ne zaman aktif olduğunu bilmek değerlidir.

İzleme şarttır. Hangi peer’ın bağlı olduğunu, hangisinin uzun süredir handshake yapmadığını bilmemek hem güvenlik hem de operasyonel bir kör noktadır. Basit bir cron script’i bile büyük fark yaratır.

Erişim kontrolünü WireGuard seviyesinde değil firewall seviyesinde yönet. AllowedIPs ile IP bloğu segmentasyonu, iptables ile granüler politika. Bu ikili yapı hem esnek hem de güvenli.

Düzenli anahtar rotasyonu yaşam tarzı haline gelmeli. Özellikle ayrılan çalışanların anahtarlarını anında iptal etmek, kalan ekip için yılda bir rotasyon yapmak minimum güvenlik hijyeni.

Gerçek dünya WireGuard kurulumlarında bu prensipleri uyguladığında hem operasyonel yük azalır hem de güvenlik duruşun güçlenir. WireGuard’ın sadeliği aldatıcı olabilir, ama bu sadeliğin üzerine kendi katmanlı yönetim yapını inşa etmek sysadmin’in asıl işidir.

Yorum yapın