Sunucularını yöneten herkes er ya da geç şu soruyla yüzleşir: “Bu porta kim erişebilmeli, kim erişememeli?” İşte tam bu noktada iptables devreye giriyor. Linux çekirdeğinin netfilter altyapısı üzerine inşa edilmiş bu araç, onlarca yıldır sistem yöneticilerinin en güvenilir güvenlik duvarı çözümü olmaya devam ediyor. UFW veya firewalld gibi soyutlama katmanları ne kadar kolaylık sağlasa da, altında dönen asıl mekanizmayı anlamak seni gerçek anlamda kontrolü elinde tutan biri yapar.
iptables Nedir ve Nasıl Çalışır?
iptables, Linux çekirdeğine gelen ve giden ağ paketlerini filtrelemek için kullanılan bir komut satırı aracıdır. Paketleri belirli kurallara göre değerlendirerek kabul eder, reddeder ya da başka bir hedefe yönlendirir.
Temel kavramları anlamadan kurallar yazmak, körü körüne iş yapmak demektir. Bu yüzden önce yapıyı kavrayalım.
Tablolar
iptables dört ana tablo üzerinde çalışır:
- filter: Varsayılan tablo. Paket filtreleme için kullanılır. Günlük işlemlerin büyük çoğunluğu buradadır.
- nat: Ağ adresi çevirme (Network Address Translation) işlemleri için. Port yönlendirme, maskeleme gibi senaryolarda kullanılır.
- mangle: Paket başlıklarını değiştirmek için. TTL değerini düzenlemek, özel işaretlemeler yapmak gibi ileri düzey senaryolarda karşına çıkar.
- raw: Bağlantı takibini devre dışı bırakmak için kullanılır. Çok özel durumlar dışında nadiren dokunursun.
Zincirler (Chains)
Her tablo içinde zincirler bulunur. filter tablosundaki üç temel zincir şunlardır:
- INPUT: Sunucuya gelen paketler. Dışarıdan senin makinene ulaşan her şey buradan geçer.
- OUTPUT: Sunucudan çıkan paketler. Senin makinenin dışarıya gönderdiği trafik.
- FORWARD: Sunucu üzerinden geçen ama sunucuya ait olmayan paketler. Router olarak çalışan sistemlerde önemlidir.
Hedefler (Targets)
Bir kural eşleştiğinde ne olacağını hedef belirler:
- ACCEPT: Paketi kabul et, geçişine izin ver.
- DROP: Paketi sessizce düşür, gönderene hiçbir şey söyleme.
- REJECT: Paketi reddet ve gönderene hata mesajı gönder.
- LOG: Paketi kayıt altına al, sonra bir sonraki kurala geç.
- MASQUERADE: NAT senaryolarında kaynak IP’yi gizle.
Temel Kullanım ve Sözdizimi
iptables komutunun genel yapısı şöyle:
iptables [-t tablo] KOMUT zincir [eşleşme kriterleri] [-j hedef]
Sık kullanılan parametreler:
- -A: Zincire kural ekle (append). Listenin sonuna ekler.
- -I: Zincire kural ekle (insert). Belirtilen pozisyona ekler, varsayılan olarak başa ekler.
- -D: Belirtilen kuralı sil.
- -L: Kuralları listele.
- -F: Zincirdeki tüm kuralları temizle (flush).
- -P: Zincirin varsayılan politikasını ayarla.
- -n: IP adreslerini ve portları numerik göster, DNS çözümlemesi yapma.
- -v: Ayrıntılı çıktı göster.
- –line-numbers: Kural numaralarını göster.
- -p: Protokol belirt (tcp, udp, icmp, all).
- -s: Kaynak IP adresi.
- -d: Hedef IP adresi.
- –dport: Hedef port.
- –sport: Kaynak port.
- -i: Gelen ağ arayüzü.
- -o: Giden ağ arayüzü.
Mevcut Kuralları Görme
Bir sunucuya el attığında ilk yapman gereken şey, mevcut durumu anlamak:
# Temel kural listesi
iptables -L
# Daha okunabilir, numerik çıktı
iptables -L -n -v
# Kural numaralarıyla birlikte
iptables -L -n -v --line-numbers
# Belirli bir zinciri listele
iptables -L INPUT -n -v --line-numbers
Çıktıda “pkts” (paket sayısı) ve “bytes” sütunları sana hangi kuralın ne kadar trafik gördüğünü söyler. Uzun süredir sıfırda kalan bir kural muhtemelen gereksizdir.
İlk Kuralları Yazalım: Pratik Senaryolar
Senaryo 1: SSH Erişimini Güvenceye Alma
Yeni bir VPS kuruyorsun. İlk iş SSH’ı koruma altına almak. Tüm dünyaya 22 numaralı portu açık bırakmak davet çıkarmak demektir.
# Önce kendi IP'nden SSH'a izin ver
iptables -A INPUT -p tcp -s 203.0.113.10 --dport 22 -j ACCEPT
# Diğer herkesten SSH'ı engelle
iptables -A INPUT -p tcp --dport 22 -j DROP
# Mevcut bağlantıları kesmemek için ESTABLISHED trafiğe izin ver
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Önemli uyarı: Bu sırayı ters yazarsan kendini de kilitlersin. Önce ACCEPT kuralları, sonra DROP kuralları gelmelidir. iptables kuralları yukarıdan aşağıya doğru işler, ilk eşleşen kural uygulanır.
Senaryo 2: Web Sunucusu için Temel Güvenlik Duvarı
Bir web sunucusunun olmazsa olmaz kuralları:
# Loopback arayüzüne her şeye izin ver
iptables -A INPUT -i lo -j ACCEPT
# Mevcut ve ilişkili bağlantıları kabul et
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# SSH erişimi (belirli IP bloğundan)
iptables -A INPUT -p tcp -s 10.0.0.0/8 --dport 22 -j ACCEPT
# HTTP ve HTTPS herkese açık
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# ICMP ping'e izin ver (tamamen kapatmak sorun çıkarır)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Diğer her şeyi engelle
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
Senaryo 3: Brute Force Koruması
SSH’a brute force saldırısı yapılıyorsa, dakikada belirli sayıda bağlantı denemesini kısıtlayabilirsin:
# Yeni SSH bağlantılarını izlemeye başla
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
# Son 60 saniyede 4'ten fazla deneme yapan IP'yi engelle
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
# Engele takılmayan bağlantılara izin ver
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
Bu yaklaşım fail2ban’a alternatif değil, tamamlayıcı bir katman olarak düşünülmelidir.
Senaryo 4: Belirli Bir IP’yi Tamamen Engelleme
Loglarında sürekli kötü niyetli istek gören bir IP adresi varsa:
# Tek IP engelleme
iptables -A INPUT -s 198.51.100.42 -j DROP
# Bir IP bloğunu engelleme
iptables -A INPUT -s 198.51.100.0/24 -j DROP
# Kuralı listenin başına ekle (daha hızlı işlenir)
iptables -I INPUT 1 -s 198.51.100.42 -j DROP
Senaryo 5: Port Yönlendirme (NAT)
Bir iç ağ makinesine dışarıdan erişim sağlamak gerektiğinde NAT tablosu devreye girer. Örneğin, dış IP’nin 8080 portuna gelen trafiği iç ağdaki bir sunucunun 80 portuna yönlendir:
# IP forwarding'i etkinleştir
echo 1 > /proc/sys/net/ipv4/ip_forward
# Dış porttan iç sunucuya yönlendirme
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
# Yönlendirilen paketin geçişine izin ver
iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
# Maskeleme (iç ağdan geri dönen paketler için)
iptables -t nat -A POSTROUTING -j MASQUERADE
Senaryo 6: Outbound Trafiği Kısıtlama
Bir uygulama sunucusunun yalnızca belirli harici servislere bağlanabilmesini istiyorsan:
# Loopback çıkışına izin ver
iptables -A OUTPUT -o lo -j ACCEPT
# DNS sorgularına izin ver
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
# HTTP/HTTPS çıkışına izin ver
iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
# Mevcut bağlantıların cevaplarına izin ver
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Diğer çıkış trafiğini engelle
iptables -P OUTPUT DROP
Bu tür kısıtlamalar özellikle veritabanı sunucularında veya hassas verileri işleyen sistemlerde kritik önem taşır.
Senaryo 7: Loglama
Hangi paketlerin düştüğünü görmek için loglama ekleyebilirsin:
# DROP'tan önce logla
iptables -A INPUT -j LOG --log-prefix "iptables-drop: " --log-level 4
# Ardından düşür
iptables -A INPUT -j DROP
# Logları görmek için
tail -f /var/log/syslog | grep "iptables-drop"
# veya
journalctl -f | grep "iptables-drop"
Dikkat: Her düşürülen paketi loglamak yoğun trafikte disk I/O’sunu ciddi ölçüde artırır. Üretim ortamında loglama kurallarını dikkatli kullan, belki yalnızca belirli portları veya belirli bir rate limit ile logla.
Kuralları Kalıcı Hale Getirme
iptables kuralları sistem yeniden başlatıldığında silinir. Kalıcı hale getirmek için farklı yöntemler vardır.
Debian/Ubuntu için:
# iptables-persistent paketini kur
apt-get install iptables-persistent
# Mevcut kuralları kaydet
netfilter-persistent save
# Kaydedilen dosyalar
cat /etc/iptables/rules.v4
cat /etc/iptables/rules.v6
RHEL/CentOS için:
# Kuralları kaydet
service iptables save
# veya
iptables-save > /etc/sysconfig/iptables
# Yükleme için
iptables-restore < /etc/sysconfig/iptables
Evrensel yöntem, iptables-save ve restore:
# Tüm kuralları dosyaya yaz
iptables-save > /root/iptables-backup-$(date +%Y%m%d).rules
# Kuralları geri yükle
iptables-restore < /root/iptables-backup-20240115.rules
Bu yedekleme alışkanlığını kesinlikle edinmelisin. Özellikle mevcut bir sunucuda kural değişikliği yapmadan önce mutlaka yedeğini al.
Kural Silme ve Sıfırlama
Yanlış bir kural yazdığında panik yapma:
# Kural numarasıyla silme
iptables -L INPUT --line-numbers
iptables -D INPUT 3
# Kuralı kopyalayıp -D ile silme (-A yerine -D yaz)
iptables -D INPUT -p tcp --dport 8080 -j ACCEPT
# Belirli bir zinciri temizle
iptables -F INPUT
# Tüm kuralları temizle
iptables -F
# NAT tablasını da temizle
iptables -t nat -F
# Politikaları sıfırla (kilitlenme yaşamamak için önce ACCEPT yap)
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -F
Uzak bir sunucuda çalışıyorsan ve bir şeylerin ters gideceğinden korkuyorsan şu numarayı kullanabilirsin: Değişikliklerini yap, ardından cron ile 5 dakika sonra tüm kuralları temizleyecek bir görev ayarla. Eğer her şey yolunda giderse cron görevini iptal et; giderse sistem kendiliğinden eski haline döner.
# 5 dakika sonra kuralları sıfırlayacak geçici güvenlik ağı
echo "iptables -F && iptables -P INPUT ACCEPT" | at now + 5 minutes
iptables ile ip6tables Arasındaki Fark
iptables yalnızca IPv4 trafiğini yönetir. IPv6 için ayrı olarak ip6tables kullanman gerekir. Sözdizimi neredeyse aynıdır:
# IPv6 SSH kuralı
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
# IPv6 kurallarını listele
ip6tables -L -n -v
# IPv6 kurallarını kaydet
ip6tables-save > /etc/iptables/rules.v6
Pek çok sysadmin IPv6’yı gözden kaçırır. Sunucun IPv6 adresi varsa ve ip6tables kurallarını tanımlamadıysan, IPv4 tarafında titizlikle kapattığın kapılar IPv6 tarafında açık kalabilir.
Özel Zincirler Oluşturma
Karmaşık kural setlerini yönetmek için özel zincirler işe yarar. Özellikle belli bir uygulama grubuna özel kuralları bir arada tutmak istediğinde:
# Yeni zincir oluştur
iptables -N WEB_RULES
# Zincire kural ekle
iptables -A WEB_RULES -p tcp --dport 80 -j ACCEPT
iptables -A WEB_RULES -p tcp --dport 443 -j ACCEPT
# Ana zincirden yeni zincire yönlendir
iptables -A INPUT -j WEB_RULES
# Zinciri listele
iptables -L WEB_RULES -n -v
# Zinciri sil (önce boşaltılmış ve referanslar kaldırılmış olmalı)
iptables -F WEB_RULES
iptables -X WEB_RULES
Sık Yapılan Hatalar ve Çözümleri
Kendini kilitleme: Uzak sunucuda çalışırken INPUT politikasını DROP yapmadan önce SSH kuralını eklemeyi unutmak. Çözüm: Her zaman önce izin kurallarını yaz, sonra kısıtlayıcı politikayı uygula.
Kural sırası hatası: Geniş bir DROP kuralının altına spesifik bir ACCEPT kuralı koymak. iptables ilk eşleşmede durur, alttaki kural hiç işlenmez. Kurallarda en spesifik olanlar en üste gelmeli.
ESTABLISHED trafiği unutmak: INPUT politikasını DROP yapıp ESTABLISHED,RELATED kuralını eklemeyi unutmak. Bu durumda başlattığın bağlantıların cevapları bile gelmez. Neredeyse her kural setinin başında bu kural olmalı.
IPv6’yı ihmal etmek: iptables kuralı yazdım, güvendeyim demek. ip6tables ayrı bir araç, ayrı ele alınmalı.
Kuralları kaydetmemeyi: Harika bir kural seti yazdın ama reboot sonrası hepsi gitti. Her önemli değişiklikten sonra iptables-save çalıştır.
iptables mi, nftables mi?
Modern Linux dağıtımlarında nftables, iptables’ın yerini almaya başladı. RHEL 8, Debian 10 ve Ubuntu 20.04’ten itibaren arka planda nftables çalışıyor olsa da, iptables komutları genellikle uyumluluk katmanı üzerinden hala çalışıyor.
Mevcut sistemlerde iptables bilgisi hala geçerliliğini koruyor ve uzun süre koruyacak. Yeni projeler kuruyorsan nftables’a da göz atmaya değer; daha tutarlı sözdizimi ve daha iyi performans sunuyor. Ama iptables’ı kavramadan nftables’a geçmek de pek önerilmez, temel kavramlar büyük ölçüde aynı.
Sonuç
iptables, öğrenme eğrisi biraz dik görünse de temelleri kavradıktan sonra son derece güçlü ve esnek bir araç. Tablolar, zincirler ve hedefler mantığını bir kez oturtunca neredeyse her senaryoya uygun kural yazabilirsin.
Pratikte önerdiğim yaklaşım şu şekilde: Her yeni sunucu kurulumunda önce minimum gereksinimleri belirle (hangi portlar açık olmalı, hangi IP’lerden erişim olmalı), ardından bu gereksinimler etrafında sıkı bir kural seti oluştur. Yeni bir servis eklendiğinde kural setini güncelle, eski servislerin kurallarını temizle. Kural setini düzenli olarak gözden geçir; aylarca hiç isabet almayan kural muhtemelen gereksizdir.
En önemli alışkanlık ise her şeyi belgelendirmek. iptables kurallarının yanına yorum ekleyemiyorsun, ama kural setini bir dosyaya kaydedip üstüne Bash yorum satırlarıyla açıklama ekleyebilirsin. Üç ay sonra neden o kuralı yazdığını hatırlamak için buna ihtiyacın olacak, güven bana.