Linux ile Bir Güvenlik Duvarı Kuralım | e-bergi
Linux, günümüzde sunucularda ve masaüstü bilgisayarlarda yaygın olarak kullanılan bir işletim sistemi.
Bunun yanı sıra, güvenlik duvarı (firewall) makinası olarak da Linux kullanılması yaygın. Kimsenin yüzüne bile bakmak istemeyeceği kadar eski ve güçsüz bir makinaya çok hafif bir linux dağıtımı kurup,
yüzlerce kişilik bir ağın güvenliğini sağlayabilirsiniz.
Bu yazıda iki ağ arayüzüne sahip bir makinada Linux ile nasıl güvenlik duvarı oluşturabileceğimizi
inceleyeceğiz. Örneklerde, Debian Linux üzerinden üzerinden gideceğiz. Ubuntu gibi Debian türevlerinde
de anlatılanlar geçerli olacak. Diğer dağıtımlarda da temeller aynı olsa bile dosyaların yerleri, servisler, vb.
farklılıklar olabilir. Örneğin Redhat türevlerinde (Fedora, Centos) sistem kendi güvenlik duvarı kurallarıyla gelmekte, bu durumda kullandığınız sistemin belgelerine bakarak detaylarını öğrenmeniz gerekecek.
Öncelikle, sistemde iki ethernet kartı olduğunu varsayıyoruz. Bunlardan eth0 dışarıya bakan
ağ arayüzü, eth1 ise korumaya çalıştığımız ağa bakan arayüz olsun.
internet ve iç ağ arasında yönlendirme yapabilmek için, Linux çekirdeğindeki yönlendirme (forwarding) ayarını açmamız gerekiyor.
Bu işlemi root yetkileriyle yapmanız gerekli ( "su -" komutu ile root olduktan sonra, ya da komutun başına "sudo" ekleyerek)
Linux'taki iptables/netfilter altyapısı paketleri işlerken tablolar ve zincirlerden faydalanır (İngilizceleri: tables, chains).
Bir kaç çeşit tablo ve zincir bulunmasına rağmen, bu yazıda sadece "filter" tablosundan, INPUT, OUTPUT ve FORWARD
zincirlerinden faydalanacağız. Filter tablosu, ağ paketlerinin incelenip izin verildiği ya da engellendiği tablo.
Temel bir güvenlik duvarı paketleri hedef/kaynak IP adresi, hedef/kaynak portu gibi özelliklerine göre inceleyeceği
için, örneklerimizde filter tablosunu kullanıyor olacağız. Çeşitli zincirler arasında kullanacağımız üç tanesi ise;
INPUT: Internet'ten ya da iç ağdan yola çıkıp, güvenlik duvarının kendisine gelen paketler.
Örneğin güvenlik duvarının yönetimi için iç ağdan yapılan bir SSH bağlantısı, INPUT zincirinde işlem görecektir
OUTPUT: Güvenlik duvarı makinasından kaynaklanıp Internet'e veya iç ağa giden paketler. Örneğin güvenlik duvarı
makinasındaki paket yöneticisi, güncellemeleri indirmeye çalıştığında giden paketler OUTPUT zincirinde işlem görecekler
FORWARD: Br ağı korumak için kurulan güvenlik duvarında en önemli zincir FORWARD zinciridir, çünkü Internet'ten gelip
iç ağa gitmeye çalışan paketler bu zincirden geçerler. Aynı şekilde iç ağdan çıkıp Internet'e gitmeye çalışan paketler de bu zincirde işlem görürler.
Iptables kuralları girmek için izlenebilecek iki yol var. İlki kuralları "iptables"
programına parametreler halinde teker teker girmek. Bu yöntem çok verimli değil ve de kuralların girilmesi esnasında güvenlik duvarı yarım bir kural kümesi ile çalışıyor olacak. Tercih edeceğimiz ikinci yöntem ise tüm kuralları bir dosyaya yazıp "iptables-restore" komutuna yönlendirmek. Bu sayede hem verimli bir şekilde kuralları
yükleyebiliriz, hem de kural yükleme işlemi anlık olarak gerçekleştiği için kurallar yarımken paketlerin incelenmesi
söz konusu olmaz. Aşağıda temel bir iptables kural kümesi dosyası var, şu aşamada herhangi bir yönlendirme yapmayan, bu yüzden de FORWARD zincirini kullanmayan bir kural kümesi. Bu örneğin üzerinden devam edeceğiz.
Şimdi bu dosyanın nasıl bir kural kümesi tanımladığını satır satır inceleyelim.
En baştaki dört satır, "filter" tablosunu kullanacağımızı, ve INPUT, FORWARD, OUTPUT zincirlerindeki varsayılan işlemin ise pakete izin vermek
Bu satır, loopback arayüzü (yani "ifconfig -a" çıktısında 127.0.0.1 ip adresine sahip görünen arayüz) üzerinden gelen tüm paketlere izin veriyor.
Bu arayüze sadece makine üzerinde çalışan programlar paket gönderebileceğinden bunda bir sakınca yok, bazı programlar bileşenlerini loopback
arayüzü üzerinden konuşturmayı tercih ettiklerinden, bu kuralla onların sorunsuz çalışmasını sağlıyoruz.
Satırın detaylarına bakarsak "-A" parametresinden sonra kullanacağımız zinciri, "-i" parametresinden sonra hangi arayüzden gelen paketler üzerinde
işlem yapacağımızı belirttik. "-j" parametresiyle de bu pakete ne gibi bir işlem uygulanacağını belirtiyoruz; ACCEPT pakete izin vermemizi sağlıyor.
Bu satır önceden yapılmış bağlantıların devam paketlerine izin vermeyi sağlıyor. Iptables durumlu (stateful) bir güvenlik duvarıdır;
yani iptables kurallarında gelen paketlerin daha önce başlatılmış ve izin verilmiş (ESTABLISHED) bir bağlantıya ait olup olmadığına bakabilirsiniz.
Ya da FTP gibi birden fazla bağlantı kullanan protokollerde, daha önceden izin verilmiş bir bağlantıyla ilintili yeni bir bağlantı olup olmadığını (RELATED)
"-m state" parametresi bu durum kontrolünü etkinleştirirken, "--state" parametresinden sonra hangi durumlar üzerinde işlem yapabileceğimizi
belirtebiliyoruz. Burada ESTABLISHED ve RELATED durumlarındaki paketlere "-j ACCEPT" ile izin veriyoruz.
Bu satırda durumu tanımsız olan (INVALID) paketlere izin vermiyoruz "-j DROP" bu paketin daha fazla işlem görmeyeceğini ve "çöpe atılacağını"
Şimdi en çok kullanacağımız türden kuralları girmeye başladık. Paketin hedef IP ve hedef port bilgilerine göre filtreleme yapacağız.
"-p tcp", TCP protokolü taşıyan paketleri işlememizi sağlıyor. "--dport 22" hedef TCP portu 22 olan, "-s 10.0.0.45" de kaynak IP adresi 10.0.0.45 olan paketlerle kuralımızı sınırlıyor. INPUT zinciri ile birlikte tüm satırı ele alırsak; güvenlik duvarı makinasının
22. TCP portuna, 10.0.0.45 IP adresinden gelen tüm paketlere izin veriyoruz.
Bundan sonra aynı IP adresinden gelen SSH bağlantı paketleri,
iki üstteki ESTABLISHED durumdaki bağlantılara izin veren kuralımız sayesinde,
daha fazla incelemeye tabi tutulmadan kabul edilecekler. Yani ESTABLISHED kuralımız,
bir bağlantının sadece ilk paketinin tüm filtreme kurallarınca işlenmesini, daha sonraki paketlerin kısa
yoldan kabul edilmesini sağlıyor. Uzun bir kural kümesi olduğunda, önceden izin verdiğimiz bağlantılara ait paketlerin tekrar tekrar tüm kurallarca incelenmemesi önemli bir hız kazancı sağlayacaktır.
Bu kurallar, daha önce izin vermediğimiz tüm bağlantı isteklerinin reddedilmesini sağlar. Reddetme işlemini "-j REJECT" ve "-j DROP" kararlarıyla yapıyruz. TPC protokolü için ayrı, UDP protokolü için ayrı reddetme yöntemleri kullanıyoruz ("--reject-with"). Tüm diğer protokollerdeki paketleri
ise çöpe atıyoruz. Bu yaklaşıma "varsayılan olarak reddet" (default deny) adı verilir. İzin verilmeyen tüm bağlantıların varsayılan olarak reddedilmesi sistemin ve iç ağın güvenliğini sağlamakta önemli bir adımdır.
COMMIT satırı, kural kümesinin sonuna geldiğimizi belirtir. iptables bu satırı gördüğünde tüm kural kümesini tek bir anda, atomik olarak
Bu kural kümesini bir dosyaya kaydetikten sonra aşağıdaki gibi bir komutla dosyadaki kuralları etkinleştirebiliriz. Bu işlemi de root olarak yapmanız
Şimdi bir adım daha ileri gidelim, ve iç ağımızı koruyacak kuralları nasıl yazacağız onu görelim.
Aşağıdaki kuralları, COMMIT satırınının öncesine ekleyelim.
Bu kuralımızla, Internet'e bağlı eth0 arayüzü üzerinden gelip, 10.0.0.88 IP adresli bilgisayarın 53 numaralı UDP portuna giden
paketlere izin veriyoruz. Bu kural 10.0.0.88 IP adresli makinada DNS sunucusu çalıştırıyorsanız faydalı olacaktır.
-m mac --mac-source MAC_ADRESİ: Belirtilen MAC adresinden gönderilmiş paketleri yakalar, böylelikle bir makinanın IP
adresi değişse bile MAC adresine bağlı olarak filtreleme yapabilirsiniz. MAC adresini 01:23:45:67:89:ab şeklinde belirtmelisiniz.
MAC adresi filtresi sadece iç ağınız için anlamlıdır.
Ayrıca, yukarıdaki kurallar "!" işareti ile tersine çevrilebilir, örneğin "-s ! 10.0.0.13" ile, kaynak IP adresi 10.0.0.13 dışında herhangi bir
şey olan paketleri yakalayabilirsiniz.
Son örneğimizde, iç ağdan dışarı giden istekleri kısıtlamak istediğimizde nasıl bir yol izleyeceğimize bakalım.
Aşağıda FORWARD zincirine yeni eklediğimiz kurallarla birlikte tüm iptables kural kümemizi görebilirsiniz.
"#" işaretiyle başlayan satırlar yorum satırlarıdır, iptables tarafından işlenmezler ve kural kümesini açıklamak için kullanılabilirler.
Son olarak, bu yazıdaki örnek IP adresleri 10.x.x.x biçimindeki özel IP adresleri. Bu IP adreslerini kullanabilmek için NAT (Network Address Translation) yapılması gerekir. NAT konusuna
ilerki yazılarda değineceğiz. Bu yazıdaki örnek kural kümesini ise, iç ağınızdaki bilgisayarlarda "gerçek IP adresleri"
varsa kullanabilirsiniz. (Gerçek IP adresleri, 10.0.0.0/8 , 127.0.0.0/8, 172.16.0.0/12 ve 192.168.0.0/16 aralıkları dışında kalan IP adresleridir)