Pardus/Linux iptables ile Güvenlik Duvarı Yönetimi

TCP modülünü kullanarak geçersiz TCP paketlerini engelleme

Artık iptables hakkında yeteri kadar bilgiye sahip olduğumuza göre, geçersiz TCP paketlerini bloke edecek bir kural yazalım. tcp modülü --tcp-flags  parametresine sahiptir, ve bu parametreyi geçersiz tcp etiketlerini kontrol etmek için kullanabiliriz.  Bu parametre iki argüman alır; bunlar “mask” ve “compared flags” etiketleridir. mask etiketi kontrol edilmesi gereken etiketleri seçerken, compared flags etiketi paket üzerine işlenmesi gereken etiketleri seçer.

Örnek olarak; “christmas tree” paketlerini engellemek isteyelim. Bu durumda tüm etiketleri kontrol edip FIN, PSH ve URG etiketlerini işlememiz gerekiyor. Yani yazmamız gereken kural:

iptables -A INPUT -p tcp -m tcp --tcp-flags ALL FIN,PSH,URG -j DROP

Buna ek olarak red edilebilecek pek çok geçersiz paket vardır. Mesela, SYN ve FIN etiketleri geçersiz işlenmiş olan paketler. Bu durumda sadece bu etiketleri işlememiz yeterli olacaktır, yani yazmamız gereken kural:

iptables -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP

Şimdi de diğer bir tür geçersiz paket inceleyelim, yeni bir bağlantıda SYN etiketiyle başlamayan bir paket. Burda basit bi şekilde FIN, RST, ACK  ve SYN etiketlerini kontrol etmemiz yeterli olacaktır, fakat sadece SYN işlenecektir. Yani, negatif karşılaştırma yaparak bu şartı işleyebiliriz.  Son olarak, conntrack kullanarak, bağlantının yeni bir bağlantı olduğunu doğrulayabiliriz. Yazmamız gereken kural:

iptables -A INPUT -p tcp -m conntrack --ctstate NEW \
-m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -j DROP

Paketleri Limitlemek : limit modülü

Bu bölümde, limit modülünü inceleyeceğiz. Limit modülünün işi; geçecek paket sayısına bir limit koymaktır.

Bu modülün nasıl çalıştığını anlamak için bir benzetme yapalım. Farzedelim ki, bir kesede 5 tane jetonunuz var. Her paket geçişinde jetonlardan birini atacaksınız. Böylece kova boş kaldığında yeni bir paket geçişine izin veremezsiniz. Ek olarak, attığınız jetonları her 3 saatte bir kovaya geri koyabilirsiniz (ya da 20 dakikada bir). Teknik olarak, jeton sayısına “limit-burst” değeri ve bu işlemi sıfırlama oranınıza “limit” değeri denir.

Şimdi, farzedelim ki sisteminize 10 paket ulaştı. İlk 5 paketi kabul edebilmek için, 5 jetonu atmanız gerekecek. Artık kesenizde jeton kalamadığı için kalan paketleri görmezden gelmek zorundasınız, ve önümüzdeki 20 dk boyunca başka paket kabul edemezsiniz, çünkü kesede atabileceğiniz hiç jetonunuz kalmadı, ve keseyi tekrar doldurabilmek için bu sürenin bitmesini beklemek zorundasınız. Şimdi farzedelim ki 45 dk geçti ve sisteminize üç paket daha ulaştı. Bu paketlerden sadece ilk ikisini kabul edebileceksiniz çünkü kesenizde sadece iki jeton kaldı. Eğer 100 dk boyunca sisteminizden hiç paket geçmezse keseniz tekrar tamamen dolmuş olacaktır.

Pratik bir örnek olarak , farzedelim ki ICMP paketlerine bir ratelimit koymak istiyorsunuz. Bu halde şu kural işi yapacaktır:

iptables -A INPUT -p icmp -m limit --limit 1/sec --limit-burst 1 -j ACCEPT

IP adresine göre paket limitleri: recent modülü

Maalesef, limit modülü dinamik bir şekilde IP adresine göre kısıtlama yeteneğine sahip değildir. Bu durumda recent modülü devreye girer.

Sunucunuzda daha evvel SSH brute-force saldırılarına maruz kalmış olabilirsiniz. Genellikle saldırganlar izin verilen en fazla sayıda bağlantıyı kullanarak saldırıyı gerçekleştirmeye çalışacaklardır. Bu durumda IP başına kısıtlama koyarak saldırıyı yavaşlatabilirsiniz:

