magmalinux-iptables-betik-ornekleri

8  Iptables Betik Örnekleri

Bu bölümde çeşitli durumlardaki bilgisayarlar için örnek Iptables betiklerini inceleyeceğiz. Bu betiklerle ilgili açıklamaları, betiklerin içerisindeki yorum satırlarında yapacağız.

8.1  Kişisel Bilgisayar için

Internete bağlı bir kişisel bilgisayar için, dışarıdan bağlantı açan paketler için bütün portları kapatan Iptables betiği:

#!/bin/sh

# Baslangic betigi olarak ayarladigimizda PATH degiskeni 
# ayarlanmadan önce çalistirilirsa iptables komutunu bulabilsin diye
# iptables degiskenini tanimladik:

iptables="/sbin/iptables"

# Filter ve Nat tablosunu temizliyoruz
# Kullanici tanimli bos zincirleri siliyoruz
$iptables -F
$iptables -F -t nat
$iptables -X

# lo arayuzune gelen butun paketleri kabul ediyoruz
$iptables -A INPUT -i lo -j ACCEPT

# Gelen paket varolan bir baglantiya ait ya da var olan bir baglanti
# ile iliskili ise kabul ediyoruz.
$iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Paket bu kosullara uymuyorsa reddediyoruz
# (Ornegin yeni baglanti acan paket)
$iptables -P INPUT DROP

# Bilgisayarimizdan giden butun paketlere izin veriyoruz
$iptables -P OUTPUT ACCEPT

# Kaynak ve hedef adresi farkli ama bu bilgisayar
# uzerinden giden paketleri reddediyoruz.
$iptables -P FORWARD DROP

 

8.2  Sunucular için

FTP, HTTP, SMTP ve POP3 gibi hizmetler veren bir sunucu için Iptables betiğini inceleyeceğiz. Bu betik, dışarıdan sunucumuza açılan bağlantıların hepsini engelleyip, sadece TCP_ACIK ve UDP_ACIK değişkeninde belirtilen portlara izin verir ve bu belirtilen portlara 60 saniye içerisinde yapılabilecek maksimum bağlantı açma sayısını 20 ile sınırlar.

 

#!/bin/sh



# FTP, HTTP, SMTP, POP3, IMAP gibi servisleri sunan bir sunucu

# icin Iptables Kurallari

iptables="/sbin/iptables"



# Arayuz isimlerini degiskenlere atiyoruz. Boylelikle arayuzler degistiginde

# degistirmemiz gereken tek bir satir oluyor.



LO_IFACE="lo"

WAN_IFACE="eth0"







# TCP Disariya acik portlar. 33300:33400 araligi passive FTP icin.

# Port numaralari yerine /etc/services dosyasinda yazan isimleri

# kullandik.



TCP_ACIK="ftp-data ftp ssh telnet smtp http pop3 imap https smtps

          rsync ftps-data ftps telnets imaps pop3s 33300:33400"

UDP_ACIK="domain"

MAX_SYN="21"



# Filter ve Nat tablosunu temizliyoruz

# Kullanici tanimli bos zincirleri siliyoruz

$iptables -F

$iptables -F -t nat

$iptables -X







# Cesitli amaclar icin zincir tanimliyoruz.

# bad_tcp_packets: Yanlis TCP basligina sahip paketleri engellemek icin

# allowed: Kabul edilen paketlerle ilgili kural tanimlamak icin

# denied: Reddedilen paketlerle ilgili kural tanimlamak icin

# tcp_acik: WAN'dan baglanilmasina izin verilen TCP portlari ile ilgili kurallar

# udp_acik: WAN'dan baglanilmasina izin verilen UDP portlari ile ilgili kurallar



$iptables -N bad_tcp_packets

$iptables -N allowed

$iptables -N denied

$iptables -N tcp_acik

$iptables -N udp_acik









# SYN/ACK paketi oldugu halde, baglanti izleme modulune gore

# baglantiyi baslatan ilk paket (NEW) olarak gozuken paketleri reddediyor.

$iptables -A bad_tcp_packets -p tcp –tcp-flags SYN,ACK SYN,ACK \

    -m state –state NEW -j REJECT –reject-with tcp-reset







# SYN paketi olmadigi halde, baglanti izleme modulune gore

# ilk paket olarak gozuken paketleri log'a yaziyor ve paketleri reddediyor.

$iptables -A bad_tcp_packets -p tcp ! –syn -m state –state NEW -j LOG \

    –log-prefix "New but not SYN"

$iptables -A bad_tcp_packets -p tcp ! –syn -m state –state NEW -j DROP







