Şirket VPN’ini açtığında tüm trafiğin o tünelden geçmesini istemiyorsun. Netflix izlerken bant genişliğini boşa harcamak, iş saatlerinde YouTube videoları için VPN sunucusunu meşgul etmek ya da yerel ağdaki yazıcıya erişirken trafiğin Almanya’daki bir sunucudan dönmesini beklemek… Bunların hepsi gereksiz. Split tunneling tam da bu sorunu çözer: hangi trafiğin VPN üzerinden gideceğini, hangisinin direkt internet bağlantısını kullanacağını sen belirlersin.
Split Tunneling Nedir ve Neden Gereklidir
Varsayılan OpenVPN yapılandırmasında sunucu istemciye bir redirect-gateway def1 direktifi gönderir ve istemcinin tüm trafiği VPN tünelinden geçirilir. Bu yaklaşım güvenlik açısından temiz görünse de pratikte ciddi sorunlar yaratır.
Düşün: 50 kişilik bir şirketin çalışanları evden çalışıyor. Herkesin YouTube, Spotify, sosyal medya trafiği VPN sunucusundan geçiyor. Hem bant genişliği maliyetin artar hem de VPN sunucunun yükü gereksiz yere şişer. Asıl iş trafiği bu gürültü altında boğulur.
Split tunneling ile sadece şirket kaynaklarına giden trafik (10.0.0.0/8, şirket domainleri, iç uygulamalar) VPN’den geçer. Geri kalan her şey doğrudan kullanıcının internet bağlantısından gider.
Kullanım senaryoları:
- Uzaktan çalışan ekipler için şirket iç ağı erişimi
- Belirli ülke kısıtlamalarını aşarken yerel hızlı bağlantıyı korumak
- Birden fazla VPN endpoint’i kullanan multi-site yapılar
- Geliştiricilerin hem şirket reposuna hem de harici servislere hızlı erişmesi
OpenVPN’in Yönlendirme Mantığı
Split tunneling’i doğru yapılandırmak için OpenVPN’in trafik yönlendirmeyi nasıl ele aldığını anlamak lazım.
OpenVPN sunucu tarafında iki ana direktif kullanır:
push "redirect-gateway def1": Tüm trafiği tünelden geçirir. Varsayılan “full tunnel” modudur.
push "route 192.168.10.0 255.255.255.0": Sadece belirtilen ağa giden trafiği tünelden geçirir. Split tunneling’in temel taşı budur.
İstemci tarafında ise route direktifi aynı işi yapar ama sunucudan push almak yerine istemci kendisi karar verir.
Sunucu Tarafı Yapılandırması
Önce temel bir OpenVPN sunucu yapılandırmasına bakalım. Ben bu örneklerde Ubuntu 22.04 üzerinde OpenVPN 2.5.x kullanıyorum.
# /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/server.crt
key /etc/openvpn/server/server.key
dh /etc/openvpn/server/dh.pem
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt
# Split tunneling icin bu satiri KALDIR veya yorum satiri yap
# push "redirect-gateway def1 bypass-dhcp"
# Sadece sirkete ait aglari tunden gectir
push "route 192.168.1.0 255.255.255.0"
push "route 10.10.0.0 255.255.0.0"
push "route 172.16.0.0 255.240.0.0"
push "dhcp-option DNS 192.168.1.53"
push "dhcp-option DOMAIN corp.sirket.local"
keepalive 10 120
cipher AES-256-GCM
auth SHA256
user nobody
group nogroup
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log-append /var/log/openvpn/openvpn.log
verb 3
Bu yapılandırmada dikkat et: redirect-gateway yok. Sadece belirli subnet’lere route push ediyoruz. İstemci bu push’ları aldığında o subnet’lere giden trafiği tünelden, geri kalanını kendi bağlantısından geçirir.
İstemci Tarafı Yapılandırması
İstemci tarafında da benzer bir yaklaşım var. Bazı durumlarda sunucudan push almak yerine istemcinin kendi route kararlarını vermesi daha esneklik sağlar.
# /etc/openvpn/client/client.conf (Linux istemci)
client
dev tun
proto udp
remote vpn.sirket.com 1194
resolv-retry infinite
nobind
ca ca.crt
cert client.crt
key client.key
cipher AES-256-GCM
auth SHA256
# Sunucudan gelen route push'larini kabul et
route-nopull # Bu satir OLMAMALI split tunneling icin
# Ya da elle route ekle (sunucu push kullanmiyorsa)
# route 192.168.1.0 255.255.255.0
# route 10.10.0.0 255.255.0.0
persist-key
persist-tun
verb 3
Dikkat: route-nopull direktifi sunucudan gelen tüm route push’larını engeller. Eğer sunucu tarafı split tunneling yapıyorsa ve istemcinin bu route’ları almasını istiyorsan bu satırı koyma.
IP Tables ile Sunucu Tarafı Yönlendirme
Sunucuda NAT ve yönlendirme doğru yapılandırılmazsa split tunneling çalışsa bile şirket ağına erişim olmaz.
#!/bin/bash
# /etc/openvpn/server/setup-routing.sh
# IP forwarding aktif et
echo 1 > /proc/sys/net/ipv4/ip_forward
# Bu ayari kalici yap
sed -i 's/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/' /etc/sysctl.conf
sysctl -p
# VPN istemcilerinin iç ağa erişimi için NAT
ETH_IFACE=$(ip route | grep default | awk '{print $5}')
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o $ETH_IFACE -j MASQUERADE
# Şirket ağına yönlendirme
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A FORWARD -i $ETH_IFACE -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
# Kurallari kalici hale getir
iptables-save > /etc/iptables/rules.v4
Bu scripti çalıştırdıktan sonra reboot’larda da çalışması için systemd servisi veya iptables-persistent paketi kullanabilirsin.
DNS Split Tunneling
Sadece IP bazlı split tunneling yeterli değil çoğu zaman. corp.sirket.local gibi internal domain’leri de çözümlemen gerekiyor. Ama harici DNS’in de hızlı çalışmasını istiyorsun.
Bunun için istemcide systemd-resolved veya dnsmasq ile domain bazlı DNS yönlendirme yapılabilir.
# systemd-resolved kullanan Ubuntu/Debian istemcilerde
# OpenVPN up scripti olarak çalıştır: /etc/openvpn/client/update-systemd-resolved.sh
#!/bin/bash
# VPN baglantisi kuruldugunda calisir
VPN_IFACE=$1
# Sirket DNS'ini sadece sirket domainleri icin kullan
resolvectl dns $VPN_IFACE 192.168.1.53
resolvectl domain $VPN_IFACE ~corp.sirket.local ~sirket.local
# Global DNS etkilenmesin
resolvectl default-route $VPN_IFACE false
echo "DNS split tunneling aktif: $VPN_IFACE"
Bu scripti OpenVPN config’inde çağırmak için:
# client.conf'a ekle
script-security 2
up /etc/openvpn/client/update-systemd-resolved.sh
down /etc/openvpn/client/update-systemd-resolved.sh
Böylece corp.sirket.local sorguları şirket DNS’ine gider, google.com sorgusu ise sistem DNS’ini (ya da 8.8.8.8’i) kullanır.
Belirli Uygulamalar İçin Split Tunneling (Policy-Based Routing)
Daha gelişmiş bir senaryo: belirli uygulamaların trafiğini VPN’den, diğerlerini direkt bağlantıdan geçirmek. Bu Linux’ta cgroups ve ip rule ile mümkün.
# Policy-based routing ile uygulama bazli split tunneling
# Yeni bir routing tablosu olustur
echo "200 vpn" >> /etc/iproute2/rt_tables
# VPN arayüzü için routing kuralı
ip route add default dev tun0 table vpn
ip route add 10.8.0.0/24 dev tun0 table vpn
# Belirli bir mark'a sahip paketleri vpn tablosuna yönlendir
ip rule add fwmark 0x1 table vpn
# Belirli uygulamalarin trafiğini işaretle (cgroup kullanarak)
mkdir -p /sys/fs/cgroup/net_cls/vpn_apps
echo 1 > /sys/fs/cgroup/net_cls/vpn_apps/net_cls.classid
# iptables ile cgroup trafiğini işaretle
iptables -t mangle -A OUTPUT -m cgroup --cgroup 1 -j MARK --set-mark 0x1
Bu yaklaşım çok güçlü ama karmaşık. Üretim ortamında test etmeden uygulamayı önermiyorum.
Windows İstemcilerinde Split Tunneling
Windows tarafında OpenVPN GUI veya OpenVPN Connect kullanıyorsan yapılandırma benzer ama birkaç fark var.
OpenVPN istemcisinin route’ları Windows’un routing tablosuna nasıl yazdığını görmek için:
# VPN bagli iken route tablosunu kontrol et
route print
# Aktif OpenVPN baglantisini sorgula
netsh interface show interface
# VPN baglantisi olusturduktan sonra route eklemek
# (test amaçli, kalici degil)
route add 192.168.1.0 mask 255.255.255.0 10.8.0.1 metric 5 if [VPN_INTERFACE_INDEX]
Windows istemci config dosyasında (client.ovpn) split tunneling için:
# Windows icin client.ovpn
client
dev tun
proto udp
remote vpn.sirket.com 1194
# Windows'ta metric degerini ayarla
route-metric 100
# Sirket agina giden trafiği tunden gectir
route 192.168.1.0 255.255.255.0
route 10.10.0.0 255.255.0.0
# redirect-gateway OLMAMALI
# Eger sunucu push ediyorsa sorun yok, push olmuyorsa elle ekle
resolv-retry infinite
nobind
ca ca.crt
cert client.crt
key client.key
cipher AES-256-GCM
auth SHA256
persist-key
persist-tun
verb 3
Sorun Giderme
Split tunneling çalışmıyorsa sırayla kontrol et.
Adım 1: Route tablosunu kontrol et
# Linux istemcide VPN bagliyken
ip route show
ip route show table main
# Beklenen cikti: sirket ag araligi tun0 üzerinden gitmeli
# 192.168.1.0/24 via 10.8.0.1 dev tun0
# 10.10.0.0/16 via 10.8.0.1 dev tun0
# Genel internet trafiği fiziksel arayüzden gitmeli
# default via 192.168.0.1 dev eth0
Adım 2: OpenVPN log’larını incele
# Sunucu logları
tail -f /var/log/openvpn/openvpn.log
# Push edilen route'lari görmek için verb seviyesini artır
# server.conf'ta: verb 4
# Istemci logları
journalctl -u openvpn-client@client -f
# Ya da direkt log dosyasından
tail -f /var/log/openvpn/client.log
Adım 3: Paket takibi
# Belirli bir hedefe giden trafiği izle
traceroute 192.168.1.1 # Şirket sunucusu - tün üzerinden gitmeli
traceroute 8.8.8.8 # Google DNS - direkt gitmeli
# tcpdump ile arayüz bazlı kontrol
sudo tcpdump -i tun0 -n host 192.168.1.1
sudo tcpdump -i eth0 -n host 8.8.8.8
Eğer traceroute 8.8.8.8 sonucunda ilk hop VPN sunucusu IP’si çıkıyorsa full tunnel modunda çalışıyorsun demektir. redirect-gateway push edilip edilmediğini tekrar kontrol et.
Güvenlik Konuları
Split tunneling güvenlik açısından tartışmalı bir konu. Bazı noktaları göz önünde bulundurman lazım.
Split tunneling riski ne zaman kabul edilebilir:
- Uç noktalarda (endpoint) güvenlik yazılımı var ve güncel
- Çalışanların kişisel cihazları değil şirket cihazları kullanılıyor
- VPN sadece iç kaynaklara erişim için, tüm trafik şifreleme için değil
- Uyumluluk gereksinimleri (compliance) full tunnel şart koşmuyorsa
Split tunneling’i tehlikeli yapan durumlar:
- Zararlı yazılım VPN tünelinden geçmeden C&C sunucularına bağlanabilir
- DNS leak riski var (yukarıdaki DNS split tunneling yapılandırmasını doğru yap)
- Saldırgan, istemcinin açık internet bağlantısını pivot point olarak kullanabilir
Güvenlik açısından hassas ortamlarda split tunneling yerine traffic shaping tercih edilebilir. Yani tüm trafik VPN’den geçer ama QoS ile kritik trafik önceliklendirilir.
Gerçek Dünya Senaryosu: 50 Kişilik Şirket
Şöyle bir senaryo üzerinden gidelim: İstanbul’daki merkez ofiste ERP sistemi, Git sunucusu ve dosya paylaşım sunucusu var. 50 çalışan uzaktan bağlanıyor. Her çalışanın günlük video konferans trafiği, bulut depolama senkronizasyonu var.
Hedef: Sadece ERP (192.168.1.100), Git (192.168.1.101), dosya sunucusu (192.168.1.102) ve iç DNS trafiği VPN’den geçsin. Zoom, Google Drive, genel internet direkt gitsin.
# /etc/openvpn/server/server.conf için ekleme
# ERP sunucusu
push "route 192.168.1.100 255.255.255.255"
# Git sunucusu
push "route 192.168.1.101 255.255.255.255"
# Dosya sunucusu
push "route 192.168.1.102 255.255.255.255"
# İç DNS ve domain controller
push "route 192.168.1.10 255.255.255.255"
push "route 192.168.1.11 255.255.255.255"
# Tüm ofis ağı yerine sadece sunucular - daha kısıtlı erişim
push "dhcp-option DNS 192.168.1.10"
push "dhcp-option DOMAIN corp.sirket.local"
Bu yapılandırmayla çalışan başına VPN bant genişliği tüketimi dramatik düşüyor. Ortalama bir çalışan günde 2-3 GB genel internet trafiği yaratırken şirkete özel trafik genellikle birkaç yüz MB’da kalıyor.
Yapılandırmayı Test Etme
Her değişiklikten sonra mutlaka test et.
# Tam bir split tunneling kontrol scripti
#!/bin/bash
echo "=== Split Tunneling Kontrol ==="
echo -e "n[1] Route tablosu:"
ip route | grep -E "(tun|default)"
echo -e "n[2] Sirkete giden trafik (tun üzerinden olmali):"
traceroute -n -m 3 192.168.1.1 2>/dev/null | head -5
echo -e "n[3] Genel internet trafiği (direkt olmali):"
traceroute -n -m 3 8.8.8.8 2>/dev/null | head -5
echo -e "n[4] DNS kontrolü:"
dig corp.sirket.local @192.168.1.10 +short 2>/dev/null || echo "Şirket DNS yanit vermiyor"
dig google.com +short 2>/dev/null | head -2
echo -e "n[5] VPN arayüzü IP:"
ip addr show tun0 2>/dev/null | grep "inet "
echo -e "n[6] Sirket sunucusu erişim testi:"
ping -c 2 -W 2 192.168.1.100 2>/dev/null && echo "OK" || echo "HATA"
Bu scripti her VPN bağlantısından sonra çalıştırma alışkanlığı edin. Özellikle OpenVPN versiyonu güncellendiğinde davranış değişebiliyor.
Systemd ile Otomatik Başlatma
Sunucu tarafı routing scriptlerinin her açılışta çalışması için:
# /etc/systemd/system/openvpn-routing.service
[Unit]
Description=OpenVPN Split Tunneling Routing Setup
After=network.target [email protected]
[Service]
Type=oneshot
ExecStart=/etc/openvpn/server/setup-routing.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable openvpn-routing.service
systemctl start openvpn-routing.service
# Durumu kontrol et
systemctl status openvpn-routing.service
Sonuç
Split tunneling, doğru yapılandırıldığında hem performans hem de kullanıcı deneyimi açısından büyük fark yaratıyor. Ama “doğru yapılandırıldığında” kısmını es geçme. DNS leak’i çözmeyen, route tablolarını test etmeyen bir split tunneling yapılandırması hem güvensiz hem de işlevsiz olur.
Özetlemek gerekirse: Sunucu tarafında redirect-gateway push’unu kaldır ve sadece gereken subnet’leri push et. DNS için systemd-resolved veya dnsmasq ile domain bazlı yönlendirme yap. IP forwarding ve iptables NAT’ı doğru ayarla. Her değişiklikten sonra traceroute ile test et.
Büyük ortamlarda bu yapılandırmayı tek tek istemciye push etmek yerine, kullanıcı gruplarına göre farklı profiller oluşturmak daha yönetilebilir bir yapı sağlıyor. OpenVPN’in client-config-dir direktifi ile her kullanıcı veya grup için özel route listesi tutabilirsin. Ama bu konu ayrı bir yazıyı hak ediyor.