iptables -A INPUT -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --set --name SSHLIMIT --rsource
iptables -A INPUT -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW \
-m recent --set --name SSHLIMIT --update --seconds 180 --hitcount 5 --name SSH \
--rsource -j DROP

Modül tarafından isteklerin ve paketlerin takip edilebilmesi için “SSHLIMIT” şeklinde isimlendirdik.  İlk satır kaynak IP adresini listeye ekliyor ve recent modülü geri kalan işlemlerle ilgileniyor Eğer IP adresi zaten listedeyse , bu P adresi için var olan kayıt güncellenecektir. Diğer satırda sayacın belirlediğimiz değerlen olan 180 sn içersinde 5 e ulaşıp ulaşmadığını kontrol ediyor. Eğer sayaç bu değere belirtilen sürede ulaştıysa, paket engelleniyor. Bu kurallar bize 3 dk içersinde aynı IP adresinden 4 bağlantı girişimi hakkı veriyor(beşinci paket engellenecektir).

Bazı güncel kernellerde --mask parametresi de bulunmaktadır. Bu parametre IP aralıklarının belirtilen şekilde kısıtlanabilmesini sağlamaktadır. Yani örneğin tüm /24 notasyonunu kısıtlamak istiyorsanız:

iptables ... -m recent ... --mask 255.255.255.0

recent modülü isim tabanlı çalıştığı için bu bize bazı kestirmeler sağlamaktadır. Örneğin saldırganın sadece SSH servisinden değil, tüm sistemden engellenmesini isterseniz, sadece ikinci satırdaki –name parametresini kaldırmanız yeterli olacaktır.

Özel Zincirler

Bazen , aynı paket üzerinde kompleks işlemleri tekrar tekrar yapmanız gerekebilir. Örneğin; SSH iznini belirli bazı ip aralıklarına nasl verileceğini gördük:

iptables -A INPUT -p tcp -m tcp --dport 22 -s 192.168.0.0/16 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -s 192.162.0.0/16 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 22 -j DROP

Maalesef bu yöntem pek tercih edilmeyen ve verimsiz bir yoldur. Bunu yapmanın daha iyi olu, özel zincirler kullanmaktır. Öncelikle, özel bir zincir oluşturmamız gerekiyor. Farzedelim ki kullanacağımız özel zincirin ismi  ssh-kurallariolsun:

iptables -N ssh-kurallari

Daha sonra, oluşturduğumuz bu yeni zincire, ilgili IP adresleri için kuralları ekleyelim. Unutmamalıyız ki, oluşturduğumuz yeni zincirin bir varsayılan politikası yok. Bu yüzden işimiz bittiğinde bunu da ayarlamamız gerekecek. Burda eklediğimiz en son satır, karşılık bulmayan tüm paketleri engellemek üzere:

iptables -A ssh-kurallari -s 192.168.0.0/16 -j ACCEPT
iptables -A ssh-kurallari -s 192.162.0.0/16 -j ACCEPT
iptables -A ssh-kurallari -j DROP

Şimdi de , INPUT zincirine, ssh-kurallari zincirini referans eden bir kural koyalım:

iptables -A INPUT -p tcp -m tcp --dport 22 -j ssh-kurallari

Özel bir zincir kullanmanın pek çok avantajı vardır. Örneğin bu zinciri bir script ile kontrol edebilir, ve diğer zincirlerde olan kurallar için endişe etmezsiniz.

Eğer bu zinciri silmek istersek, öncelikle bu zincire referans eden kuralları silip sonra da zinciri şu şekilde sileriz:

iptables -X ssh-kurallari

Paketleri loglamak : LOG hedefi

Pek çok sonlandıran hedef ile örnekler verdik. Şimdiki başlığımız ise sonlandırmayan (non-terminating) bir hedef üzerine. Ismi gibi, bu hedef paketi kernel loglarına loglar . Bu logların yeri değişebileceği gibi genellikle /var/log/syslog ya da /var/log/messages  dosyalarıdır.

Bu hedefin kullanımı oldukça kolaydır. Örneğin; geçersiz TCP paketlerini engellemeden önce loglamak istiyorsunuz. Bunun için önce loglama yapmalı, daha sonra paketi düşürmelisiniz:

iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j LOG
iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j DROP

LOG hedefi aynı zamanda  --log-prefix parametresi kullanabilir. Bu parametre kernel logları içinde iptables loglarını bulmak için oldukça kullanışlıdır:

iptables -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j LOG \
--log-prefix=iptables:


, , , , , , , ,