5
Kas

Merhabalar, bügün sizlere Linux çekirdeği ile birlikte gelen iptables ile ilgili bilgi vermeye
çalışacağım. Iptables çekirdek ile gelen bir firewall yazılımı, internet üzerinde iptables ile ilgi
pek türkçe döküman olmadığından bende bir tane hazırlamaya karar verdim umarım birilerine yardımcı olur.

Herneyse, şimdi iptables kullanımını bir örnek üzerinden öğrenmeye çalışalım. Linux sistemlerde
uzak masaüstü bağlantısı yapılmasını nasıl engelleyebiliriz onu görelim.

Öncelikle bağlantı izinini vermek için ayarları yapalım.

Evet, şimdi bağlantı programı ile localhost’a yani kendi bilgisayarımıza bağlanalım.

Bağlantı sırasında atadığımız şifreyi giriyoruz ve şöyle bir uyarı alıyoruz bağlantı istediğini
onaylayıp onaylamadığımızı soruyor.

Bağlantıya onay verdiğimizde ise bağlantı gerçekleşiyor.

Şimdi, bu bağlantıyı iptables ile nasıl engelleyebiliriz ? Şimdi biz kendi bilgisayarımıza bağlantığımız
için bilgisayarımızdan ip’si 127.0.0.1 olan bağlantıları engellemeliyiz. Yani Iptables’de ki OUTPUT
kısmı ile ilgileneceğiz. Şimdi ip adresi 127.0.0.1 olan bir bağlantıyı engellemek için yeni bir kural
eklememiz lazım. Kural eklemek için -A parametresini kullanıyoruz, -A’dan sonra INPUT,FORWARD veya OUTPUT
seçeneği ile kuralımızın hangi durumda geçerli olması gerektiğini bilgiriyoruz OUTPUT dediğimizde sistemden çıkan
bağlantılar ile ilgileniyor.

Şimdi, kural eklemek için hazırız, şimdi hangi adresin engelleneceğini belirtelim bunun için -s parametresini kullanıyoruz
komutumuzun son hali ise şöyle

iptables -A INPUT -s 127.0.0.1

Şuan için komutumuz iptables için bir şey ifade etmiyor çünkü bu tür bir bağlantıda ne yapması gerektiğini
belirtmedik bunun için ise -j parametresini kullanacağız -j parametresi yapmak istediğiniz işleme
göre farklı değerler alıyor örneğin engellemek için DROP, kabul etmek için ACCEPT gibi. Biz engellemek istiyoruz bu yüzden drop kullanıyoruz
Komutun son hali ise

iptables -A INPUT -s 127.0.0.1 -j DROP

Evet şimdi bu komutu konsolda root hakları ile verelim eğer alt satıra geçiyorsa komut başarılı demektir.

Evet, alt satıra geçti emin olmak için iptables kurallarımızı listeleyelim bunun için iptables -L komutunu kullanıyoruz.

Evet, şimdi sistemi yeniden başlattığımızda kuralların değişmemesi için kurallarımızı kayıt edelim.

Komutumuz :

/etc/init.d/iptables save

Evet, şimdi çalışıp çalışmadığını kontrol etmek için ilk yaptığımız gibi bağlanmayı deneyelim.

Evet, artık bağlanmaya çalıştığımızda parola sormadan bekliyor bağlanamıyor. Yani komutumuz işe yaradı.
Peki bu yazdığımız kuralı silmek için ne yapacağız ? Çok basit, kural eklermiş gibi -D parametresi ile oluşturduğumuz kuralı sırasına göre silebiliriz

Önce kuralları listeleyelim,

Şimdi bizim kuralımız OUTPUT kısmında 1. sırada şimdi bu kuralı silelim bunun için şu
komutu kullanıyoruz

iptables -D OUTPUT 1

Bu işlemden sonra yeniden bağlanmyı denediğinizde bağlantı kurulacaktır.

Eğer belirli bir porttan gelen tüm bağlantıları engellemek istersek port belirtip kaynak adres belirmeyiz bu
sayede isteğimiz gerçekleşir. Bu işlem için şöyle yapıyoruz.

iptables -A INPUT -p tcp --sport 80 -j DROP

Komutun anlamı ise şudur 80 numaralı porttan (–sport 80) ve TCP protokolunü(-p tcp)  gelen tüm bağlantı isteklerini(INPUT)
kabul etme(-j DROP)

Bu komuttan sonra kurallarımızı listeleyelim.

Gördüğünüz gibi kuralımız orada belirmiş.

Son olarak bir örnek verelim[1]

Iptables kullanarak sistemden sadece http ve DNS erişimini sağlayalım.
Öncelikle Policy yani kuralları tüm bağlantıları reddetmesini sağlayacak şekilde ayarlayalım.

iptables -P INPUT DROP
iptables -P OUTPUT DROP

NOT: iptables’de -P parametresi ile ana kuralların genel olarak uygulayacağı davranışı belirleyeblirsiniz.

Şimdi Durumumuza bakalım.