# Kabul edilen paketlerin geldigi zincir

# Paket yeni baglanti aciyorsa, var olan baglantiya ait ise ya da

# var olan baglanti ile iliskili ise kabul ediliyor.

# Aksi halde (INVALID), log tutulup, paket reddediliyor.



$iptables -A allowed -p tcp –syn -j ACCEPT

$iptables -A allowed -p tcp -m state –state ESTABLISHED,RELATED -j ACCEPT

$iptables -A allowed -p tcp -m limit –limit 3/minute –limit-burst 3 -j LOG \

    –log-prefix "*Allowed* zincirinde DROP: "

$iptables -A allowed -p tcp -j DROP







# Reddedilen paketlerin geldigi zincir

# Reddedilen paketlerin dakikada maksimum 3 tanesi log'a yaziliyor.



$iptables -A denied -p ALL -m limit –limit 3/minute –limit-burst 3 -j LOG \

    –log-level DEBUG –log-prefix "Packet Denied: "

$iptables -A denied -p ALL -j DROP









# Disariya acik olacak TCP ve UDP portlari kurallari tanimlaniyor.

# TCP SYN DoS saldirilarindan korunmak icin, ayni IP adresinden 60 saniye

# icerisinde en fazla 20 baglanti acma istegi kabul ediyoruz.



for port in $TCP_ACIK; do

    $iptables -A tcp_acik -p tcp –dport $port -m state –state NEW \

        -m recent –set

    $iptables -A tcp_acik -p tcp –dport $port -m state –state NEW \

        -m recent –update –seconds 60 –hitcount $MAX_SYN -j DROP

    $iptables -A tcp_acik -p tcp –dport $port -j allowed

done



for port in $UDP_ACIK; do

    $iptables -A udp_acik -p udp –dport $port -j ACCEPT

done











# Gelen TCP paketlerinin dogrulugunu kontrol etmek icin tum TCP paketlerini

# bad_tcp_packets zincirine gonderiyoruz.

$iptables -A INPUT -p tcp -j bad_tcp_packets





# Yerel arayuzumuzden gelen (lo) butun paketleri kabul ediyoruz.

$iptables -A INPUT -p ALL -i $LO_IFACE -j ACCEPT





# WAN arayuzumuze gelen paketler var olan bir baglantiya ait

# ya da var olan bir baglanti ile iliskili ise kabul ediyoruz

$iptables -A INPUT -p ALL -i $WAN_IFACE -m state –state ESTABLISHED,RELATED \

    -j ACCEPT





# WAN arayuzune gelen TCP paketlerini tcp_acik, UDP paketlerini udp_acik

# zincirine gonderiyoruz. Eger bu zincirlerde tanimladigimiz portlardan

# biri ile eslesirse paketi kabul ediyoruz.

$iptables -A INPUT -p tcp -i $WAN_IFACE -j tcp_acik

$iptables -A INPUT -p udp -i $WAN_IFACE -j udp_acik





# Eger paket bu kurallara kadar kabul edilmemisse, log'unu tutup,

# reddediyoruz

$iptables -A INPUT -m limit –limit 3/minute –limit-burst 3 -j LOG \

    –log-level DEBUG –log-prefix "IPT INPUT packet died: "

$iptables -P INPUT DROP









# LO ve WAN arayuzumuzden giden paketlerin hepsine izin veriyoruz

# Eger paket herhangi bir nedenden dolayi kabul edilmemis ise bunun logunu

# tutuyoruz.



$iptables -A OUTPUT -p tcp -j bad_tcp_packets

$iptables -A OUTPUT -p ALL -o $LO_IFACE -j ACCEPT

$iptables -A OUTPUT -p ALL -o $WAN_IFACE -j ACCEPT

$iptables -A OUTPUT -m limit –limit 3/minute –limit-burst 3 -j LOG \

    –log-level DEBUG –log-prefix "IPT OUTPUT packet died: "

$iptables -P OUTPUT DROP







# Kaynagi ve hedefi baska bir bilgisayar olan paketler bu bilgisayar

# uzerinden gecmeyecek



$iptables -P FORWARD DROP

8.3  Alt ağa internet paylaştıran sunucular için

HTTP, FTP, SMTP ve POP3 gibi verdiği hizmetlerin yanında, alt ağa internetini paylaştıran bir sunucu için hazırlanmış bir Iptables betiğini inceleyeceğiz. Bu betikte, dışarıdan sunucuya yapılan bağlantıların tümü yasaklanıp sadece belli başlı portlar (TCP_ACIK ve UDP_ACIK değişkeninde belirtilen portlar) açılmıştır ve iç ağdan sunucuya yapılan bağlantıların tümüne izin verilip sadece bazı portlar (TCP_KAPALI ve UDP_KAPALI değişkeninde belirtilen portlar) engellenmiştir.

