iptables Kural Seti Hata Ayıklama Teknikleri

Firewall kuralları yazdınız, servisi yeniden başlattınız, ama trafik hala istendiği gibi akmıyor. Ya da tam tersi, engellenmesi gereken bir şey geçiyor. iptables ile ciddi zaman geçiren her sistem yöneticisinin yaşadığı o sinir bozucu an. Sorun bazen tek bir kuralın sırası, bazen bir chain politikası, bazen de hiç beklemediğiniz bir ESTABLISHED kuralı oluyor. Bu yazıda iptables kural setlerini sistematik olarak nasıl hata ayıklayabileceğinizi, hangi araçları kullanacağınızı ve gerçek dünya senaryolarında nasıl yaklaşacağınızı ele alacağız.

Temel Durum Tespiti: Nereye Bakmalısınız?

Hata ayıklamaya başlamadan önce mevcut durumu net olarak görmeniz gerekiyor. Çoğu kişi iptables -L ile işe başlar ama bu komut varsayılan haliyle oldukça yetersiz bilgi verir.

# Temel listeleme - yetersiz
iptables -L

# Daha kullanışlı: satır numaraları, sayaçlar ve IP adresleri sayısal formatta
iptables -L -n -v --line-numbers

# Belirli bir zinciri inceleme
iptables -L INPUT -n -v --line-numbers

# NAT tablosunu görme
iptables -t nat -L -n -v --line-numbers

# Mangle tablosunu görme
iptables -t mangle -L -n -v --line-numbers

Buradaki -v parametresi çok kritik. Paket ve byte sayaçlarını gösterir. Bir kuralın hiç eşleşme yaşayıp yaşamadığını bu sayaçlardan anlarsınız. Eğer bir kuralın sayacı sıfırda duruyorsa, ya o kurala hiç trafik gelmiyor ya da kural daha önce başka bir kuralla eşleşiyor demektir.

# Sayaçları sıfırla ve izlemeye başla
iptables -Z INPUT
# Ardından trafiği tetikle, sonra kontrol et
iptables -L INPUT -n -v --line-numbers

-Z komutu tüm sayaçları sıfırlar. Test trafiğini göndermeden önce sayaçları sıfırlarsanız, hangi kuralın devreye girdiğini çok daha net görürsünüz.

LOG Hedefi: En Güçlü Hata Ayıklama Aracı

iptables’ın en değerli hata ayıklama özelliği LOG hedefidir. Paketleri düşürmeden veya kabul etmeden önce kernel log’una kayıt yazabilirsiniz.

# INPUT chain'ine gelen her şeyi logla (dikkatli kullanın, çok log üretir)
iptables -I INPUT 1 -j LOG --log-prefix "IPTABLES-DEBUG: " --log-level 4

# Belirli bir kaynaktan gelen trafiği logla
iptables -I INPUT 1 -s 192.168.1.100 -j LOG --log-prefix "SUSPECT-HOST: " --log-level 4

# Belirli porta gelen trafiği logla
iptables -I INPUT 1 -p tcp --dport 443 -j LOG --log-prefix "HTTPS-IN: " --log-level 4

# Logları gerçek zamanlı izle
tail -f /var/log/kern.log | grep "IPTABLES-DEBUG"
# ya da
journalctl -f -k | grep "IPTABLES-DEBUG"

LOG hedefinin güzel yanı, paketi durdurmaz. Paket LOG kuralına çarpınca log yazılır, ardından bir sonraki kurala geçilir. Bu sayede trafiği kesmeden izleme yapabilirsiniz.

Gerçek bir senaryo düşünün: Bir web sunucunuz var ve port 8080’e gelen bağlantılar ulaşmıyor. Şüphelendiğiniz kuralın öncesine ve sonrasına LOG eklersiniz:

# Şüpheli DROP kuralından önce
iptables -I INPUT 5 -p tcp --dport 8080 -j LOG --log-prefix "BEFORE-DROP: "

# Şüpheli DROP kuralından sonra (bir sonraki kural pozisyonuna)
iptables -I INPUT 7 -p tcp --dport 8080 -j LOG --log-prefix "AFTER-DROP: "

Eğer “BEFORE-DROP” logunu görüyor ama “AFTER-DROP” görmüyorsanız, 6. kural paketinizi yiyor demektir.

TRACE Hedefi: Paketi Adım Adım Takip Etme

Daha ileri düzey bir teknik olan TRACE, bir paketin hangi kurallardan geçtiğini adım adım gösterir. Bunun için iptable_raw modülüne ihtiyacınız var.

# Modülü yükle
modprobe ipt_LOG

# TRACE kuralını raw tablosuna ekle
iptables -t raw -A PREROUTING -p tcp --dport 80 -j TRACE
iptables -t raw -A OUTPUT -p tcp --dport 80 -j TRACE

# Logları izle
journalctl -f -k | grep "TRACE"

TRACE çıktısı oldukça ayrıntılıdır ve şöyle görünür:

TRACE: raw:PREROUTING:rule:1 IN=eth0 OUT= SRC=192.168.1.50 DST=10.0.0.1 PROTO=TCP DPT=80
TRACE: mangle:PREROUTING:policy:1 IN=eth0 OUT= SRC=192.168.1.50 DST=10.0.0.1 PROTO=TCP DPT=80
TRACE: nat:PREROUTING:policy:1 IN=eth0 OUT= SRC=192.168.1.50 DST=10.0.0.1 PROTO=TCP DPT=80
TRACE: filter:INPUT:rule:3 IN=eth0 OUT= SRC=192.168.1.50 DST=10.0.0.1 PROTO=TCP DPT=80

Bu çıktıdan paketin hangi tablodan, hangi chain’den, hangi kural numarasıyla eşleştiğini görürsünüz. Karmaşık kural setlerinde nerede takıldığını anlamak için biçilmiş kaftan.

Önemli uyarı: TRACE çok yoğun log üretir ve production sistemlerde performansı ciddi şekilde etkileyebilir. Sadece test ortamında veya çok kısa süreli olarak kullanın.

Kural Sırası Sorunları ve Nasıl Tespit Edilir

iptables kuralları sırayla işlenir ve ilk eşleşen kazanır. Bu yüzden kural sırası hata ayıklamada en sık karşılaşılan sorundur.

Klasik bir senaryo: Belirli bir IP’ye erişim vermek istiyorsunuz ama genel bir REJECT kuralınız var.

# Mevcut durumu görelim
iptables -L INPUT -n -v --line-numbers

# Şöyle bir çıktı görürsünüz:
# 1   ACCEPT  all  -- 0.0.0.0/0  0.0.0.0/0  state RELATED,ESTABLISHED
# 2   REJECT  all  -- 0.0.0.0/0  0.0.0.0/0  reject-with icmp-host-prohibited
# 3   ACCEPT  tcp  -- 192.168.1.50  0.0.0.0/0  tcp dpt:22

# Sorun: 3. kural hiç işlenmez çünkü 2. kural her şeyi reddeder
# Çözüm: 3. kuralı 2. kuralın önüne taşı
iptables -D INPUT 3
iptables -I INPUT 2 -p tcp -s 192.168.1.50 --dport 22 -j ACCEPT

Başka bir yaygın sorun, ESTABLISHED/RELATED kuralının eksik olmasıdır:

# Bu kural olmadan kurulu bağlantıların yanıt paketleri düşer
iptables -I INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -I OUTPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT

conntrack ile Bağlantı Durumu Takibi

Durum tabanlı güvenlik duvarlarında sorunların büyük kısmı bağlantı takibinden kaynaklanır. conntrack aracı bu konuda çok değerli bilgiler sunar.

# conntrack-tools paketini kur
apt-get install conntrack   # Debian/Ubuntu
yum install conntrack-tools  # RHEL/CentOS

# Aktif bağlantıları listele
conntrack -L

# Belirli bir IP'nin bağlantılarını izle
conntrack -L | grep 192.168.1.100

# Gerçek zamanlı bağlantı olaylarını izle
conntrack -E

# TCP bağlantılarını durumlarıyla listele
conntrack -L -p tcp

# Bağlantı sayısını göster
conntrack -C

Gerçek dünya senaryosu: Bir kullanıcı VPN üzerinden bağlanıyor ama belirli bir süre sonra bağlantısı kopuyor. conntrack ile şunu yapabilirsiniz:

# Conntrack zaman aşımı değerlerini kontrol et
cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
# Genellikle 432000 saniye (5 gün) - bu normalde sorun değil

# UDP için zaman aşımı (VPN için kritik)
cat /proc/sys/net/netfilter/nf_conntrack_udp_timeout
cat /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream

# Conntrack tablosu doluysa bağlantılar düşer
cat /proc/sys/net/netfilter/nf_conntrack_count    # Mevcut bağlantı sayısı
cat /proc/sys/net/netfilter/nf_conntrack_max      # Maksimum limit

# Limit yeterse geçici artırma
sysctl -w net.netfilter.nf_conntrack_max=131072

tcpdump ile Firewall Öncesi ve Sonrası Paket Analizi

Bazen iptables log’larından yeterli bilgi alamazsınız. tcpdump ile daha düşük seviyede analiz yapabilirsiniz.

# Belirli interface'e gelen 80 portlu trafiği yakala
tcpdump -i eth0 -n port 80

# Belirli kaynak IP'den gelen trafiği yakala ve detaylı göster
tcpdump -i eth0 -n -v src 192.168.1.100

