Şirket ağına bağlanmak için VPN kullanıyorsunuz ama YouTube videoları da VPN üzerinden geçiyor ve bant genişliğinizi mahvediyor. Ya da evden çalışırken hem iş sunucularına hem de yerel ağdaki yazıcınıza erişmeniz gerekiyor. İşte tam bu nokta split tunneling devreye giriyor. WireGuard ile split tunneling kurulumu, doğru yapılandırıldığında hem güvenliği hem de performansı aynı anda elde etmenizi sağlar.
Split Tunneling Nedir ve Neden Önemlidir
Normal bir VPN bağlantısında tüm trafik VPN tünelinden geçer. Bu “full tunneling” olarak bilinir ve güvenlik açısından ideal görünse de pratikte ciddi sorunlar yaratır. Bant genişliği israfı, gecikme artışı ve VPN sunucusunun gereksiz yük altına girmesi bunların başında gelir.
Split tunneling ise trafiği ikiye böler. Belirli hedefler (şirket ağı, hassas servisler) VPN üzerinden giderken geri kalan trafik doğrudan internet bağlantısı üzerinden akar. WireGuard’ın tasarımı bu konsept için son derece uygundur çünkü AllowedIPs direktifi hem routing kararlarını hem de firewall kurallarını tek satırda yönetmenize olanak tanır.
Gerçek dünya senaryosuna bakacak olursak: 50 kişilik bir şirkette çalışanlar evden bağlanıyor. Şirketin iç ağı 10.10.0.0/16 bloğunda. Çalışanlar Zoom görüşmeleri yapıyor, Netflix izliyor, aynı zamanda şirket içi GitLab ve Jira’ya erişiyor. Full tunneling ile 50 çalışanın tüm internet trafiği şirket hattından geçerse hem maliyet hem de performans krizi kaçınılmaz olur.
WireGuard Temel Kavramları
Split tunneling’e geçmeden önce WireGuard’ın routing mekanizmasını anlamak gerekiyor.
WireGuard’da routing şu şekilde çalışır: Her peer için tanımlanan AllowedIPs değeri aslında iki işlevi birden üstlenir. Gelen paketlerde bu IP bloklarından gelen paketler kabul edilir, giden paketlerde ise bu IP bloklarına giden paketler ilgili peer üzerinden yönlendirilir. Yani AllowedIPs = 0.0.0.0/0 full tunneling anlamına gelirken AllowedIPs = 10.10.0.0/16 sadece o bloğu tünellemek demektir.
Temel WireGuard kurulumu için gerekli paketler:
# Ubuntu/Debian
sudo apt update && sudo apt install -y wireguard wireguard-tools
# CentOS/RHEL 8+
sudo dnf install -y wireguard-tools
# Arch Linux
sudo pacman -S wireguard-tools
# Kernel modülünü kontrol et
sudo modprobe wireguard
lsmod | grep wireguard
Sunucu Tarafı Yapılandırması
Önce WireGuard sunucusunu kuralım. Bu örnekte sunucu 192.168.1.100 IP adresinde, VPN ağı 10.10.0.0/24 bloğunda olacak.
# Anahtar çifti oluştur
cd /etc/wireguard
umask 077
wg genkey | tee server_private.key | wg pubkey > server_public.key
# İstemci anahtarları
wg genkey | tee client1_private.key | wg pubkey > client1_public.key
wg genkey | tee client2_private.key | wg pubkey > client2_public.key
# Anahtarları görüntüle
echo "Server Public Key: $(cat server_public.key)"
echo "Client1 Public Key: $(cat client1_public.key)"
Sunucu yapılandırma dosyasını oluşturalım:
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = <SUNUCU_PRIVATE_KEY>
# Split tunneling için NAT kuralları - sadece şirket trafiği için
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT
PostUp = iptables -A FORWARD -o wg0 -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT
PostDown = iptables -D FORWARD -o wg0 -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -s 10.10.0.0/24 -o eth0 -j MASQUERADE
# İstemci 1 - Sadece şirket ağı erişimi
[Peer]
PublicKey = <CLIENT1_PUBLIC_KEY>
AllowedIPs = 10.10.0.2/32
# İstemci 2 - Şirket ağı + özel subnet
[Peer]
PublicKey = <CLIENT2_PUBLIC_KEY>
AllowedIPs = 10.10.0.3/32
EOF
Servisi başlatalım:
# IP forwarding aktif et
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
# WireGuard servisini başlat
systemctl enable --now wg-quick@wg0
systemctl status wg-quick@wg0
# Bağlantıları kontrol et
wg show
İstemci Tarafı Split Tunneling Yapılandırması
İşte asıl sihir burada gerçekleşiyor. İstemci tarafında AllowedIPs direktifini doğru ayarlamak split tunneling’in temelidir.
Senaryo 1: Sadece Şirket İç Ağı Üzerinden
Bu en saf split tunneling senaryosu. Çalışan sadece 10.10.0.0/24 şirket VPN ağına ve 172.16.0.0/12 şirket iç subnetlerine erişmek istiyor, geri kalan her şey doğrudan gidiyor:
# /etc/wireguard/wg0.conf - İstemci 1
[Interface]
Address = 10.10.0.2/24
PrivateKey = <CLIENT1_PRIVATE_KEY>
DNS = 10.10.0.1
[Peer]
PublicKey = <SUNUCU_PUBLIC_KEY>
Endpoint = sunucu.sirket.com:51820
AllowedIPs = 10.10.0.0/24, 172.16.0.0/12, 192.168.10.0/24
PersistentKeepalive = 25
Bu yapılandırmayla şirket kaynaklarına erişim VPN üzerinden giderken YouTube, Gmail, her türlü internet trafiği doğrudan ISP üzerinden akar.
Senaryo 2: Belirli Servisleri Tünelleme
Daha granüler bir kontrol istiyorsanız belirli IP adreslerini veya subnetleri ekleyebilirsiniz:
# /etc/wireguard/wg0.conf - Gelişmiş split tunneling
[Interface]
Address = 10.10.0.3/24
PrivateKey = <CLIENT2_PRIVATE_KEY>
# Özel DNS: şirket domain'leri için iç DNS, geri kalanı için public DNS
DNS = 10.10.0.1, 8.8.8.8
[Peer]
PublicKey = <SUNUCU_PUBLIC_KEY>
Endpoint = sunucu.sirket.com:51820
# Şirket ağları
AllowedIPs = 10.10.0.0/24
# Şirket sunucuları (GitLab, Jira, Jenkins)
AllowedIPs = 172.16.1.0/24
# Şirketin kullandığı bulut provider private IP aralığı
AllowedIPs = 10.20.0.0/16
# Belirli bir sunucunun public IP'si (eski on-premise sistem)
AllowedIPs = 203.0.113.50/32
PersistentKeepalive = 25
CIDR Hesaplama Aracı ile AllowedIPs Optimizasyonu
Split tunneling yapılandırmasında en çok karşılaşılan sorun şudur: “Full tunneling istiyorum ama şu IP’leri hariç tutmak istiyorum.” Bu durumda CIDR matematği devreye girer.
WireGuard topluluğunun geliştirdiği wg-api ve cidr-utils araçları bu işi kolaylaştırır. Ama önce elle hesaplamayı anlayalım:
# 0.0.0.0/0 'dan belirli IP'leri çıkarmak için kullanışlı script
# Örnek: Tüm trafiği tünelle ama 192.168.1.0/24 yerel ağını hariç tut
# Python ile CIDR çıkarma
python3 << 'EOF'
import ipaddress
def exclude_from_cidr(base_network, exclude_networks):
"""
Bir CIDR bloğundan belirtilen subnetleri çıkar
"""
result = [ipaddress.ip_network(base_network)]
for exclude in exclude_networks:
exclude_net = ipaddress.ip_network(exclude)
new_result = []
for net in result:
if net.overlaps(exclude_net):
new_result.extend(net.address_exclude(exclude_net))
else:
new_result.append(net)
result = new_result
return sorted(result)
# Tüm IPv4 trafiği tünelle ama yerel ağları ve özel ağları hariç tut
base = "0.0.0.0/0"
excludes = [
"192.168.0.0/16", # Yerel ağ
"10.0.0.0/8", # Private range (dikkat: şirket ağı da buradan)
"172.16.0.0/12", # Private range
"169.254.0.0/16", # Link-local
"224.0.0.0/4", # Multicast
]
routes = exclude_from_cidr(base, excludes)
print("AllowedIPs = " + ", ".join(str(r) for r in routes))
EOF
Bu scriptin çıktısını doğrudan AllowedIPs değeri olarak kullanabilirsiniz.
Dinamik Routing ile İleri Seviye Split Tunneling
Statik IP tabanlı split tunneling çoğu zaman yeterli olur. Ancak bazı senaryolarda dinamik yaklaşım gerekir. Örneğin, çalışan hem evde hem ofiste hem de kafede çalışıyorsa her lokasyonda farklı routing ihtiyacı doğabilir.
#!/bin/bash
# /usr/local/bin/wg-split-tunnel.sh
# Lokasyona göre dinamik split tunneling yapılandırması
INTERFACE="wg0"
WG_CONFIG="/etc/wireguard/wg0.conf"
# Mevcut default gateway'i tespit et
DEFAULT_GW=$(ip route show default | awk '/default/ {print $3}' | head -1)
LOCAL_NETWORK=$(ip route show | grep -v default | grep "$(ip route show default | awk '{print $5}' | head -1)" | awk '{print $1}' | head -1)
echo "Varsayılan Gateway: $DEFAULT_GW"
echo "Yerel Ağ: $LOCAL_NETWORK"
# Şirket ağlarını tanımla
COMPANY_NETWORKS=(
"10.10.0.0/24" # VPN ağı
"172.16.0.0/12" # İç network
"192.168.10.0/24" # Ofis ağı (farklı subnet)
)
# WireGuard arayüzünü yeniden yapılandır
wg_reconfigure() {
local allowed_ips=$(IFS=', '; echo "${COMPANY_NETWORKS[*]}")
# Mevcut bağlantıyı durdur
wg-quick down $INTERFACE 2>/dev/null || true
# Yerel ağı AllowedIPs'ten çıkar (zaten doğrudan erişilebilir)
wg set $INTERFACE peer $(wg show $INTERFACE peers)
allowed-ips "$allowed_ips" 2>/dev/null || true
echo "Split tunneling güncellendi: $allowed_ips"
}
# NetworkManager hook olarak kullanım için
case "$1" in
"office")
COMPANY_NETWORKS+=("192.168.1.0/24")
wg_reconfigure
;;
"home")
wg_reconfigure
;;
"cafe")
# Kafede daha agresif: DNS de tünelle
COMPANY_NETWORKS+=("8.8.8.8/32" "8.8.4.4/32")
wg_reconfigure
;;
*)
wg_reconfigure
;;
esac
DNS Sızıntısı ve Çözümü
Split tunneling’in en büyük güvenlik riski DNS sızıntısıdır. VPN üzerinden giden trafiğin DNS sorguları bazen VPN dışına çıkabilir.
# DNS sızıntısını test et
# Önce mevcut durumu kontrol et
cat /etc/resolv.conf
# DNS sorgu yolunu izle
dig +short myip.opendns.com @resolver1.opendns.com
# WireGuard aktifken hangi DNS sunucusu kullanılıyor
systemd-resolve --status | grep "DNS Servers"
# DNS sızıntısı önleme - resolvconf ile
# wg0.conf içinde
cat >> /etc/wireguard/wg0.conf << 'EOF'
PostUp = resolvconf -a %i -m 0 -x
PostDown = resolvconf -d %i
EOF
# Veya systemd-resolved ile domain bazlı DNS yönlendirme
# Bu yaklaşım split DNS için idealdir
mkdir -p /etc/systemd/resolved.conf.d/
cat > /etc/systemd/resolved.conf.d/wireguard.conf << 'EOF'
[Resolve]
DNS=10.10.0.1
Domains=~sirket.local ~internal.sirket.com
# Tilde (~) işareti: Bu domain'ler için bu DNS sunucusunu kullan
# Diğer domain'ler için sistem varsayılanı kullanılır
EOF
systemctl restart systemd-resolved
Split DNS yapılandırmasıyla *.sirket.local sorguları iç DNS sunucusuna giderken google.com sorguları normal ISP DNS’ine gider. Bu hem güvenlik hem performans açısından optimaldır.
Windows İstemcisi İçin Split Tunneling
Linux odaklı anlattık ama Windows kullanıcıları da bu işi yapabilir:
# Windows'ta WireGuard config dosyası
# C:Program FilesWireGuardDataConfigurationssirket.conf
<#
[Interface]
PrivateKey = <WINDOWS_CLIENT_PRIVATE_KEY>
Address = 10.10.0.10/24
DNS = 10.10.0.1
[Peer]
PublicKey = <SUNUCU_PUBLIC_KEY>
Endpoint = sunucu.sirket.com:51820
AllowedIPs = 10.10.0.0/24, 172.16.0.0/12
PersistentKeepalive = 25
#>
# PowerShell ile mevcut routing tablosunu görüntüle
Get-NetRoute -InterfaceAlias "WireGuard Tunnel"
# Bağlantı sonrası routing ekle (gerekirse)
$wgInterface = Get-NetAdapter | Where-Object {$_.InterfaceDescription -like "*WireGuard*"}
New-NetRoute -InterfaceIndex $wgInterface.InterfaceIndex `
-DestinationPrefix "172.16.50.0/24" `
-NextHop "10.10.0.1"
Sorun Giderme
Gerçek hayatta her zaman bir şeyler ters gider. En sık karşılaşılan sorunlar ve çözümleri:
# 1. Hangi trafiğin VPN'den geçtiğini izle
sudo tcpdump -i wg0 -n
# 2. Routing tablosunu kontrol et
ip route show table main
ip route show table all | grep wg0
# 3. WireGuard istatistiklerini izle (hangi peer, ne kadar veri)
watch -n 1 'wg show all'
# 4. Belirli bir IP'nin hangi arayüzden geçtiğini test et
ip route get 172.16.1.50
ip route get 8.8.8.8
# 5. AllowedIPs çakışması kontrolü
# Aynı IP iki peer'da tanımlıysa WireGuard hata verir
wg show wg0 allowed-ips
# 6. MTU sorunlarını tespit et
# WireGuard overhead nedeniyle MTU ayarı önemli
ping -M do -s 1400 10.10.0.1
# Gerekirse MTU'yu düşür
ip link set mtu 1380 dev wg0
# Kalıcı yapmak için wg0.conf [Interface] bölümüne ekle:
# MTU = 1380
# 7. Firewall kurallarını kontrol et
iptables -L FORWARD -n -v
iptables -t nat -L POSTROUTING -n -v
Güvenlik Değerlendirmesi
Split tunneling kullanırken bazı güvenlik tradeoff’larını göz önünde bulundurmak gerekir.
Risk faktörleri:
- İstemci makinesi internet üzerinden saldırıya uğrarsa şirket ağına pivot noktası olabilir
- Zararlı yazılım hem şirket ağına hem internete erişim sağlayabilir
- Kullanıcı farkında olmadan hassas verileri VPN dışından iletebilir
Hafifletme yöntemleri:
- İstemci firewall’ını zorunlu kıl
- Endpoint security (EDR) çözümü kullan
- VPN bağlantısı aktifken LAN’dan WAN’a erişimi kısıtlayan host firewall kuralları ekle
- Network Access Control (NAC) ile cihaz sağlık kontrolü uygula
# İstemci tarafında ek güvenlik kuralları
# WireGuard bağlı olduğunda dışarıdan gelen bağlantıları engelle
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
Address = 10.10.0.2/24
PrivateKey = <PRIVATE_KEY>
DNS = 10.10.0.1
# WireGuard aktifken yeni inbound bağlantıları engelle
PostUp = iptables -I INPUT -m state --state NEW -i eth0 -j DROP
PostUp = iptables -I INPUT -m state --state ESTABLISHED,RELATED -i eth0 -j ACCEPT
PostDown = iptables -D INPUT -m state --state NEW -i eth0 -j DROP
PostDown = iptables -D INPUT -m state --state ESTABLISHED,RELATED -i eth0 -j ACCEPT
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = sunucu.sirket.com:51820
AllowedIPs = 10.10.0.0/24, 172.16.0.0/12
PersistentKeepalive = 25
EOF
Performans İzleme
Split tunneling kurulumunuzun beklediğiniz gibi çalışıp çalışmadığını düzenli olarak doğrulamanız gerekir:
#!/bin/bash
# /usr/local/bin/vpn-traffic-check.sh
# Split tunneling doğrulama scripti
echo "=== VPN Trafik Doğrulama ==="
echo ""
# VPN üzerinden gitmesi gereken bir IP'yi test et
VPN_TARGET="10.10.0.1"
INTERNET_TARGET="8.8.8.8"
# VPN hedefine yol
echo "Şirket ağına giden yol:"
ip route get $VPN_TARGET
echo ""
echo "İnternete giden yol (VPN'den geçmemeli):"
ip route get $INTERNET_TARGET
echo ""
echo "WireGuard bant genişliği istatistikleri:"
wg show wg0 | grep -E "(transfer|latest)"
echo ""
echo "Aktif bağlantılar (VPN arayüzü):"
ss -tunp | grep wg0 | head -10
Sonuç
WireGuard ile split tunneling, doğru yapılandırıldığında güçlü ve esnek bir ağ mimarisi sunar. AllowedIPs direktifinin hem gelen hem giden trafik için tek kaynak gerçeği olarak çalışması, karmaşık routing konfigürasyonlarını son derece sade bir şekilde ifade etmenizi sağlar.
Pratik olarak yapmanız gerekenler şu sırayla özetlenebilir: Şirketinizin hangi IP bloklarını kullandığını belgeleyin, bu blokları AllowedIPs listesine ekleyin, DNS sızıntısını split DNS ile önleyin ve son olarak ip route get komutuyla her şeyin beklediğiniz gibi davrandığını doğrulayın.
Performans gözlemlerinize göre MTU ayarlarına dikkat edin, özellikle yüksek paket kaybı yaşanan bağlantılarda 1380 değeri genellikle iyi başlangıç noktasıdır. Güvenlik tarafında ise split tunneling’in getirdiği riskleri endpoint güvenliği ve host firewall kurallarıyla dengelemeyi unutmayın.
Split tunneling mükemmel bir araç ama sihirli değil. Ağ topolojinizi iyi anlayan biri olarak bu konfigürasyonu düzenli gözden geçirmeyi alışkanlık haline getirin. Şirket ağları büyür, IP blokları değişir ve AllowedIPs listesi de buna paralel güncellenmek zorundadır.