#!/bin/sh

# FTP, HTTP, SMTP, POP3, IMAP gibi servisleri sunan ve alt aga
# internet paylastiran bir sunucu icin Iptables kurallari


iptables="/sbin/iptables"

LAN_IFACE="eth1"
LAN_IP="10.1.0.1"
LAN_IP_RANGE="10.1.0.0/16"

LO_IFACE="lo"
LO_IP="127.0.0.1"

WAN_IFACE="eth0"
WAN_IP="192.168.1.2"

SQUID="$LAN_IP:3128"
DANSGUARDIAN="$LAN_IP:8080"


# TCP ve UDP *disariya* acik portlar.
# 33300:33400 araligi passive FTP icin.
# Port numaralari yerine /etc/services dosyasinda yazan isimleri
# kullandik.
TCP_ACIK="ftp-data ftp ssh telnet smtp http pop3 imap https smtps
          rsync ftps-data ftps telnets imaps pop3s 33300:33400"
UDP_ACIK="domain"

MAX_SYN_INET="21"
MAX_SYN_LAN="61"

# TCP ve UDP *ic aga* kapali portlar.
TCP_KAPALI=""
UDP_KAPALI=""


# Filter ve Nat tablosunu temizliyoruz
# Kullanici tanimli bos zincirleri siliyoruz
$iptables -F
$iptables -F -t nat
$iptables -X



# Cesitli amaclar icin zincir tanimliyoruz.
# bad_tcp_packets: Yanlis TCP basligina sahip paketleri engellemek icin
# allowed: Kabul edilen paketlerle ilgili kural tanimlamak icin
# denied: Reddedilen paketlerle ilgili kural tanimlamak icin
# tcp_acik: WAN'dan baglanilmasina izin verilen TCP portlari ile ilgili kurallar
# tcp_kapali: LAN'dan baglanilmasina izin VERILMEYEN TCP portlari
# udp_acik: WAN'dan baglanilmasina izin verilen UDP portlari ile ilgili kurallar
# udp_kapali: LAN'dan baglanilmasina izin VERILMEYEN TCP portlari

$iptables -N bad_tcp_packets
$iptables -N allowed
$iptables -N denied
$iptables -N tcp_acik
$iptables -N tcp_kapali
$iptables -N udp_acik
$iptables -N udp_kapali



# IP Forwarding destegini aciyoruz
echo "1" > /proc/sys/net/ipv4/ip_forward



# SYN/ACK paketi oldugu halde, baglanti izleme modulune gore
# baglantiyi baslatan ilk paket (NEW) olarak gozuken paketleri reddediyor.
$iptables -A bad_tcp_packets -p tcp --tcp-flags SYN,ACK SYN,ACK \
    -m state --state NEW -j REJECT --reject-with tcp-reset



# SYN paketi olmadigi halde, baglanti izleme modulune gore
# ilk paket olarak gozuken paketleri log'a yaziyor ve paketleri reddediyor.
$iptables -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j LOG \
    --log-prefix "New but not SYN"
$iptables -A bad_tcp_packets -p tcp ! --syn -m state --state NEW -j DROP



# Kabul edilen paketlerin geldigi zincir
# Paket yeni baglanti aciyorsa, var olan baglantiya ait ise ya da
# var olan baglanti ile iliskili ise kabul ediliyor.
# Aksi halde (INVALID), log tutulup, paket reddediliyor.

$iptables -A allowed -p tcp --syn -j ACCEPT
$iptables -A allowed -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
$iptables -A allowed -p tcp -m limit --limit 3/minute --limit-burst 3 -j LOG \
    --log-prefix "*Allowed* zincirinde DROP: "
$iptables -A allowed -p tcp -j DROP



# Reddedilen paketlerin geldigi zincir
# Reddedilen paketlerin dakikada maksimum 3 tanesi log'a yaziliyor.
$iptables -A denied -p ALL -m limit --limit 3/minute --limit-burst 3 -j LOG \
    --log-level DEBUG --log-prefix "Packet Denied: "
$iptables -A denied -p ALL -j DROP



# Disariya acik olacak TCP ve UDP portlari kurallari tanimlaniyor.
# TCP SYN DoS saldirilarindan korunmak icin, her acik port icin
# ayni IP adresinden 60 saniye icerisinde en fazla 20 baglanti acma
# istegi kabul ediyoruz.