Şimdi http ve dns’ye izin verecek şekilde ayarlayıp son durumu görelim.

iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT -> Hedef portu 80 olan paketlerin çıkışına izin verir.

iptables -A INPUT -p tcp --sport 80 -j ACCEPT -> Kaynak portu 80 olan paketlerin girişine izin verir.

iptables -A OUTPUT -p udp --dport 53 -j ACCEPT -> Hedef portu 53 olan paketlerin çıkışına izin verir.

iptables -A INPUT -p udp --sport 53 -j ACCEPT -> Kaynak portu 53 olan paketlerin  girişine izin verir.

Evet, şimdi son durumu görelim.

Gördüğünz gibi istediğim kurallar hazır. Eğer kuralların hepsini aynı anda silmek isterseniz

iptables -F komutunu kullanabilirsiniz.

[1] = Bilişimin Karanlık Yüzü – Sayfa 335-336

21
Eki
div.example { padding: 5px; font-family: Courier; border: 1px dashed #cccccc; background-color: #eeeeff; margin-left: 5%; margin-right: 5%; } table.inline { border-style:none; background-color:#fff; } table.inline th { padding:3px; border:1px solid #8cacbb; background-color:#dee7ec; } table.inline td { padding:3px; border:1px solid #8cacbb; }
    IP Tables, güvenlik duvarı için Linux'ta kullanılan temel araçlardan birisidir. Linux'un çekirdek uzayındaki güvenlik duvarı gerçekleştirimi olan netfilter ile etkileşime giren, kullanıcı uzayında çalışan bir takım araçların bir araya gelmesinden oluşmuştur. IP Tables bir takım kurallar(rules) ve eylemlere(actions) göre davranır. Kurallar hangi paketler (ör. belli bir ağdan gelen paketler) için hangi eylemlerin (ör. paketlerin düşürülmesi) gerçekleştirileceğini belirlerler. Netfilter her paket için bütün kuralları sırasıyla işletecektir. Eşleşen bir kural bulduğunda bu kural için tanımlanan eylemi işletir.

$man iptables

ile kılavuzu okuyabilirsiniz.

Tablolar
iptabes ismi iptables'ın tablolar üzerinde çalıştığı gerçeğinden gelmektedir. Tabloların her biri belli bir paket davranışı üzerinde özelleştirilmiştir. Aşağıdakiler Linux 2.6.8 çekirdeği üzerinde varolan tablolardır(değişik çekirdek sürümlerinde değişik tablolar olabilir):

Tablo Anlamı
raw Paketlerin düşük seviye ayrıştırılması.
nat Paket başlığında değişiklikler (where NAT takes place).
mangle Özelleştirilmiş paket ayrıştırması.
filter Paket filtreleme.

Paketle ne yapmak istediğinize bağlı olarak uygun bir tablo bulunmaktadır.

Zincirler (Chains)
Ip Tables'ta, her tabloya yapışık ve herbiri farklı trafik tipiyle ilişkili birçok zincir vardır:


Zincir Anlamı
PREROUTING Yönlendirmeden(routing) devreye girmeden makineye gelen trafik.
INPUT Makinenin kendisine gelen trafik.
FORWARD Makine üzerinden geçen trafik (başka makinede üretilen, hedefi başka makine olan).
OUTPUT Yerel olarak yaratılmış trafik (hedef yerel ya da dış bir makine olabilir).
POSTROUTING Dışarı giden trafik.

Ayrıca kendi zincirlerinizi oluşturmak da mümkün.

Veri Akışı
Linux çekirdeğinde her tablo/zincirde veri akışı aşağıdaki grafikte gösterilmiştir. Her kutuda zincir ve o zincir için geçerli tablolar gösterilmiştir. Trafik her zincir için geçerli her tablodan sırasıyla geçmektedir. Örneğin,  PREROUTING zincirinde raw, mangle ve nat tabloları var. Trafik akışı sırasıyla bu tabloların üçünden de geçer.



       Incoming
Traffic
|
|
V
+----------+
|PREROUTING|
+----------+
| raw | <--------------+
| mangle | |
| nat | |
+----------+ |
| |
| |
Routing |
+- Decision -+ |
| | |
| | |
V V |
Local Remote |
Destination Destination |
| | |
| | |
V V |
+--------+ +---------+ |
| INPUT | | FORWARD | |
+--------+ +---------+ |
| mangle | | mangle | |
| filter | | filter | |
+--------+ +---------+ |
| | |
| | |
V | |
Local | |
Machine | |
| | |
| | |
V | |
Routing | |
Decision | |
| | |
| | |
V | |
+--------+ | |
| OUTPUT | | |
+--------+ | |
| raw | | |
| mangle | | |
| nat | | |
| filter | | |
+--------+ | |
| | |
| +-------------+ |
| | POSTROUTING | Local
+----> +-------------+ --> Traffic
| mangle |
| nat |
+-------------+
|
|
V
Outgoing
Traffic


Örnek olarak makinede üretilen ve yine makineye dönen bir trafik şu şekilde bir yol izler:

  1. Paket yerel bir süreç ya da çakirdek tarafından üretilir
  2. Yönlendirme kararı
  3. OUTPUT: raw
  4. OUTPUT: mangle
  5. OUTPUT: nat
  6. OUTPUT: filter
  7. POSTROUTING: mangle
  8. POSTROUTING: nat
  9. PREROUTING: raw
  10. PREROUTING: mangle
  11. PREROUTING: nat
  12. Yönlendirme kararı
  13. INPUT: mangle
  14. INPUT: filter
  15. Paket yerel bir süreç ya da çekirdek tarafından alınır
 Kurallar (Rules)
Belli zincir/tablolar için hangi paketlere hangi eylemlerin uygulanacağını belirlemek için kurallar tanımlamak yeterlidir. Bütün kurallar bütün zincirlere uygulanmaz.

Zincir yönetiminde kullanılan bazı seçenekler ve parametreler
Zincir yönetiminde kullanılan seçenekler:
-N: Yeni zincir ekleme
-X: Boş zincir silme
-P: Temel zincirlerdeki kuralı (policy) değiştirme
-L: Zincir kurallarını listeleme
-F: Zincirlerdeki kuralları boşaltma
-Z: Zincirlerdeki paket ve byte sayacını sıfırlama

Zincirlere kural tanımlamak için:
-A: Zincire yeni kural ekleme
-I: Zincirde herhangi bir konuma kural eklemek için
-R: Zincirde herhangi bir konumdaki kuralı değiştirmek için
-D: Zincirden herhangi bir kural silmek için

Zincirdeki kuralların yönetiminde kullanılan parametrelerden bazıları:
-p: protokol
-s: kaynak makine
-d: hedef makine
-i: Giriş işleminde kullanılacak arabirim
-o: Çıkış işleminde kullanılacak arabirim
-j: Uygulanacak kural
-t: Kullanılacak zincir

Basit Komutlar
sudo iptables -L

komutu iptables'taki kurallarınızı listeler. Eğer henüz herhangi bir kural tanımlamadıysanız şu şekilde bir çıktıyla karşılaşıcaksınız:

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Kurulu Oturumlara İzin Vermek:
Halihazırda kurulu oturumların trafiğine izin vermek için:
$sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Belli Bir Porttan Gelen Trafiğe İzin Vermek
Öntanımlı SSH portundan (22) gelen trafiğe izin vermek için, iptables'a bu porttan gelen bütün TCP trafiğine izin vermesini söyleyebilirsiniz:
$sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT
Komutu incelersek:
  • -A INPUT: Gelen trafiğe bakmak için kuralı girdi zincirine ekliyoruz
  • -p tcp: TCP olup olmadığına bakıyoruz
  • --dport ssh: Eğer öyleyse, girdinin ssh portuna gidip gitmediğine bakıyoruz
  • -j ACCEPT: Eğer öyleyse, girdiyi kabul ediyoruz
Bu eklemelerden sonra kuralları tekrar kontrol edersek:
$sudo iptables -L
 Chain INPUT (policy ACCEPT)
target     prot opt source               destination       
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh

Şimdi gelen bütün web trafiğine izin verelim:
$sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Kurallarımızı tekrar kontrol edelim:
$sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
Özel olarak ssh ve web trafiğine izin verdik ama herhangi bir engelleme yapmadığımız için bütün trafik devam edecektir.

Trafiği Engelleme
Bir paketi kabul etmek için bir kural tanımladığımızda, diğer kurallar onu etkilemez. Ssh ve web trafiğine izin veren kurallarımız önce geldiği sürece bütün trafiği engellesek de bu portlardan gelen trafik devam edecektir. Önemli olan bu kuralı sona eklemektir:
$sudo iptables -A INPUT -j DROP
$sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
DROP       all  --  anywhere             anywhere
Özel olarak herhangi bir arayüz(interface) belirtmediğimiz için, ssh ve web haricinde bütün portlardaki ve arayüzlerdeki trafik engellenir.
iptables Düzenleme
Son tanımladığımız kuralla loopback arayüzü de engellenmiş oldu. Engelleme kuralını özel olarak -i eth0 ile sadece eth0 için tanımlayabilirdik. Bunun yanında loopback için de bir kural ekleyebiliriz. Kuralımızı eklediğimizde en sona geleceği ve onun öncesinde bütün trafiği engellediğimiz için bir işe yaramayacaktır. Bu yüzden bu kuralı dah önceye eklemeliyiz:
$sudo iptables -I INPUT 1 -i lo -j ACCEPT
$sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere           
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
DROP       all  --  anywhere             anywhere
Bu açıdan bakınca ilk ve son satır neredeyse aynı. Daha detaylı bakmak için:
$sudo iptables -L -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination        
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere           
 2661  616K ACCEPT     all  --  any    any     anywhere             anywhere             state RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:ssh
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:http
  222 24504 DROP       all  --  any    any     anywhere             anywhere


Kaynaklar: