Sunucunuzu internete açtığınız anda, birkaç dakika içinde port tarama botlarının kapınızı çalmaya başladığını fark edersiniz. Bu gerçeklik, port bazlı erişim kontrolünü sıradan bir “iyi olur” özelliği olmaktan çıkarıp zorunlu bir güvenlik katmanına dönüştürür. iptables, Linux çekirdeğinin Netfilter altyapısı üzerinde çalışan ve bu kontrolü milisaniye düzeyinde gerçekleştiren güçlü bir araçtır. Bu yazıda teorik bilgiden çok, gerçek senaryolarda nasıl kullanacağınızı ele alacağız.
iptables’ın Temel Mantığını Anlamak
iptables, paketleri zincirler (chains) üzerinden geçirir ve her zincirde sırayla uygulanan kurallar vardır. Port bazlı erişim kontrolü için çoğunlukla üç temel zincirle çalışırsınız:
- INPUT: Sunucuya gelen paketler
- OUTPUT: Sunucudan çıkan paketler
- FORWARD: Sunucu üzerinden geçen paketler (router/gateway senaryoları)
Her kural bir eşleşme (match) ve bir hedef (target) içerir. Paket kuralla eşleşirse hedefe yönlendirilir. Hedefler şunlardır:
- ACCEPT: Paketi kabul et
- DROP: Paketi sessizce düşür, gönderene bilgi verme
- REJECT: Paketi reddet, gönderene hata mesajı gönder
- LOG: Paketi kaydet ama zincirlemeye devam et
Kural sırası kritik öneme sahiptir. iptables kuralları yukarıdan aşağıya işler ve ilk eşleşen kuralda durur. Bu yüzden daha spesifik kuralları daha önce yazmanız gerekir.
Mevcut Durumu Kontrol Etmek
Bir sunucuda çalışmaya başlamadan önce mevcut iptables durumunu anlamanız şarttır.
# Mevcut kuralları listele
iptables -L -v -n
# Satır numaralarıyla listele
iptables -L -v -n --line-numbers
# Belirli bir zinciri görüntüle
iptables -L INPUT -v -n --line-numbers
# NAT tablosunu görüntüle
iptables -t nat -L -v -n
-n parametresi önemlidir; bu olmadan iptables her IP için ters DNS sorgusu yapar ve listeleme işlemi dakikalarca sürebilir. -v parametresi paket ve byte sayaçlarını gösterir, trafik analizi için değerlidir.
Temel Port Engelleme ve Açma
En basit senaryo, belirli bir portu tüm kaynaklara açmak veya kapatmaktır.
# 80 numaralı HTTP portunu tüm kaynaklara aç
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 443 numaralı HTTPS portunu tüm kaynaklara aç
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# 8080 portunu engelle
iptables -A INPUT -p tcp --dport 8080 -j DROP
# Zaten kurulu bağlantıları ve ilişkili paketleri kabul et
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Loopback arayüzüne izin ver
iptables -A INPUT -i lo -j ACCEPT
# Yukarıdakilerin dışındaki tüm gelen trafiği düşür (varsayılan politika)
iptables -P INPUT DROP
Dikkat: -P INPUT DROP komutunu çalıştırmadan önce SSH portuna erişim kuralınızın aktif olduğundan emin olun, aksi halde sunucunuzdan kilitlenirsiniz.
SSH Portunu Güvenli Hale Getirmek
SSH, brute force saldırılarının birincil hedefidir. Sadece belirli IP adreslerinden SSH erişimine izin vermek, bu saldırı vektörünü neredeyse tamamen ortadan kaldırır.
# Sadece belirli bir IP'den SSH erişimine izin ver
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.100 -j ACCEPT
# Bir IP bloğundan SSH erişimine izin ver
iptables -A INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
# Birden fazla IP için (multiport yerine ayrı kurallar)
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.50 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 203.0.113.51 -j ACCEPT
# SSH için kalan tüm erişimi engelle ve logla
iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "SSH-BLOCKED: " --log-level 4
iptables -A INPUT -p tcp --dport 22 -j DROP
Log kuralı burada önemli bir rol oynar. --log-prefix ile tanımladığınız ön ek, /var/log/kern.log veya /var/log/syslog içinde kolayca aranabilir. Hangi IP’lerin SSH portuna ulaşmaya çalıştığını bu şekilde takip edebilirsiniz.
Multiport ile Birden Fazla Port Yönetimi
Tek tek port kuralı yazmak yerine multiport modülü kullanarak daha temiz bir yapı kurabilirsiniz.
# Web sunucusu için gerekli portları tek kuralla aç
iptables -A INPUT -p tcp -m multiport --dports 80,443,8080,8443 -j ACCEPT
# Mail sunucusu portlarını aç
iptables -A INPUT -p tcp -m multiport --dports 25,465,587,993,995 -j ACCEPT
# Belirli bir IP'den birden fazla porta erişim ver
iptables -A INPUT -p tcp -s 10.10.0.0/24 -m multiport --dports 3306,5432,6379,27017 -j ACCEPT
# UDP portları için de aynı yaklaşım
iptables -A INPUT -p udp -m multiport --dports 53,123,161 -j ACCEPT
Multiport modülü, bir kuralda en fazla 15 port tanımlamanıza izin verir. Bu sınırı aştığınızda kuralları bölmeniz gerekir.
Port Aralığı Kontrolü
Bazen belirli bir port aralığının tamamını yönetmeniz gerekir. FTP pasif modu, yüksek numaralı portlar veya uygulama sunucuları için port aralığı tanımı kullanışlıdır.
# FTP pasif modu için port aralığı aç
iptables -A INPUT -p tcp --dport 49152:65535 -j ACCEPT
# Özel uygulama port aralığı
iptables -A INPUT -p tcp --dport 8000:8100 -s 172.16.0.0/12 -j ACCEPT
# Kaynak port bazlı kural (dikkatli kullanın)
iptables -A INPUT -p tcp --sport 1024:65535 -m state --state ESTABLISHED -j ACCEPT
# Yüksek numaralı portlardan gelen yeni bağlantıları engelle
iptables -A INPUT -p tcp --dport 1:1023 --sport 1024:65535 -m state --state NEW -j ACCEPT
Gerçek Dünya Senaryosu: Web ve Veritabanı Sunucusu
Bir web uygulaması sunucusu için tipik bir firewall yapılandırması şöyle görünür:
#!/bin/bash
# Web + DB sunucusu için iptables yapılandırması
# Mevcut kuralları temizle
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# Varsayılan politikaları belirle
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Loopback trafiğine izin ver
iptables -A INPUT -i lo -j ACCEPT
# Kurulu bağlantıları kabul et
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# ICMP ping'e izin ver (ama flood'u engelle)
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 5 -j ACCEPT
# SSH sadece yönetim IP bloğundan
iptables -A INPUT -p tcp --dport 22 -s 10.0.1.0/24 -j ACCEPT
# HTTP ve HTTPS herkese açık
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# MySQL sadece uygulama sunucusundan
iptables -A INPUT -p tcp --dport 3306 -s 10.0.2.50 -j ACCEPT
# Redis sadece iç ağdan
iptables -A INPUT -p tcp --dport 6379 -s 10.0.0.0/16 -j ACCEPT
# Monitoring için SNMP
iptables -A INPUT -p udp --dport 161 -s 10.0.1.10 -j ACCEPT
# Tüm engellenen trafiği logla
iptables -A INPUT -j LOG --log-prefix "IPT-DROPPED: " --log-level 4
echo "Firewall kuralları uygulandı."
Bu script’i /etc/firewall.sh olarak kaydedip chmod +x ile çalıştırılabilir yapın. Sistemi her başladığında otomatik çalıştırmak için ise farklı yaklaşımlar var.
Kuralları Kalıcı Hale Getirmek
iptables kuralları varsayılan olarak bellekte tutulur ve sistem yeniden başladığında kaybolur. Kalıcı hale getirmenin birkaç yolu var:
# Debian/Ubuntu için iptables-persistent kur
apt-get install iptables-persistent
# Mevcut kuralları kaydet
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
# RHEL/CentOS için
service iptables save
# veya
iptables-save > /etc/sysconfig/iptables
# Manuel yükleme için
iptables-restore < /etc/iptables/rules.v4
# Systemd ile özel bir servis oluşturma
cat > /etc/systemd/system/iptables-custom.service << 'EOF'
[Unit]
Description=Custom iptables rules
After=network.target
[Service]
Type=oneshot
ExecStart=/etc/firewall.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
systemctl enable iptables-custom
systemctl start iptables-custom
Rate Limiting ile Port Flood Koruması
Bir portu tamamen açık bırakmak ama aşırı bağlantıları sınırlamak isteyebilirsiniz. Bu özellikle HTTP, SSH ve DNS için geçerlidir.
# SSH brute force koruması - dakikada 3'ten fazla yeni bağlantıyı engelle
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
# HTTP flood koruması
iptables -A INPUT -p tcp --dport 80 -m state --state NEW -m limit --limit 50/minute --limit-burst 200 -j ACCEPT
# SYN flood koruması
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
# DNS sorgu limiti
iptables -A INPUT -p udp --dport 53 -m limit --limit 10/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j DROP
--limit ve --limit-burst parametrelerini doğru ayarlamak önemlidir. Çok düşük değerler meşru kullanıcıları etkiler. Ürün ortamında bu değerleri belirlemeden önce mevcut trafik verilerinizi analiz edin.
Port Yönlendirme ve NAT
Bazen bir porta gelen trafiği başka bir porta yönlendirmeniz gerekir. Bu hem güvenlik hem de servis yönetimi açısından kullanışlıdır.
# 80 portunu 8080'e yönlendir (aynı sunucuda)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# Harici 80 portunu iç ağdaki başka bir sunucuya yönlendir
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.50:80
iptables -A FORWARD -p tcp -d 192.168.1.50 --dport 80 -j ACCEPT
# IP masquerading (NAT router senaryosu)
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# Port yönlendirmesini etkinleştirmek için kernel parametresi
echo 1 > /proc/sys/net/ipv4/ip_forward
# Kalıcı için /etc/sysctl.conf içine: net.ipv4.ip_forward = 1
Kural Sırasını Yönetmek
Mevcut bir zincire kural eklerken sıra önemlidir. -A her zaman sona ekler, -I ise belirtilen konuma ekler.
# Mevcut kurallara bakalım
iptables -L INPUT --line-numbers -n
# 3. sıraya yeni bir kural ekle
iptables -I INPUT 3 -p tcp --dport 9200 -s 10.0.0.5 -j ACCEPT
# Belirli bir kuralı sil (satır numarasıyla)
iptables -D INPUT 5
# Belirli bir kuralı kural içeriğiyle sil
iptables -D INPUT -p tcp --dport 9200 -s 10.0.0.5 -j ACCEPT
# Belirli bir zinciri temizle
iptables -F INPUT
# Tüm kuralları temizle
iptables -F
# Kural sayaçlarını sıfırla
iptables -Z INPUT
Üretim ortamında kural silme veya değiştirme işlemi yaparken önce kuralları yedekleyin: iptables-save > /tmp/iptables-backup-$(date +%Y%m%d-%H%M%S)
ipset ile Büyük IP Listesi Yönetimi
Yüzlerce veya binlerce IP için ayrı ayrı kural yazmak hem yönetim kabusu hem de performans sorunu yaratır. ipset bu problemi çözer.
# ipset kur
apt-get install ipset # Debian/Ubuntu
yum install ipset # RHEL/CentOS
# Bir IP kümesi oluştur
ipset create whitelist hash:ip
# Kümeye IP ekle
ipset add whitelist 203.0.113.10
ipset add whitelist 203.0.113.20
ipset add whitelist 198.51.100.0/24
# iptables kuralında ipset kullan
iptables -A INPUT -p tcp --dport 443 -m set --match-set whitelist src -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j DROP
# Ağ blokları için farklı küme tipi
ipset create blocked_nets hash:net
ipset add blocked_nets 185.220.0.0/16
ipset add blocked_nets 91.108.4.0/22
iptables -I INPUT 1 -m set --match-set blocked_nets src -j DROP
# ipset kurallarını kaydet
ipset save > /etc/ipset.rules
# Geri yükle
ipset restore < /etc/ipset.rules
Hata Ayıklama ve İzleme
Kurallarınız beklendiği gibi çalışmıyorsa izleme araçları hayat kurtarır.
# Hangi kuralın kaç paketi işlediğini gör
iptables -L INPUT -v -n
# Canlı log takibi
tail -f /var/log/kern.log | grep "IPT-DROPPED"
# tcpdump ile port trafiğini izle
tcpdump -i eth0 port 80 -n
# conntrack ile aktif bağlantıları izle
apt-get install conntrack
conntrack -L -p tcp --dport 443
# iptables trace modu (dikkatli kullanın, çok fazla log üretir)
iptables -t raw -A PREROUTING -p tcp --dport 8080 -j TRACE
iptables -t raw -A OUTPUT -p tcp --sport 8080 -j TRACE
# Sonra dmesg veya /var/log/kern.log'u takip edin
# Trace modunu kapatmayı unutmayın
iptables -t raw -D PREROUTING -p tcp --dport 8080 -j TRACE
Yeni Sunucu için Güvenli Başlangıç Şablonu
Yeni bir Linux sunucusunu devreye alırken uyguladığım temel şablon şudur:
#!/bin/bash
# Temel güvenli iptables şablonu
# Kullanım: ADMIN_IP=x.x.x.x ./firewall-base.sh
ADMIN_IP=${ADMIN_IP:-"0.0.0.0/0"} # Production'da mutlaka belirtin
iptables -F && iptables -X
iptables -t nat -F && iptables -t nat -X
iptables -t mangle -F && iptables -t mangle -X
# Varsayılan politikalar
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Temel izinler
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
# SSH erişimi
iptables -A INPUT -p tcp --dport 22 -s $ADMIN_IP -j ACCEPT
# Genel web trafiği
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# Tüm reddedilenleri logla
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPT-DENY: " --log-level 7
# Kuralları kaydet
iptables-save > /etc/iptables/rules.v4 2>/dev/null ||
iptables-save > /etc/sysconfig/iptables 2>/dev/null
echo "Firewall aktif. Admin IP: $ADMIN_IP"
echo "Test için: ssh root@$(hostname -I | awk '{print $1}') -p 22"
Sık Yapılan Hatalar
Deneyimlerime göre en sık karşılaşılan iptables hataları şunlardır:
- Kural sırası hatası: DROP kuralını ACCEPT kuralından önce yazıp servise erişimi kesmek. Daima daha permissive (izin veren) kuralları önce yazın.
- ESTABLISHED/RELATED kuralı eksikliği: Bu kural olmadan giden isteklerin yanıtları da bloklanır. INPUT zincirinin en başına bu kuralı ekleyin.
- Test etmeden varsayılan politikayı DROP yapmak: Önce tüm ACCEPT kurallarını ekleyin, en son varsayılan politikayı değiştirin.
- IPv6’yı unutmak: iptables sadece IPv4 yönetir. ip6tables için ayrı kurallar gerekmez, ancak sunucunuzda IPv6 etkinse ihmal etmeyin.
- NAT sonrasında FORWARD kuralı eksikliği: DNAT kuralı yazıp FORWARD zincirinde geçişe izin vermeyi unutmak.
- Kalıcılık sağlamamak:
iptables-saveçalıştırmadan restart sonrası tüm kuralların kaybolduğunu fark etmek.
Sonuç
iptables, doğru kullanıldığında son derece güçlü ve esnek bir güvenlik katmanı sunar. Port bazlı erişim kontrolü, saldırı yüzeyini dramatik biçimde azaltır; ancak tek başına yeterli değildir. fail2ban gibi dinamik engelleme araçları, uygulama seviyesi güvenlik duvarları ve düzenli güvenlik denetimleriyle birlikte kullanıldığında gerçek bir savunma derinliği elde edersiniz.
Pratik önerim şu: Her yeni servisi devreye almadan önce hangi kaynaklardan hangi portlara erişim gerektiğini bir kağıda yazın. Bu tasarım alışkanlığı, hem gereksiz port açımını önler hem de bakım sürecini kolaylaştırır. Üretim ortamında kural değişikliklerini her zaman yedek alarak ve tercihen bir değişiklik penceresi içinde yapın. “Şimdi hızlıca düzeltirim” düşüncesiyle yapılan acele değişiklikler, en sık yaşanan kesintilerin kaynağıdır.
nftables, iptables’ın yerini almaya devam etse de iptables hâlâ sayısız sistemde çalışıyor ve uzun süre daha çalışmaya devam edecek. Bu bilgi yatırımı boşa gitmeyecek.