for port in $TCP_ACIK; do
    $iptables -A tcp_acik -p tcp --dport $port -m state --state NEW \
        -m recent --set --name "$port"
    $iptables -A tcp_acik -p tcp --dport $port -m state --state NEW \
        -m recent --name "$port" --update --seconds 60 \
        --hitcount $MAX_SYN_INET -j DROP
    $iptables -A tcp_acik -p tcp --dport $port -j allowed
done

for port in $UDP_ACIK; do
    $iptables -A udp_acik -p udp --dport $port -j ACCEPT
done



# Ic aga kapali olacak TCP ve UDP portlari kurallari tanimlaniyor.
for port in $TCP_KAPALI; do
    $iptables -A tcp_kapali -p tcp --dport $port -j denied
done

for port in $UDP_KAPALI; do
    $iptables -A udp_kapali -p udp --dport $port -j denied
done



# Gelen TCP paketlerinin dogrulugunu kontrol etmek icin tum TCP paketlerini
# bad_tcp_packets zincirine gonderiyoruz.
$iptables -A INPUT -p tcp -j bad_tcp_packets

# Eger yerel agdaki bir bilgisayarin belli zaman araliginda sunucuya
# gonderebilecegi maksimum SYN paketi sayisi engellenmek isteniyorsa
# asagidaki satirlarin basindaki ## isaretleri kaldirilabilir.

## $iptables -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE \
##     -m state --state NEW -m recent --set --name "yerel"
## $iptables -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE \
##     -m state --state NEW -m recent --name "yerel" \
##     --update --second 60 --hit-count $MAX_SYN_LAN -j DROP

# LAN'dan sunucuya gelen butun paketleri kabul ediyoruz
$iptables -A INPUT -p ALL -i $LAN_IFACE -s $LAN_IP_RANGE -j ACCEPT

# LO arayuzunden gelen butun paketleri kabul ediyoruz
$iptables -A INPUT -p ALL -i $LO_IFACE -s $LO_IP -j ACCEPT
$iptables -A INPUT -p ALL -i $LO_IFACE -s $LAN_IP -j ACCEPT
$iptables -A INPUT -p ALL -i $LO_IFACE -s $WAN_IP -j ACCEPT


# Yerel Ag'dan gelen DHCP isteklerini kabul ediyoruz.
# Yukarida yerel agdan gelen her paketi kabul ederken IP adresini de
# kontrol ettigimize dikkat edin. DHCP isteklerinde paketin gonderici
# kisminda hicbir IP adresi bulunmayacagi icin, DHCP istekleri icin bu
# istisnai kurali tanimladik.
$iptables -A INPUT -p UDP -i $LAN_IFACE --dport 67 --sport 68 -j ACCEPT




# WAN arayuzumuze gelen paketler var olan bir baglantiya ait
# ya da var olan bir baglanti ile iliskili ise kabul ediyoruz
$iptables -A INPUT -p ALL -d $WAN_IP -m state --state ESTABLISHED,RELATED \
    -j ACCEPT




# WAN arayuzune gelen TCP paketlerini tcp_acik, UDP paketlerini udp_acik
# zincirine gonderiyoruz. Eger bu zincirlerde tanimladigimiz portlardan
# biri ile eslesirse paketi kabul ediyoruz.

$iptables -A INPUT -p tcp -i $WAN_IFACE -j tcp_acik
$iptables -A INPUT -p udp -i $WAN_IFACE -j udp_acik



# Eger paket bu kurallara kadar kabul edilmemisse, log'unu tutup,
# reddediyoruz
$iptables -A INPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
    --log-level DEBUG --log-prefix "IPT INPUT packet died: "
$iptables -P INPUT DROP






# LO, LAN ve WAN IP'lerinden giden paketlerin hepsine izin veriyoruz
# Eger paket herhangi bir nedenden dolayi kabul edilmemis ise bunun logunu
# tutuyoruz.

$iptables -A OUTPUT -p tcp -j bad_tcp_packets
$iptables -A OUTPUT -p ALL -s $LO_IP -j ACCEPT
$iptables -A OUTPUT -p ALL -s $LAN_IP -j ACCEPT
$iptables -A OUTPUT -p ALL -s $WAN_IP -j ACCEPT
$iptables -A OUTPUT -m limit --limit 3/minute --limit-burst 3 -j LOG \
    --log-level DEBUG --log-prefix "IPT OUTPUT packet died: "
$iptables -P OUTPUT DROP




