OpenVPN ile Firewall Kuralları ve IPTables Entegrasyonu: Trafik Filtreleme ve Erişim Kontrolü
OpenVPN sunucunu kurdun, istemciler bağlanıyor, tünel çalışıyor. Peki ya güvenlik? Varsayılan kurulum genellikle “hepsi geçsin” mantığıyla çalışır ve bu bir felakete davet çıkarmaktan farksızdır. Gerçek dünyada OpenVPN ile iptables entegrasyonu, bir VPN kurulumunun olmazsa olmaz parçasıdır. Bu yazıda, üretim ortamında kullandığım konfigürasyonları ve gerçek senaryolardan öğrendiğim dersleri paylaşacağım.
Temelden Başlayalım: OpenVPN ve Netfilter Nasıl Çalışır?
OpenVPN, TUN veya TAP arayüzü üzerinden bir sanal ağ katmanı oluşturur. Linux çekirdeğinin Netfilter altyapısı ise bu trafiği yakalamak, filtrelemek ve yönlendirmek için devreye girer. iptables, bu Netfilter altyapısının kullanıcı tarafındaki yönetim aracıdır.
Bir paket OpenVPN tünelinden geçtiğinde şu yolu izler:
- İstemciden gelen şifreli paket fiziksel arayüzden (eth0) gelir
- OpenVPN bu paketi çözer ve tun0 arayüzüne enjekte eder
- Kernel PREROUTING, FORWARD ve POSTROUTING zincirlerinden geçirir
- Hedef sunucuya veya ağa iletilir
Bu akışı anlamak, doğru iptables kuralları yazmanın temelini oluşturur.
Sunucu Tarafı Temel Yapılandırma
OpenVPN sunucu konfigürasyonunuza bazı kritik direktifler eklemeniz gerekiyor. /etc/openvpn/server.conf dosyanızda şunlar olmalı:
# Temel sunucu konfigürasyonu
port 1194
proto udp
dev tun
# VPN subnet
server 10.8.0.0 255.255.255.0
# İstemciye varsayılan gateway olarak VPN'i göster
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
# IP forwarding zorunlu
push "route 192.168.1.0 255.255.255.0"
# Keepalive
keepalive 10 120
# Log seviyesi
verb 3
# İstemci bazlı konfigürasyon dizini
client-config-dir /etc/openvpn/ccd
# Script güvenlik seviyesi (iptables scriptleri için)
script-security 2
up /etc/openvpn/scripts/up.sh
down /etc/openvpn/scripts/down.sh
IP forwarding’i aktif etmeyi unutmayın, yoksa hiçbir şey çalışmaz:
# Anlık aktifleştirme
echo 1 > /proc/sys/net/ipv4/ip_forward
# Kalıcı hale getirme
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
# Doğrulama
cat /proc/sys/net/ipv4/ip_forward
# Çıktı: 1 olmalı
Temel iptables Kural Seti
Şimdi asıl meseleye gelelim. Sıfırdan, güvenli bir başlangıç noktası oluşturalım. Bu script’i /etc/openvpn/scripts/firewall-base.sh olarak kaydedin:
#!/bin/bash
# Değişkenler
VPN_IFACE="tun0"
WAN_IFACE="eth0"
VPN_SUBNET="10.8.0.0/24"
LAN_SUBNET="192.168.1.0/24"
VPN_PORT="1194"
# Mevcut kuralları temizle
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# Varsayılan politikaları ayarla (önce DROP, sonra izin ver)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Loopback trafiğine izin ver
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Kurulu bağlantılara izin ver (stateful inspection)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSH erişimine izin ver (yönetim için)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# OpenVPN portuna izin ver
iptables -A INPUT -p udp --dport $VPN_PORT -j ACCEPT
# VPN istemcilerinden gelen trafiği kabul et
iptables -A INPUT -i $VPN_IFACE -j ACCEPT
# NAT - VPN trafiğini internete çıkar
iptables -t nat -A POSTROUTING -s $VPN_SUBNET -o $WAN_IFACE -j MASQUERADE
# VPN'den internete forward izni
iptables -A FORWARD -i $VPN_IFACE -o $WAN_IFACE -j ACCEPT
# VPN'den LAN'a forward izni
iptables -A FORWARD -i $VPN_IFACE -o $WAN_IFACE -s $VPN_SUBNET -j ACCEPT
echo "Firewall kuralları yüklendi."
Scripti çalıştırılabilir yapın ve test edin:
chmod +x /etc/openvpn/scripts/firewall-base.sh
bash /etc/openvpn/scripts/firewall-base.sh
# Kuralları kontrol et
iptables -L -v -n
iptables -t nat -L -v -n
Gerçek Dünya Senaryosu 1: Departman Bazlı Erişim Kontrolü
Diyelim ki bir şirkette çalışıyorsunuz. Muhasebe departmanı sadece muhasebe sunucusuna, IT departmanı tüm iç ağa, misafir kullanıcılar ise sadece internete çıkabilecek. Bu senaryoyu OpenVPN’in CCD (Client Config Directory) özelliğiyle birlikte iptables ile çözebiliriz.
Önce CCD dosyalarını oluşturalım:
# IT departmanı kullanıcısı - tam erişim
cat > /etc/openvpn/ccd/it-user1 << EOF
ifconfig-push 10.8.1.1 10.8.1.2
iroute 192.168.0.0 255.255.255.0
EOF
# Muhasebe kullanıcısı - kısıtlı erişim
cat > /etc/openvpn/ccd/muhasebe-user1 << EOF
ifconfig-push 10.8.2.1 10.8.2.2
EOF
# Misafir kullanıcı - sadece internet
cat > /etc/openvpn/ccd/misafir-user1 << EOF
ifconfig-push 10.8.3.1 10.8.3.2
EOF
Şimdi buna karşılık gelen iptables kurallarını yazalım:
#!/bin/bash
# Departman bazlı erişim kontrolü
# IP aralıkları
IT_RANGE="10.8.1.0/24"
MUHASEBE_RANGE="10.8.2.0/24"
MISAFIR_RANGE="10.8.3.0/24"
# Hedef sunucular
MUHASEBE_SERVER="192.168.1.50"
IT_SERVERS="192.168.1.0/24"
# Muhasebe kullanıcıları: sadece muhasebe sunucusuna
iptables -A FORWARD -s $MUHASEBE_RANGE -d $MUHASEBE_SERVER -j ACCEPT
iptables -A FORWARD -s $MUHASEBE_RANGE -d $IT_SERVERS -j DROP
iptables -A FORWARD -s $MUHASEBE_RANGE -o eth0 -j ACCEPT
# IT kullanıcıları: her yere
iptables -A FORWARD -s $IT_RANGE -j ACCEPT
# Misafir kullanıcılar: sadece internet, iç ağa yasak
iptables -A FORWARD -s $MISAFIR_RANGE -d 192.168.0.0/16 -j DROP
iptables -A FORWARD -s $MISAFIR_RANGE -d 10.0.0.0/8 -j DROP
iptables -A FORWARD -s $MISAFIR_RANGE -d 172.16.0.0/12 -j DROP
iptables -A FORWARD -s $MISAFIR_RANGE -o eth0 -j ACCEPT
# Kuralları kaydet
iptables-save > /etc/iptables/rules.v4
echo "Departman bazlı kurallar uygulandı."
Gerçek Dünya Senaryosu 2: Port Bazlı Filtreleme
Bazı durumlarda VPN kullanıcılarının belirli portlara erişimini kısıtlamanız gerekir. Mesela, geliştirici ekibinin veritabanı portuna direkt erişimi olmasın, sadece uygulama sunucusu üzerinden geçsin:
# MySQL portuna (3306) direkt erişimi engelle
# Sadece uygulama sunucusundan (192.168.1.100) geçişe izin ver
iptables -A FORWARD -i tun0 -d 192.168.1.200 -p tcp --dport 3306
-s 10.8.0.0/24 ! -s 192.168.1.100 -j DROP
# Redis portunu sadece backend grubuna aç
iptables -A FORWARD -i tun0 -d 192.168.1.201 -p tcp --dport 6379
-s 10.8.10.0/24 -j ACCEPT
iptables -A FORWARD -i tun0 -d 192.168.1.201 -p tcp --dport 6379 -j DROP
# HTTP/HTTPS'e tüm VPN kullanıcıları erişebilir
iptables -A FORWARD -i tun0 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -i tun0 -p tcp --dport 443 -j ACCEPT
# Diğer tüm portları varsayılan olarak engelle
# (Bu kural en sona gelecek)
iptables -A FORWARD -i tun0 -j DROP
Rate Limiting ile Brute Force Koruması
OpenVPN portuna yapılan brute force saldırılarını sınırlamak için rate limiting kullanın. Bu özellikle UDP’de biraz farklı çalışır:
# OpenVPN portuna bağlantı sayısını sınırla
# Dakikada 10'dan fazla yeni bağlantıyı engelle
iptables -A INPUT -p udp --dport 1194
-m recent --name OVPN --set
iptables -A INPUT -p udp --dport 1194
-m recent --name OVPN --rcheck --seconds 60 --hitcount 10
-j LOG --log-prefix "OVPN_RATELIMIT: " --log-level 4
iptables -A INPUT -p udp --dport 1194
-m recent --name OVPN --rcheck --seconds 60 --hitcount 10
-j DROP
# SSH için de benzer koruma (tcp daha yaygın saldırı hedefi)
iptables -A INPUT -p tcp --dport 22
-m recent --name SSH --set
iptables -A INPUT -p tcp --dport 22
-m recent --name SSH --update --seconds 60 --hitcount 5
-j LOG --log-prefix "SSH_BRUTEFORCE: "
iptables -A INPUT -p tcp --dport 22
-m recent --name SSH --update --seconds 60 --hitcount 5
-j DROP
OpenVPN Script Entegrasyonu: up.sh ve down.sh
OpenVPN’in bağlantı olaylarına bağlı script çalıştırma özelliğini kullanarak kuralları dinamik olarak yönetebilirsiniz:
#!/bin/bash
# /etc/openvpn/scripts/up.sh
# VPN arayüzü kalktığında çalışır
VPN_IFACE=$1
WAN_IFACE="eth0"
VPN_SUBNET="10.8.0.0/24"
# NAT kuralını ekle
iptables -t nat -A POSTROUTING -s $VPN_SUBNET -o $WAN_IFACE -j MASQUERADE
# Forward kurallarını ekle
iptables -A FORWARD -i $VPN_IFACE -o $WAN_IFACE -j ACCEPT
iptables -A FORWARD -i $WAN_IFACE -o $VPN_IFACE -m state
--state RELATED,ESTABLISHED -j ACCEPT
# Log başlat
logger -t openvpn-up "VPN interface $VPN_IFACE is up, firewall rules applied"
exit 0
#!/bin/bash
# /etc/openvpn/scripts/down.sh
# VPN arayüzü kapandığında çalışır
VPN_IFACE=$1
WAN_IFACE="eth0"
VPN_SUBNET="10.8.0.0/24"
# Eklenen kuralları kaldır
iptables -t nat -D POSTROUTING -s $VPN_SUBNET -o $WAN_IFACE -j MASQUERADE
iptables -D FORWARD -i $VPN_IFACE -o $WAN_IFACE -j ACCEPT
iptables -D FORWARD -i $WAN_IFACE -o $VPN_IFACE -m state
--state RELATED,ESTABLISHED -j ACCEPT
logger -t openvpn-down "VPN interface $VPN_IFACE is down, firewall rules removed"
exit 0
Her iki dosyayı da çalıştırılabilir yapın:
chmod +x /etc/openvpn/scripts/up.sh
chmod +x /etc/openvpn/scripts/down.sh
Kuralları Kalıcı Hale Getirme
Sunucu yeniden başladığında kuralların silinmesini önlemek için iptables-persistent kullanın:
# Debian/Ubuntu
apt-get install iptables-persistent
# Mevcut kuralları kaydet
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
# RHEL/CentOS sistemlerde
service iptables save
# veya
iptables-save > /etc/sysconfig/iptables
Sistemd ile entegrasyon için bir servis dosyası da oluşturabilirsiniz:
cat > /etc/systemd/system/iptables-restore.service << 'EOF'
[Unit]
Description=Restore iptables rules
Before=network-pre.target
Wants=network-pre.target
[Service]
Type=oneshot
ExecStart=/sbin/iptables-restore /etc/iptables/rules.v4
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
systemctl enable iptables-restore
systemctl start iptables-restore
Loglama ve İzleme
Güvenlik kuralları yazmak yeterli değil, ne olduğunu da takip etmeniz gerekir. iptables loglama ile şüpheli trafiği kayıt altına alın:
# Engellenen forward trafiğini logla
iptables -N VPN_LOG_DROP
iptables -A VPN_LOG_DROP -j LOG
--log-prefix "VPN_BLOCKED: "
--log-level 4
--log-tcp-options
--log-ip-options
iptables -A VPN_LOG_DROP -j DROP
# Bu zinciri kullan
iptables -A FORWARD -i tun0 -j VPN_LOG_DROP
# Log dosyasını izle
tail -f /var/log/kern.log | grep "VPN_BLOCKED"
# Ya da rsyslog ile ayrı bir dosyaya yaz
echo ':msg, contains, "VPN_BLOCKED" /var/log/vpn-blocked.log'
> /etc/rsyslog.d/vpn.conf
systemctl restart rsyslog
Anlık kural istatistiklerini görmek için:
# Paket ve byte sayacıyla birlikte kuralları listele
iptables -L FORWARD -v -n --line-numbers
# Belirli zinciri sıfırla (sayaçları temizle)
iptables -Z FORWARD
# NAT tablosunu kontrol et
iptables -t nat -L -v -n
# Aktif bağlantıları gör (conntrack gerekli)
conntrack -L | grep 10.8.0
Yaygın Sorunlar ve Çözümleri
Sorun: VPN bağlanıyor ama internet çıkışı yok.
# Kontrol listesi
# 1. IP forwarding aktif mi?
sysctl net.ipv4.ip_forward
# 2. MASQUERADE kuralı var mı?
iptables -t nat -L POSTROUTING -v -n
# 3. Hangi arayüz üzerinden çıkılıyor?
ip route get 8.8.8.8
# 4. Doğru arayüz adını kullanıyor musunuz?
ip link show | grep -E "eth|ens|enp"
Sorun: VPN tüneli üzerinden iç ağa ulaşılamıyor.
# Forward kurallarını test et
iptables -C FORWARD -i tun0 -o eth0 -j ACCEPT
# Kural varsa çıkış kodu 0, yoksa 1
# Paket izleme için (kısa süreli, dikkatli kullanın)
iptables -A FORWARD -i tun0 -j LOG --log-prefix "FWD_DEBUG: "
# Sonra log'a bakın ve kuralı silin
iptables -D FORWARD -i tun0 -j LOG --log-prefix "FWD_DEBUG: "
Sorun: Belirli bir istemciye özel kural çalışmıyor.
# İstemci IP'sini kontrol et
cat /var/log/openvpn/openvpn-status.log
# Kural sırasını kontrol et (ilk eşleşen kazanır)
iptables -L FORWARD -v -n --line-numbers
# Test için belirli kaynaktan ping at
ping -I tun0 192.168.1.1
nftables ile Modern Yaklaşım
Yeni sistemlerde iptables’ın yerini nftables alıyor. OpenVPN ile nftables kullanmak istiyorsanız temel yapı şöyle:
# /etc/nftables.conf
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state established,related accept
tcp dport 22 accept
udp dport 1194 accept
iifname "tun0" accept
}
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
iifname "tun0" oifname "eth0" accept
# Departman bazlı kural örneği
iifname "tun0" ip saddr 10.8.1.0/24 accept
iifname "tun0" ip saddr 10.8.2.0/24 ip daddr 192.168.1.50 accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
table ip nat {
chain postrouting {
type nat hook postrouting priority 100;
ip saddr 10.8.0.0/24 oifname "eth0" masquerade
}
}
Aktifleştirmek için:
nft -f /etc/nftables.conf
systemctl enable nftables
systemctl start nftables
Güvenlik Kontrol Listesi
Konfigürasyonunuzu canlıya almadan önce şunları doğrulayın:
- Varsayılan politika DROP’tur:
iptables -P INPUT DROPveiptables -P FORWARD DROPayarlı olmalı - ESTABLISHED,RELATED kuralı var: Aksi halde yanıt paketleri de engellenir
- NAT doğru arayüzde: MASQUERADE kuralında doğru WAN arayüzü kullanılmalı
- IP forwarding aktif:
sysctl net.ipv4.ip_forwarddeğeri 1 olmalı - Kurallar kalıcı: Yeniden başlatma sonrası kurallar kaybolmamalı
- Log mekanizması çalışıyor: Engellenen paketler kayıt altına alınmalı
- CCD dizini yazılabilir:
/etc/openvpn/ccdOpenVPN prosesi tarafından okunabilmeli - Script güvenlik seviyesi:
script-security 2ayarlı olmalı - IPv6 de filtreleniyor: ip6tables ile IPv6 trafiği de kontrol altında olmalı
Sonuç
OpenVPN ile iptables entegrasyonu, başlangıçta karmaşık görünse de mantığı kavradığınızda son derece güçlü bir erişim kontrol mekanizması haline gelir. Temel prensip şu: önce her şeyi engelle, sonra ihtiyaç duyulan trafiğe izin ver. Bu “default deny” yaklaşımı, gözden kaçan bir açığın tam erişime yol açması riskini minimuma indirir.
Gerçek üretim ortamında dikkat etmeniz gereken en önemli nokta, kural sırasıdır. iptables kuralları sırayla işlenir ve ilk eşleşmede durur. Bu yüzden spesifik kurallarınızı genel kurallardan önce yazmalısınız. Ayrıca değişiklik yapmadan önce mevcut kuralları mutlaka yedekleyin (iptables-save > backup.rules) ve uzak bir sunucuda çalışıyorsanız değişiklikleri test ederken kendinizi kilitlememeye dikkat edin.
Loglama kısmını ihmal etmeyin. Bir güvenlik olayı yaşandığında ne olduğunu anlayabilmenizin tek yolu kayıtlardır. fail2ban gibi araçlarla iptables loglarını otomatik engelleme sistemlerine entegre etmek de bir sonraki adım olarak değerlendirilebilir. Güvenlik katmanlı bir iştir ve her katman önemlidir.
