iptables Nedir: Temel Kavramlar ve Çalışma Mantığı

Linux sunucularını yönetirken eninde sonunda karşılaşacağınız en kritik konulardan biri ağ güvenliğidir. Ve bu güvenliğin kalbinde, yıllardır Linux’un vazgeçilmez güvenlik duvarı aracı olan iptables yer almaktadır. Bir web sunucusu kuruyorsanız, bir VPN noktası yapılandırıyorsanız ya da sadece sunucunuzu port taramalarından korumak istiyorsanız, iptables’ı anlamak artık bir seçenek değil, bir zorunluluktur.

iptables Nedir?

iptables, Linux çekirdeğinin netfilter çerçevesi üzerine inşa edilmiş bir paket filtreleme ve ağ adresi çevirisi (NAT) aracıdır. Basitçe söylemek gerekirse, sunucunuza gelen veya sunucunuzdan çıkan her ağ paketini inceleyebilir, bu paketlere kurallarınıza göre izin verebilir ya da reddedebilirsiniz.

iptables, 1998 yılında Rusty Russell tarafından geliştirilmiş ve o günden bu yana sayısız Linux sunucusunun ilk savunma hattı olmuştur. Günümüzde yerini kısmen nftables‘a bırakmış olsa da iptables hâlâ milyonlarca üretim ortamında aktif olarak çalışmaktadır. Üstelik nftables’ı anlamak için bile iptables kavramlarını bilmek büyük avantaj sağlar.

Şunu net söyleyelim: iptables bir servis değildir. Çekirdek içinde çalışan netfilter’e kural eklemek için kullanılan bir kullanıcı alanı aracıdır. Kurallarınız çekirdek seviyesinde işlenir, bu yüzden performansı son derece yüksektir.

Temel Mimari: Tablolar, Zincirler ve Kurallar

iptables’ı anlamanın en iyi yolu, onun üç katmanlı yapısını kavramaktır: tablolar, zincirler ve kurallar. Bu hiyerarşiyi bir kez oturtursanız, geri kalanı çok daha anlamlı gelecektir.

Tablolar (Tables)

iptables’ta dört ana tablo vardır ve her biri farklı bir işlev için tasarlanmıştır:

  • filter: En çok kullanılan tablodur. Paketlere izin vermek veya engellemek için kullanılır. Herhangi bir tablo belirtmeden kural yazdığınızda varsayılan olarak bu tablo kullanılır.
  • nat: Ağ adresi çevirisi işlemleri için kullanılır. IP maskeleme, port yönlendirme gibi senaryolarda devreye girer.
  • mangle: Paket başlıklarını değiştirmek için kullanılır. TTL değeri değiştirme, QoS işaretleme gibi gelişmiş senaryolarda ihtiyaç duyulur.
  • raw: Bağlantı takibinden muaf tutmak istediğiniz paketler için kullanılır. Performans açısından kritik ortamlarda işe yarar.

Büyük çoğunluğunuz günlük işlerinizde sadece filter ve nat tablolarıyla işinizi halledeceksiniz.

Zincirler (Chains)

Her tablo, paketlerin geçtiği noktaları temsil eden zincirler içerir. filter tablosundaki üç temel zincir şunlardır:

  • INPUT: Sunucuya gelen paketler için. Birisi SSH ile bağlanmaya çalıştığında, paketi ilk karşılayan zincir budur.
  • OUTPUT: Sunucudan çıkan paketler için. Sunucunuzun dışarıya yaptığı bağlantılar buradan geçer.
  • FORWARD: Sunucunuzdan geçerek başka bir hedefe yönlendirilen paketler için. Router olarak çalışan ya da VPN sunucusu olan sistemlerde kritik önem taşır.

nat tablosu ise şu zincirleri içerir:

  • PREROUTING: Paket sisteme girmeden önce, yönlendirme kararı verilmeden işlenir.
  • POSTROUTING: Paket sistemden çıkmadan hemen önce işlenir.
  • OUTPUT: Yerel süreçlerin ürettiği paketler için kullanılır.

Kurallar (Rules) ve Hedefler (Targets)

Kurallar, zincirlerin içindeki trafik yönetim direktifleridir. Her kural belirli kriterleri (kaynak IP, hedef port, protokol vs.) kontrol eder ve eşleşme olduğunda bir hedef belirtir.

En sık kullanılan hedefler şunlardır:

  • ACCEPT: Pakete izin ver, geçmesine izin ver.
  • DROP: Paketi sessizce düşür, gönderene herhangi bir yanıt verme.
  • REJECT: Paketi reddet ama gönderene bir hata mesajı gönder.
  • LOG: Paketi logla ama zincir işlemeye devam et.
  • MASQUERADE: Kaynak IP adresini otomatik olarak değiştir (NAT için).

DROP ile REJECT arasındaki fark pratikte çok önemlidir. DROP kullanırsanız saldırgan portun açık mı kapalı mı olduğunu bilemez, bağlantı zaman aşımı beklemek zorunda kalır. REJECT ise “bağlantı reddedildi” mesajı döner, daha礼kibardır ama biraz daha fazla bilgi sızdırır.

Paket Yolculuğu: Netfilter Hook Noktaları

Bir paketin sisteme girişinden çıkışına kadar olan yolculuğunu anlamak, doğru zinciri doğru tabloda kullanabilmek için şarttır.

Gelen bir paket şu yolculuğu yapar:

Ağ arayüzüne ulaşır -> raw PREROUTING -> mangle PREROUTING -> nat PREROUTING -> Yönlendirme kararı verilir. Eğer paket bu sunucu içinse: mangle INPUT -> filter INPUT -> Yerel süreç. Eğer paket başka bir yere yönlendirilecekse: mangle FORWARD -> filter FORWARD -> mangle POSTROUTING -> nat POSTROUTING -> Ağa çıkar.

Yerel bir sürecin ürettiği paket:

Yerel süreç -> raw OUTPUT -> mangle OUTPUT -> nat OUTPUT -> Yönlendirme kararı -> mangle POSTROUTING -> nat POSTROUTING -> Ağa çıkar.

Bu yolculuğu anladığınızda, “neden kuralım çalışmıyor?” sorusunun cevabını bulmak çok kolaylaşır.

İlk Adımlar: Temel iptables Komutları

Teoriden pratiğe geçelim. Önce mevcut durumu görmekle başlayalım:

# Mevcut kuralları listele (filter tablosu varsayılan)
iptables -L -v -n

# Belirli bir tabloyu listele
iptables -t nat -L -v -n

# Kural numaralarıyla birlikte listele
iptables -L -v -n --line-numbers

Buradaki parametreleri açıklayalım:

  • -L: Zincirleri ve kuralları listele
  • -v: Ayrıntılı çıktı (byte sayacı, paket sayacı, arayüz bilgisi)
  • -n: IP adreslerini ve portları sayısal formatta göster, DNS çözümlemesi yapma
  • –line-numbers: Her kuralın önüne numara ekle, kural silmede işe yarar

Temel Kural Yazımı

iptables kural sözdizimi ilk bakışta karmaşık görünebilir ama mantığını bir kez kavrayınca oldukça tutarlı bir yapıya sahip olduğunu göreceksiniz.

# SSH bağlantılarına izin ver (22. port)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# HTTP ve HTTPS trafiğine izin ver
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Belirli bir IP adresinden gelen tüm trafiği engelle
iptables -A INPUT -s 192.168.1.100 -j DROP

# Yerel loopback arayüzüne izin ver (bu çok önemli, unutmayın!)
iptables -A INPUT -i lo -j ACCEPT

# Kurulu bağlantılara ve ilişkili paketlere izin ver
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Kural sözdizimindeki temel parametreler:

  • -A: Zincirin sonuna kural ekle (Append)
  • -I: Zincirin başına veya belirtilen pozisyona kural ekle (Insert)
  • -D: Kural sil (Delete)
  • -p: Protokol (tcp, udp, icmp, all)
  • -s: Kaynak IP veya ağ
  • -d: Hedef IP veya ağ
  • -i: Gelen ağ arayüzü (eth0, ens3 vb.)
  • -o: Çıkan ağ arayüzü
  • –dport: Hedef port
  • –sport: Kaynak port
  • -j: Hedef (ACCEPT, DROP, REJECT, LOG vb.)

Varsayılan Politikalar (Default Policies)

iptables’ın en güçlü özelliklerinden biri varsayılan politikalardır. Hiçbir kuralla eşleşmeyen paketlere ne yapılacağını belirler.

İki yaklaşım vardır:

Whitelist yaklaşımı (Önce hepsini engelle, sadece izin verdiklerini geçir):

# Varsayılan politikaları DROP olarak ayarla
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Sonra sadece istediğin trafiğe izin ver
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

DİKKAT: Uzak bir sunucuda INPUT zincirini DROP’a çekmeden önce SSH kuralınızın doğru çalıştığından mutlaka emin olun. Aksi takdirde sunucunuza erişiminizi kaybedebilirsiniz. Bunun acısını bir kez yaşayan bir sysadmin olarak söylüyorum: konsol erişiminiz yoksa bu çok kötü bir gün olabilir.

Durum Takibi: Stateful Firewall Özelliği

Modern iptables kullanımının en kritik parçalarından biri bağlantı durumu takibidir. Bu özellik sayesinde iptables sadece tek tek paketlere bakmak yerine bağlantının genel durumunu değerlendirebilir.

Bağlantı durumları:

  • NEW: Yeni bir bağlantı başlatma paketi
  • ESTABLISHED: Daha önce kurulmuş bir bağlantıya ait paket
  • RELATED: Mevcut bir bağlantıyla ilişkili yeni bağlantı (FTP veri bağlantısı gibi)
  • INVALID: Hiçbir bağlantıya ait olmayan, geçersiz paket
# Stateful firewall için temel yapı
# Önce geçersiz paketleri düşür
iptables -A INPUT -m state --state INVALID -j DROP

# Kurulu bağlantılara ve ilişkililerine izin ver
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Yeni bağlantılar için kurallar
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT

Bu yapı sayesinde sunucunuzdan dışarıya yaptığınız bağlantıların yanıt paketleri otomatik olarak içeri alınır. OUTPUT zincirinde her servis için ayrı kural yazmanız gerekmez.

Gerçek Dünya Senaryosu: Web Sunucusu Güvenliği

Diyelim ki bir web sunucusu yönetiyorsunuz. Sadece HTTP, HTTPS ve SSH trafiğine izin vermek, diğer her şeyi engellemek istiyorsunuz. İşte bunu sıfırdan nasıl yapacağınız:

#!/bin/bash
# Web sunucusu için temel firewall kuralları

# Önce mevcut kuralları temizle
iptables -F
iptables -X
iptables -Z

# Varsayılan politikaları ayarla
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Loopback arayüzüne izin ver
iptables -A INPUT -i lo -j ACCEPT

# Geçersiz paketleri düşür
iptables -A INPUT -m state --state INVALID -j DROP

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

# ICMP (ping) - isteğe bağlı ama monitoring için gerekli
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# SSH - sadece belirli IP'den (opsiyonel ama önerilen)
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.0/24 -j ACCEPT

# HTTP ve HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Log: Engellenen paketleri kaydet
iptables -A INPUT -j LOG --log-prefix "IPT-DROPPED: " --log-level 4

echo "Firewall kuralları uygulandı."

Bu script’te önce her şeyi temizleyip sıfırdan başladığımıza dikkat edin. -F mevcut kuralları siler, -X kullanıcı tanımlı zincirleri siler, -Z sayaçları sıfırlar.

NAT ve Port Yönlendirme

Özellikle ağ geçidi olarak çalışan sunucularda NAT kuralları vazgeçilmezdir. Klasik bir senaryo: iç ağdaki bir sunucuya dışarıdan erişim sağlamak.

# IP yönlendirmeyi aktif et (kalıcı için /etc/sysctl.conf'a ekleyin)
echo 1 > /proc/sys/net/ipv4/ip_forward

# Dışarıdan 8080 portuna gelen trafiği iç ağdaki 192.168.1.10:80'e yönlendir
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.10:80

# İç ağdan çıkan trafiği maskele (IP maskeleme)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

# Yönlendirilen trafiğe FORWARD zincirinde izin ver
iptables -A FORWARD -p tcp -d 192.168.1.10 --dport 80 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

Kuralları Kalıcı Hale Getirme

iptables kuralları sistem yeniden başlatıldığında kaybolur. Kalıcı hale getirmek için birkaç yöntem vardır:

Debian/Ubuntu sistemlerde:

# iptables-persistent paketini kur
apt-get install iptables-persistent

# Mevcut kuralları kaydet
netfilter-persistent save

# Ya da doğrudan dosyaya yaz
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6

RHEL/CentOS sistemlerde:

# Kuralları kaydet
service iptables save

# Ya da iptables-services ile
yum install iptables-services
systemctl enable iptables
iptables-save > /etc/sysconfig/iptables

Manuel yöntem (tüm dağıtımlar için):

# /etc/rc.local veya bir systemd service unit'i aracılığıyla
# kuralları yükleyen script oluştur
iptables-restore < /etc/iptables/rules.v4

Özel Zincirler Oluşturma

Kurallarınız çoğaldıkça yönetmesi zorlaşır. Özel zincirler, kuralları mantıksal gruplara ayırmanıza olanak tanır:

# SSH brute-force koruması için özel zincir
iptables -N SSH_RULES

# Yeni zincire kurallar ekle
iptables -A SSH_RULES -m recent --name SSH --set
iptables -A SSH_RULES -m recent --name SSH --update --seconds 60 --hitcount 4 -j DROP
iptables -A SSH_RULES -j ACCEPT

# Ana zincirden özel zincire yönlendir
iptables -A INPUT -p tcp --dport 22 -j SSH_RULES

Bu yaklaşım özellikle karmaşık kural setlerinde okunabilirliği ciddi ölçüde artırır.

Kural Sırası: Neden Önemlidir?

iptables kuralları yukarıdan aşağıya sırayla işlenir ve bir eşleşme bulunduğunda sonraki kurallar atlanır. Bu yüzden kural sırası son derece kritiktir.

Kötü sıralama örneği:

# Bu kural tüm trafiği düşürür
iptables -A INPUT -j DROP

# Bu kural hiçbir zaman çalışmaz çünkü bir üstteki her şeyi engeller
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Doğru sıralama:

# Önce izin ver
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Sonra engelle
iptables -A INPUT -j DROP

Mevcut bir kural setine belirli bir pozisyona kural eklemek için -I kullanın:

# 1. pozisyona kural ekle (en başa)
iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT

# 3. pozisyona kural ekle
iptables -I INPUT 3 -s 10.0.0.0/8 -j DROP

Hata Ayıklama: LOG Hedefi

Bir şeyler beklendiği gibi çalışmadığında LOG hedefi en değerli araçlardan biridir:

# Belirli trafiği logla
iptables -A INPUT -p tcp --dport 443 -j LOG --log-prefix "HTTPS-TRAFFIC: " --log-level 6

# Logları izle
tail -f /var/log/syslog | grep "HTTPS-TRAFFIC"
# ya da
journalctl -f | grep "HTTPS-TRAFFIC"

LOG hedefi paketi durdurmaz, sadece kaydeder ve zincir işlemeye devam eder. Bu yüzden genellikle DROP kuralının hemen üstüne koyulur.

Sık Yapılan Hatalar

Yıllarca iptables kural setleriyle uğraşmış biri olarak en çok karşılaştığım hataları paylaşayım:

  • Loopback’i unutmak: -A INPUT -i lo -j ACCEPT olmadan pek çok yerel servis düzgün çalışmaz. MySQL gibi yerel socket kullanan servisler bile bundan etkilenebilir.
  • ESTABLISHED,RELATED kuralını atlamak: Bu kural olmazsa sunucudan yaptığınız her dışarı bağlantının yanıtı engellenir.
  • IPv6’yı unutmak: iptables sadece IPv4 içindir. IPv6 için ip6tables ayrıca yapılandırılmalıdır.
  • Sıra hatası: DROP kuralını izin kurallarından önce koymak, tüm trafiği engellemek.
  • Uzak sunucuda test etmeden uygulamak: Her zaman değişikliklerinizi test etmek için bir geri alma planınız olsun.

Sonuç

iptables, karmaşık görünen ama temel kavramları bir kez oturduğunda son derece güçlü ve esnek bir araçtır. Tablo-zincir-kural hiyerarşisini, paket yolculuğunu ve durum takibini anladığınızda, sıfırdan güvenli bir firewall yapılandırması oluşturabilirsiniz.

Unutmayın: iyi bir firewall politikası her şeyi engelleyip sadece ihtiyaç duyulan trafiğe izin vermek üzerine kuruludur. “Açık bırakabilirim, sorun olmaz” yaklaşımı güvenliğin en büyük düşmanıdır. Kural setlerinizi düzenli olarak gözden geçirin, gereksiz açık portları kapatın ve her değişikliği dokümante edin.

Bir sonraki yazıda iptables kural setlerini daha sistematik şekilde nasıl yöneteceğimizi, pratik saldırı koruma senaryolarını ve nftables’a geçiş yolunu ele alacağız. Bu yazıda öğrendikleriniz o konulara geçiş için sağlam bir zemin oluşturuyor.

Yorum yapın