NAT Yapılandırması: iptables ile IP Maskeleme

Küçük bir ofis ağı kuruyorsunuz, elinizde tek bir public IP var ama 20 tane bilgisayarı internete çıkarmak istiyorsunuz. Ya da evde bir Raspberry Pi’yi router olarak kullanmak, test ortamında sanal makineleri internete açmak istiyorsunuz. Tüm bu senaryoların ortak çözümü NAT, yani Network Address Translation. Linux’ta bu işi iptables ile yapıyoruz ve doğru yapılandırıldığında son derece güçlü, esnek bir yapı elde ediyorsunuz.

NAT Nedir ve Neden Gerekli?

NAT, birden fazla cihazın tek bir public IP adresi üzerinden internete çıkmasını sağlayan bir mekanizma. IPv4 adres havuzu tükenmeden önce de kullanışlıydı, şimdi ise zorunluluk haline geldi. Temel mantık şu: iç ağdaki paketler dışarı çıkarken kaynak IP adresi router’ın public IP’siyle değiştiriliyor, dönen cevaplar da orijinal iç IP’ye yönlendiriliyor.

IP Maskeleme (IP Masquerading) ise NAT’ın dinamik bir türü. SNAT’tan farkı şu: SNAT’ta çıkış IP’sini elle belirtirsiniz, Masquerading’de iptables bunu otomatik olarak belirler. Bu özellikle çıkış IP’niz dinamik olarak değiştiğinde (DHCP ile aldığınız bağlantılar, PPPoE, vb.) işe yarıyor. Statik IP’niz varsa SNAT daha deterministik ama Masquerading her iki durumda da çalışır.

Temel Gereksinimler

Başlamadan önce şunların hazır olması gerekiyor:

  • Linux kernel’da IP forwarding aktif olmalı
  • iptables kurulu ve çalışır durumda olmalı
  • En az iki ağ arayüzü: biri WAN (internete bakan), biri LAN (iç ağa bakan)
  • Root ya da sudo yetkisi

Sistemde iptables’ın kurulu olup olmadığını kontrol edelim:

# iptables versiyonunu kontrol et
iptables --version

# Mevcut kural setini listele
iptables -L -n -v

# NAT tablosunu görüntüle
iptables -t nat -L -n -v

IP Forwarding’i Aktifleştirmek

Bu adımı atlarsan hiçbir şey çalışmaz. Kernel, gelen paketleri başka bir arayüze iletmek için forwarding özelliğinin açık olmasını bekler.

# Anlık olarak aktifleştir (reboot sonrası kaybolur)
echo 1 > /proc/sys/net/ipv4/ip_forward

# Ya da sysctl ile
sysctl -w net.ipv4.ip_forward=1

# Mevcut durumu kontrol et
cat /proc/sys/net/ipv4/ip_forward
# 1 görürsen aktif

Bu ayarı kalıcı yapmak için /etc/sysctl.conf dosyasını düzenlemeniz gerekiyor:

# /etc/sysctl.conf dosyasını aç
nano /etc/sysctl.conf

# Şu satırı ekle veya uncomment yap:
net.ipv4.ip_forward = 1

# Değişiklikleri uygula
sysctl -p

# Doğrulama
sysctl net.ipv4.ip_forward

Bazı dağıtımlarda /etc/sysctl.d/ dizini altında ayrı dosya oluşturmanız daha temiz bir yaklaşım:

# Debian/Ubuntu tarzı sistemlerde
echo "net.ipv4.ip_forward = 1" > /etc/sysctl.d/99-ip-forward.conf
sysctl --system

Ağ Arayüzlerini Tanımak

NAT kuralı yazmadan önce hangi arayüzün ne olduğunu bilmemiz lazım:

# Tüm arayüzleri listele
ip addr show
# ya da eski yöntem
ifconfig -a

# Routing tablosuna bak, default gateway hangi arayüzden çıkıyor?
ip route show
# "default via 203.0.113.1 dev eth0" gibi bir çıktı görürsün
# eth0 senin WAN arayüzün

# Örnek senaryo için arayüzleri tanımlayalım
# WAN (internete bakan): eth0, public IP: 203.0.113.10
# LAN (iç ağ): eth1, private IP: 192.168.1.1/24

Temel IP Maskeleme Kuralı

En basit haliyle IP Maskeleme tek bir komutla yapılabilir:

# NAT tablosuna POSTROUTING chain'e Masquerade kuralı ekle
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Kuralın eklendi ğini doğrula
iptables -t nat -L POSTROUTING -v -n

Bu komut ne yapıyor? -t nat ile NAT tablosunu seçiyoruz. -A POSTROUTING ile paket çıkışından hemen önce devreye giren zincire kural ekliyoruz. -o eth0 ile sadece eth0 üzerinden çıkan paketleri hedefliyoruz. -j MASQUERADE ile kaynak IP’yi eth0’ın IP’siyle değiştiriyoruz.

Ancak bu kural yeterli değil. FORWARD chain’de de izin vermemiz gerekiyor:

# İç ağdan dışarıya çıkışa izin ver
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT

# Dışarıdan içeriye gelen established/related bağlantılara izin ver
iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

# FORWARD chain default policy'sini kontrol et
iptables -L FORWARD -n -v

Gerçek Dünya Senaryosu 1: Küçük Ofis Ağı

Diyelim ki 192.168.10.0/24 bloğunda 15 bilgisayar var, tek bir statik public IP üzerinden internete çıkacaklar. Bu durumda MASQUERADE yerine SNAT daha mantıklı ama ikisi de çalışır:

#!/bin/bash
# /etc/network/nat-setup.sh

# Değişkenleri tanımla
WAN_IF="eth0"
LAN_IF="eth1"
LAN_NET="192.168.10.0/24"
PUBLIC_IP="203.0.113.10"

# Önce mevcut kuralları temizle
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

# Default policy'leri ayarla
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Loopback trafiğine izin ver
iptables -A INPUT -i lo -j ACCEPT

# Established bağlantılara izin ver
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# SSH erişimi (yönetim için)
iptables -A INPUT -i $WAN_IF -p tcp --dport 22 -j ACCEPT

# LAN'dan gelen trafiğe izin ver
iptables -A INPUT -i $LAN_IF -j ACCEPT

# FORWARD kuralları
iptables -A FORWARD -i $LAN_IF -o $WAN_IF -j ACCEPT
iptables -A FORWARD -i $WAN_IF -o $LAN_IF -m state --state ESTABLISHED,RELATED -j ACCEPT

# NAT/Masquerade - Statik IP varsa SNAT daha iyi
iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j SNAT --to-source $PUBLIC_IP

# IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

echo "NAT yapılandırması tamamlandı"
iptables -t nat -L -n -v

Gerçek Dünya Senaryosu 2: Dinamik IP ile Masquerade

Ev kullanımı veya PPPoE bağlantısı gibi dinamik IP durumlarında MASQUERADE kullanmak daha uygun:

#!/bin/bash
# Dinamik IP için Masquerade yapılandırması

WAN_IF="ppp0"      # ya da eth0, hangi arayüz olursa
LAN_IF="eth1"
LAN_NET="10.0.0.0/24"

# IP Forwarding
sysctl -w net.ipv4.ip_forward=1

# Masquerade kuralı - IP değişse de otomatik güncellenir
iptables -t nat -A POSTROUTING -s $LAN_NET -o $WAN_IF -j MASQUERADE

# Forward kuralları
iptables -A FORWARD -i $LAN_IF -o $WAN_IF -j ACCEPT
iptables -A FORWARD -i $WAN_IF -o $LAN_IF -m state --state ESTABLISHED,RELATED -j ACCEPT

# Conntrack modülünün yüklü olduğundan emin ol
modprobe nf_conntrack
modprobe nf_conntrack_ipv4

echo "Masquerade aktif"

Port Yönlendirme (DNAT) ile NAT’ı Tamamlamak

Çoğu zaman sadece iç ağı internete çıkarmak değil, dışarıdan iç sunuculara erişimi de sağlamak gerekir. Örneğin iç ağdaki bir web sunucusunu dışarıya açmak:

# Dışarıdan gelen 80 portunu iç ağdaki web sunucusuna yönlendir
# 192.168.1.100 = iç web sunucusu
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80

# FORWARD chain'de buna izin ver
iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 80 -d 192.168.1.100 -j ACCEPT

# Birden fazla port için çoklu kural ya da multiport kullanımı
iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 192.168.1.100