# Paketleri dosyaya kaydet ve sonra analiz et
tcpdump -i eth0 -w /tmp/capture.pcap port 443
tcpdump -r /tmp/capture.pcap -n -v

# SYN paketlerini izle (yeni bağlantı denemeleri)
tcpdump -i eth0 -n 'tcp[tcpflags] & (tcp-syn) != 0'

# DROP edilen paketleri görmek için (RST veya gelen SYN + giden hiçbir şey yok)
tcpdump -i eth0 -n 'tcp[tcpflags] & (tcp-syn) != 0 and not tcp[tcpflags] & (tcp-ack) != 0'

tcpdump’ın özel bir kullanımı: Paketin firewall’a ulaşıp ulaşmadığını kontrol etme. Eğer tcpdump paketi görüyor ama bağlantı kurulmuyorsa sorun iptables’ta. Eğer tcpdump paketi görmüyorsa sorun daha önce, belki routing’de.

iptables-save ve Kural Setini Analiz Etme

Aktif kural setinin tam görüntüsünü almak için iptables-save kullanın. Bu komut, kuralları restore edilebilir formatta gösterir ve karmaşık setlerde büyük resmi görmenizi sağlar.

# Tüm kuralları kaydet
iptables-save > /tmp/current-rules.txt

# Sadece filter tablosunu kaydet
iptables-save -t filter > /tmp/filter-rules.txt

# İçeriği incele
cat /tmp/current-rules.txt

# Kural sayısını say
iptables-save | grep -c "^-A"

# Belirli bir IP'ye ait kuralları bul
iptables-save | grep "192.168.1.100"

# REJECT veya DROP kurallarını listele
iptables-save | grep -E "REJECT|DROP"

Bu yaklaşım özellikle şunu ortaya çıkarır: iptables -L çıktısında göremediğiniz -m modülleri ve genişletilmiş eşleşme parametreleri iptables-save çıktısında net olarak görünür.

Gerçek Dünya Senaryosu: Web Sunucusuna Erişilemiyor

Bir e-ticaret sitesinin sunucusuna dışarıdan port 443 ile erişilemiyor. Sistematik hata ayıklama adımları:

# 1. Adım: Mevcut kuralları kontrol et
iptables -L INPUT -n -v --line-numbers
iptables -L FORWARD -n -v --line-numbers

# 2. Adım: 443 portunu dinleyen servis var mı?
ss -tlnp | grep :443
# ya da
netstat -tlnp | grep :443

# 3. Adım: 443 portuna geçici LOG ekle
iptables -I INPUT 1 -p tcp --dport 443 -j LOG --log-prefix "443-DEBUG: "

# 4. Adım: Dışarıdan bağlantı dene, logu kontrol et
tail -f /var/log/kern.log | grep "443-DEBUG"

# 5. Adım: Log görünüyorsa iptables'a paket geliyor demek
# Şimdi hangi kuralla eşleştiğini bul
iptables -t raw -A PREROUTING -p tcp --dport 443 -j TRACE
journalctl -k | grep "TRACE" | tail -50

# 6. Adım: Log görünmüyorsa routing sorunu olabilir
ip route show
ip addr show

# 7. Adım: Test için geçici ACCEPT kuralı ekle
iptables -I INPUT 2 -p tcp --dport 443 -j ACCEPT
# Bağlantı sağlandıysa sorun kural setindeydi, kalıcı çözüme geç

Gerçek Dünya Senaryosu: İçeriden Dışarıya Trafik Sorunları

Bir şirket ağında iç sunucu internet erişimi istemiyor veya NAT düzgün çalışmıyor.

# NAT kurallarını kontrol et
iptables -t nat -L -n -v --line-numbers

# MASQUERADE kuralı var mı?
iptables -t nat -L POSTROUTING -n -v

# IP forwarding aktif mi?
cat /proc/sys/net/ipv4/ip_forward
# 0 ise problem bu
sysctl -w net.ipv4.ip_forward=1

# FORWARD chain politikası ve kuralları
iptables -L FORWARD -n -v --line-numbers

# Gerçek zamanlı NAT bağlantılarını izle
conntrack -E -t nat

# Belirli bir iç IP'nin dışarıya çıkışını test et
# Sunucuda tcpdump çalıştır
tcpdump -i eth0 -n src 10.0.0.50

# İç sunucudan paket gönder
ping -c 4 8.8.8.8

# Paket dış interface'e çıkıyor mu?
tcpdump -i eth1 -n src 10.0.0.50

ipset ile Büyük Kural Setlerinde Hata Ayıklama

Yüzlerce IP adresi içeren kural setlerinde tek tek kontrol etmek imkansız hale gelir. ipset burada hayat kurtarır.