# Yonlendirilecek TCP paketlerinin dogrulugunu kontrol etmek icin
# tum TCP paketlerini bad_tcp_packets zincirine gonderiyoruz.
$iptables -A FORWARD -p tcp -j bad_tcp_packets



# FORWARD zincirine gelen TCP paketlerini tcp_kapali, UDP paketlerini
# udp_kapali zincirine gonderiyoruz. Eger bu zincirlerde tanimladigimiz
# portlardan biri ile eslesirse paketi reddediyoruz.
$iptables -A FORWARD -p tcp -o $WAN_IFACE -j tcp_kapali
$iptables -A FORWARD -p udp -o $WAN_IFACE -j udp_kapali

# Eger yerel agdaki bir bilgisayarin belli zaman araliginda uzaktaki
# bir sunucuya gonderebilecegi maksimum SYN paketi sayisi engellenmek
# isteniyorsa asagidaki satirlarin basindaki ## isaretleri
# kaldirilabilir.

## $iptables -A FORWARD -p ALL -i $LAN_IFACE -m state --state NEW \
##     -m recent --set --name "yerelforward"
## $iptables -A FORWARD -p ALL -i $LAN_IFACE -m state --state NEW \
##     -m recent --name "yerelforward" --update --second 60 \
##     --hit-count $MAX_SYN_LAN -j DROP

# tcp_kapali ve udp_kapali disindaki portlar ise ve LAN arayuzunden
# geliyorsa kabul ediyoruz.
$iptables -A FORWARD -i $LAN_IFACE -j ACCEPT



# WAN arayuzumuze gelen paketler var olan bir baglantiya ait
# ya da var olan bir baglanti ile iliskili ise kabul ediyoruz
$iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT



# Eger paket bu kurallara kadar kabul edilmemisse, log'unu tutup,
# reddediyoruz
$iptables -A FORWARD -m limit --limit 3/minute --limit-burst 3 -j LOG \
    --log-level DEBUG --log-prefix "IPT FORWARD packet died: "
$iptables -P FORWARD DROP


# WAN arayuzunden cikan paketlerin kaynak adresine WAN arayuzunun IP adresini
# yaziyoruz.
$iptables -t nat -A POSTROUTING -o $WAN_IFACE -j MASQUERADE



## LAN'dan sunucunun 80 nolu portuna gelen istekler, SQUID'e yonlendiriliyor
## LAN'dan disardaki bir bilgisayarıin 80 nolu portuna giden istekler,
##   DANSGUARDIAN'a yonlendiriliyor.

#$iptables -t nat -A PREROUTING -p tcp -s $LAN_IP_RANGE -d $LAN_IP --dport 80 \
#    -j DNAT --to $SQUID
#$iptables -t nat -A PREROUTING -p tcp -s $LAN_IP_RANGE -d ! $LAN_IP --dport 80 \
#    -j DNAT --to $DANSGUARDIAN


## Sunucumuz disinda bir proxy server kullaniliyorsa,
## bu paketlerde DANSGUARDIAN'a yonlendiriliyor.
#$iptables -t nat -A PREROUTING -p tcp -s $LAN_IP_RANGE -d ! $LAN_IP --dport 3128 \
#    -j DNAT --to $DANSGUARDIAN 

 

8.4  SYN Saldırı Testi

Yukarıda tanımladığımız Iptables SYN korumalarını test etmek için hping aracı ile SYN saldırısı yapalım. hping aracını kurmak için:

# aptitude install hping3

komutunu çalıştıralım. İşlem bittikten sonra,

# hping3 --faster -S -p 80 sunucu_ip_ya_da_host

komutu ile saldırı gerçekleştirebiliriz. hping uygulaması, bir sunucuya tcp paketleri göndermek için kullanılır. Bizim örneğimizde; kendi sunucumuzun 80 numaralı portuna (-p 80), 1 mikro saniye de bir (–faster ya da -i u1) SYN paketi (-S) gönderiyoruz.

–faster parametresi yerine daha yavaş paket göndermek için –fast (ya da -i u10000) kullanabiliriz. –fast parametresi kullandığımızda hping saniyede 10 paket gönderir. –faster parametresi ile gönderdiğimizden de daha hızlı göndermek istersek, –flood parametresini kullanabiliriz. –flood parametresi kullanıldığında hping gelen cevaplara bakmaksızın gönderebildiği kadar hızlı gönderir.

Hping aracı bu belgenin sınırları dışında olduğundan bu araçla ilgili daha ayrıntılı bilgi almak için man sayfalarını ziyaret edin (komut satırında man hping3 komutunu çalıştırın).