# Farklı external port ile internal porta yönlendirme
# Dışarıdan 2222 portuna gelen bağlantıyı içerideki SSH sunucusuna yönlendir
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 2222 -j DNAT --to-destination 192.168.1.50:22
iptables -A FORWARD -i eth0 -o eth1 -p tcp --dport 22 -d 192.168.1.50 -j ACCEPT

Hairpin NAT: İç Ağdan Public IP’ye Erişim

Klasik bir sorun: iç ağdaki kullanıcılar, domain adı üzerinden erişmeye çalıştığında sunucu public IP’ye bağlanıp döngüye giriyor veya erişemiyor. Buna Hairpin NAT ya da NAT Loopback deniyor:

# İç ağdan public IP üzerinden erişimi sağla
# PUBLIC_IP = 203.0.113.10
# İç web sunucusu = 192.168.1.100

# PREROUTING: LAN'dan gelen ve public IP'ye giden trafiği yönlendir
iptables -t nat -A PREROUTING -i eth1 -d 203.0.113.10 -p tcp --dport 80 
    -j DNAT --to-destination 192.168.1.100:80

# POSTROUTING: Dönen trafiği masquerade et
iptables -t nat -A POSTROUTING -o eth1 -s 192.168.1.0/24 -d 192.168.1.100 
    -p tcp --dport 80 -j MASQUERADE

Kuralları Kaydetme ve Kalıcı Hale Getirme

iptables kuralları reboot sonrası kaybolur. Bunu önlemek için birkaç yöntem var:

Debian/Ubuntu’da iptables-persistent:

# Paketi kur
apt-get install iptables-persistent

# Mevcut kuralları kaydet
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

# Ya da interaktif kurulum sırasında kaydet
dpkg-reconfigure iptables-persistent

# Kaydedilen kuralları geri yükle
iptables-restore < /etc/iptables/rules.v4

RHEL/CentOS’ta iptables-services:

# Servis kurulu değilse kur
yum install iptables-services
# ya da
dnf install iptables-services

# Servisi etkinleştir
systemctl enable iptables
systemctl start iptables

# Kuralları kaydet
service iptables save
# Bu /etc/sysconfig/iptables dosyasına yazar

# Manuel kaydetme
iptables-save > /etc/sysconfig/iptables

Systemd service ile özel script:

# /etc/systemd/system/nat-rules.service dosyası oluştur
cat > /etc/systemd/system/nat-rules.service << 'EOF'
[Unit]
Description=NAT ve Masquerade Kuralları
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/bash /etc/network/nat-setup.sh
ExecStop=/sbin/iptables -t nat -F
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable nat-rules
systemctl start nat-rules

Bağlantı Takibi ve Sorun Giderme

NAT düzgün çalışmıyor mu? Sistematik bir şekilde debug edelim:

# Conntrack tablosunu görüntüle - aktif NAT bağlantılarını gösterir
conntrack -L
# ya da
cat /proc/net/nf_conntrack

# Belirli bir IP için bağlantıları filtrele
conntrack -L | grep 192.168.1.100

# NAT tablosunun tamamını verbose olarak gör
iptables -t nat -L -n -v --line-numbers

# Paket sayılarına bak - kural çalışıyor mu?
watch -n 1 'iptables -t nat -L -n -v'

# FORWARD chain'i kontrol et
iptables -L FORWARD -n -v

# Log ekleyerek debug yap
iptables -A FORWARD -j LOG --log-prefix "FORWARD: " --log-level 4
# Logları takip et
tail -f /var/log/kern.log | grep FORWARD

# tcpdump ile paketleri yakala
tcpdump -i eth0 -n host 203.0.113.10
tcpdump -i eth1 -n src net 192.168.1.0/24

Sık karşılaşılan sorunlar ve çözümleri:

  • “FORWARD DROP” sorunu: Default policy DROP ise FORWARD chain’de açıkça izin vermemişseniz trafik geçmez. iptables -L FORWARD ile kontrol edin.
  • ip_forward = 0: En yaygın hata. cat /proc/sys/net/ipv4/ip_forward ile kontrol edin.
  • Yanlış arayüz: -o eth0 yerine -o eth1 yazıldığında kural hiç çalışmaz. ip route ile doğrulayın.
  • Conntrack modülü yüklü değil: modprobe nf_conntrack ile yükleyin.
  • MTU sorunları: PPPoE bağlantılarda MSS clamping gerekebilir.