# Mevcut ipset listelerini göster
ipset list

# Belirli bir set'in içeriğini göster
ipset list BLOCKED-IPS

# Bir IP'nin set'te olup olmadığını kontrol et
ipset test BLOCKED-IPS 192.168.1.100
echo $?  # 0 ise var, 1 ise yok

# Set istatistiklerini göster
ipset list -t

# Geçici debug set'i oluştur
ipset create DEBUG-IPS hash:ip
ipset add DEBUG-IPS 192.168.1.100

# Bu IP'ye özel loglama yap
iptables -I INPUT 1 -m set --match-set DEBUG-IPS src -j LOG --log-prefix "IPSET-DEBUG: "

Kural Setini Test Etme: Hata Yapmadan Değişiklik Yapma

Production’da değişiklik yaparken kendinizi kitlememeniz için güvenli test yöntemi:

# Mevcut kuralları yedekle
iptables-save > /root/iptables-backup-$(date +%Y%m%d-%H%M%S).txt

# Test kuralını ekle
iptables -I INPUT 1 -s 10.0.0.0/8 -j ACCEPT

# Eğer bağlantı kesilirse otomatik geri alma için at job kullan
at now + 5 minutes << 'EOF'
iptables-restore < /root/iptables-backup-20240101-120000.txt
EOF

# Test başarılıysa at job'u iptal et
atq  # job numarasını bul
atrm <job-numarasi>

# Değişikliği kalıcı yap
service iptables save  # RHEL/CentOS
iptables-save > /etc/iptables/rules.v4  # Debian/Ubuntu

Bu teknik özellikle uzaktan yönetimde kritik. Yanlış bir kural ekleyip SSH bağlantısı kesilirse, 5 dakika içinde sistem otomatik olarak eski haline döner.

Yaygın Hatalar ve Tanı Yöntemleri

Zincirlerin varsayılan politikası: DROP veya REJECT olarak ayarlanmış ve izin kuralı eksik.

# Politikaları kontrol et
iptables -L | grep "^Chain"
# Chain INPUT (policy DROP) görüyorsanız dikkatli olun

# Politikayı geçici ACCEPT'e al (test için)
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Modül eksikliği: Bazı kurallar için kernel modülleri gerekir.

# Yüklü modülleri kontrol et
lsmod | grep -i iptable
lsmod | grep -i netfilter
lsmod | grep -i conntrack

# Eksik modülü yükle
modprobe xt_conntrack
modprobe xt_state
modprobe ipt_recent

Interface adı değişikliği: Yeni kernel sürümlerinde eth0 yerine enp3s0 gibi isimler kullanılıyor.

# Mevcut interface isimlerini kontrol et
ip link show
ip addr show

# Kural setinde eski interface adı kullanılıyor olabilir
iptables -L INPUT -n -v | grep eth0  # Artık bu interface olmayabilir

Performans Sorunları ve Kural Optimizasyonu

Çok sayıda kural varsa firewall performansı düşebilir. Bunu tespit etmek için:

# Kural başına paket/byte istatistiklerini gör
iptables -L INPUT -n -v --line-numbers

# Çok düşük eşleşme sayılı kuralları tespit et (gereksiz kurallar)
iptables -L -n -v | awk '$1 == "0" && $2 == "0" {print NR, $0}'

# Kural setinin işlenme süresini test et
time iptables -L -n > /dev/null

# En çok eşleşen kuralları başa taşıyarak optimizasyon yap
# Önce sayaçları sıfırla
iptables -Z

# Yük altında bir süre bekle
sleep 300

# Hangi kurallar en çok tetikleniyor?
iptables -L INPUT -n -v | sort -rn -k1

Sonuç

iptables hata ayıklaması sistematik bir yaklaşım gerektiriyor. Rastgele kurallar silip eklemek yerine önce durumu anlamak, doğru araçları kullanmak çok zaman kazandırıyor. LOG hedefi günlük hata ayıklamanın temel taşı, TRACE ise gerçekten köklü sorunlar için güçlü bir araç. conntrack ile bağlantı durumlarını, tcpdump ile paket akışını, iptables-save ile de tüm kural setini bütünsel olarak görmek hata ayıklamayı dramatik biçimde kolaylaştırıyor.

En önemli alışkanlık: Production’da değişiklik yapmadan önce her zaman yedek alın ve at komutuyla otomatik geri alma planı hazırlayın. Kendinizi sistemin dışında bırakmak, özellikle gece yarısı, hiç hoş olmuyor. Sayaçları izleme alışkanlığı edinin, sıfır eşleşme sayılı kurallar genellikle ya gereksiz ya da yanlış yazılmış kurallardır. Zamanla kural setinizi temizleyip optimize etmek hem güvenliği hem de performansı artırıyor.

Yorum yapın