# PPPoE/VPN için MSS clamping
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN 
    -j TCPMSS --clamp-mss-to-pmtu

Performans ve Güvenlik Önerileri

NAT altında çalışan bir sistemde dikkat etmeniz gereken birkaç nokta var:

Conntrack tablosu boyutu: Yoğun trafik altında conntrack tablosu dolabilir. Bu durumda yeni bağlantılar reddedilir.

# Mevcut conntrack limiti
cat /proc/sys/net/netfilter/nf_conntrack_max

# Limiti artır
echo 131072 > /proc/sys/net/netfilter/nf_conntrack_max

# Ya da sysctl.conf ile kalıcı yap
echo "net.netfilter.nf_conntrack_max = 131072" >> /etc/sysctl.conf

# Mevcut kullanımı izle
cat /proc/sys/net/netfilter/nf_conntrack_count

# Zaman aşımı değerlerini optimize et
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=3600
sysctl -w net.netfilter.nf_conntrack_tcp_timeout_time_wait=30

Rate limiting ile kötüye kullanımı önleme:

# Bağlantı hızını sınırla
iptables -A FORWARD -p tcp --syn -m limit --limit 25/second --limit-burst 50 -j ACCEPT
iptables -A FORWARD -p tcp --syn -j DROP

# Belirli bir IP'den çok fazla bağlantıya izin verme
iptables -A FORWARD -p tcp -m connlimit --connlimit-above 100 -j REJECT

Belirli servisleri engelleme:

# Torrent portlarını engelle (örnek)
iptables -A FORWARD -i eth1 -o eth0 -p tcp --dport 6881:6889 -j DROP

# Belirli bir iç IP'nin sadece belirli portlara erişmesine izin ver
iptables -A FORWARD -s 192.168.1.50 -o eth0 -p tcp -m multiport 
    --dports 80,443,22 -j ACCEPT
iptables -A FORWARD -s 192.168.1.50 -o eth0 -j DROP

nftables ile Modern Yaklaşım

Eğer modern bir sistemdeyseniz nftables ile aynı işi çok daha temiz yapabilirsiniz. iptables hala yaygın ama yol haritası nftables’a doğru:

# nftables ile Masquerade
nft add table nat
nft add chain nat postrouting { type nat hook postrouting priority 100 ; }
nft add rule nat postrouting oif "eth0" masquerade

# nftables ile SNAT
nft add rule nat postrouting oif "eth0" snat to 203.0.113.10

# nftables ile Port Forwarding
nft add chain nat prerouting { type nat hook prerouting priority -100 ; }
nft add rule nat prerouting iif "eth0" tcp dport 80 dnat to 192.168.1.100

# Kuralları kaydet
nft list ruleset > /etc/nftables.conf
systemctl enable nftables

Sonuç

iptables ile IP Maskeleme, Linux’ta NAT’ın temel taşı. Tek komutla (-j MASQUERADE) iş görüyor gibi görünse de arkasında IP forwarding, FORWARD chain kuralları, conntrack mekanizması gibi birçok parça bir arada çalışıyor. Birini atlarsanız neden çalışmadığını anlamak zaman alabilir.

Özetlemek gerekirse kritik adımlar şunlar: ip_forward’ı açın, POSTROUTING’e MASQUERADE veya SNAT kuralını ekleyin, FORWARD chain’de gerekli izinleri verin, kuralları kalıcı hale getirin. Bu dört adımı doğru atarsanız geri kalanı zaten yerine oturuyor.

Gerçek üretim ortamında kullanıyorsanız conntrack limitlerini, MTU sorunlarını ve performans parametrelerini de gözden geçirmenizi öneririm. Özellikle yüzlerce eş zamanlı bağlantı olan ortamlarda conntrack tablosu beklenmedik anlarda dolabiliyor. Monitoring tarafında da conntrack -L | wc -l ile düzenli kontrol yapmak iyi bir alışkanlık.

nftables’a geçiş konusunda ise aceleci olmayın. iptables-nft (iptables’ın nftables backend üzerinde çalışan versiyonu) zaten çoğu modern sistemde varsayılan hale geldi ve eski scriptleriniz büyük ihtimalle değişiklik yapmadan çalışmaya devam ediyor.

Yorum yapın