Merhabalar;
Geçen ay başladığımız "Güvenlik Duvarları ve Vekil Sunucu - NASIL?" adlı yazı dizimizin ikinci sayısıyla karşınızdayız. Geçen sayımızda kısaca güvenlik duvarı nedir, niye ihtiyacımız vardır, vekil sunucu nedir, bulunduğumuz kuruma ve konuma göre bunlardan hangilerine ihtiyacımız vardır, gibi sorulara biraz sistem yöneticisi gözünden giriş yapmaya çalışmıştık. Şimdi ise biraz daha teknik anlamda ele almaya çalışacağız..
Linux Filtreleme Güvenlik Duvarı Kurulumu için Ön Hazırlıklar
Donanım İhtiyaçları
Filtreleme güvenlik duvarı kurulacak makineler ağır donanımlara ihtiyaç duymazlar. Basit yönlendiricilerden(router) biraz daha fazlasına ihtiyacınız olacaktır. 32 MB ram'i, 250m harddisk'i (tercihen 500) olan eski bir pentium II bile işinizi görecektir. Hatta ayrı bir makineye bile ihtiyaç duymayabilirsiniz.
Çok trafik kaldırması düşünülen bir vekil sunucusu içinse gelişmiş bir işlemciye sahip olan, logların tutulması için yeterli harddisk alanı bulunan bir makine işinizi görecektir. Gelişmiş bir işlemci gerekliliği, sağlanan her bağlantıda ayrı bir işlem(process) üretilmesidir.
Yazılım İhtiyaçları
Filtreleme güvenlik duvarı kurmak için herhangi özel bir yazılıma ihtiyaç duymazsınız. Linux çekirdeği 2.2 sürümünden itibaren ipchains, 2.4 sürümünden itibaren de iptables programlarını içinde barındırır halde gelmektedir. Ayrıca iptables programını yapılandırmaya yarayan firestarter, shoreline, fwbuilder gibi programları da kullanabilirsiniz.
Kullandığınız dağıtıma göre iptables programının kurulu olup olmadığını kontrol edebilirsiniz.
ör: redhat temelli dağıtımlar için rpm -q iptables, pardus için pisi info iptables
Sisteminizde iptables'ın yüklü olduğunu öğrendikten sonra start, stop, restart komutlarıyla iptables'ın durumunu değiştirebilirsiniz. Debian temelli dağıtımlarda /etc/init.d/iptables start vb. komutlarla, redhat ve pardus'ta service iptables restart vb. komutları kullanabilirsiniz.
Iptables'ın Nasıl Çalıştığını Öğrenmek
Iptables temelde ip adresleri, ağ protokolleri(tcp, udp, icmp) ve portları kullanarak iş görmektedir. Bu konularda derinlemesine bilgi sahibi olmamıza gerek yok, ama iptables'ın genel çalışma düzeneğini anlamamızda bize yardımcı olacak kaynaklardır bunlar.
Iptables paketleri filtrelemek için 3 ayrı öntanımlı zincir kullanmaktadır: INPUT, OUTPUT ve FORWARD. Ağdan gelen ve ağa giden paketler bu kural zincirlerine göre nasıl bir işleme sokulacaklarına, paketlerin kabul edilip(accept) edilmeyeceklerine(drop) karar verilir.
Zincirler
Filtre tablosunda bulunan zincirler, şu işe yaramaktadır:
- INPUT: Ana makinaya gelen bütün paketler
- OUTPUT: Ana makinadan çıkan bütün paketler
- FORWARD: Ana makinadan çıkmamış, ana makinaya da gelmeyen ama bu makina üzerinden geçirilen(routed by) bütün paketler. Bu zincir, makinanızı yönlendirici(router) olarak kullandığınız zaman tercih edilmektedir.
Yazı boyunca daha çok INPUT zinciri üzerinde duracağız, yani bilgisayarımıza gelen paketleri filtrelemekle (kötü adamları içeri sokmamakla :) ) uğraşacağız.
Kurallar her zincir için bir liste içine eklenmektedir. Paketler de kontrol sırası kendilerine geldiğinde baştan başlayarak her kurala göre kontrol edilirler. Eğer paket bu kurallardan birine uyuyorsa, paketi kabul etmek(accept) ya da paketi düşürmek(drop) gibi seçeneklerden biri uygulanır. Bir paket, kurallardan birine uyuyorsa, o kurala uygun bir şekilde işlenir ve o paketle ilgili işlem biter. Devamında zincirdeki diğer kurallara uyup uymadığı kontrol edilmez. Peki paket zincir boyunca hiçbir kurala uymazsa ne olur? O zaman da bu zincir için öntanımlı seçenek neyse, pakete o işlem uygulanır. Bu ön tanımlı işlem de ya paketi kabul etmek ya da paketi düşürmektir.
Zincirlerdeki öntanımlı davranışların belirlenmesi, güvenlik duvarımızı nasıl organize edeceğimize karar vermeden önce üzerinde dikkatli düşünmemiz gereken iki temel seçeneğin üzerinde durmaktadır:
- Öntanımlı seçeneği "bütün paketleri düşür/engelle"ye ayarlarız, sonra da güvenilir ip adreslerinden ya da bittorent, FTP sunucusu, Ağ sunucusu, Samba dosya sunucusu gibi servislerin çalıştığı belirli portlardan gelen paketlere izin verecek kurallar düzenleriz. Ya da,
- Öntanımlı seçeneği "bütün paketleri kabul et" diye ayarlayıp, güvensiz IP adresi aralıklarını ya da gizli servislerimizin çalıştığı veya hiç bir servisin çalışmadığı portları kapatacak kurallar düzenleriz.
Bu iki yaklaşımdan, sizin de tahmin edeceğiniz gibi; 1. durumun INPUT zincirine gelecek paketler üzerinde, 2. durumun ise OUTPUT zincirinden geçip, makinadan dışarıya çıkarılacak paketler üzerinde kullanılmakta olduğu, beklenen bir davranıştır.
Basit bir Kural Kümesi Yazmak
!! Dikkat !! bu noktadan itibaren öntanımlı kural kümesini bozacağız. SSH'la bağlandığınız uzak bir makinede, şimdi anlatacaklarımı deniyorsanız, kendinizi dışarıda bırakma ihtimaliniz bulunmaktadır. Bu yüzden başlangıçta, içeri girmenizi sağlayacak, dışarıda kalmanıza izin vermeyecek bir kuralı mutlaka eklemeniz gerekmektedir.
Örnekler üzerinden devam edeceğimiz yazımızda ilk örneğimizde Stateful Packet Inspection(SPI) (durumsal paket denetleme) türü bir güvenlik duvarı için basit bir kural kümesi yaratacağız. Bu küme sayesinde bütün giden paketlere izin verilecek ama gelen paketler arasında istenmeyenlerin hepsi engellenmiş olacak:
# iptables -F
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# iptables -P INPUT DROP
# iptables -P FORWARD DROP
# iptables -P OUTPUT ACCEPT
# iptables -A INPUT -i lo -j ACCEPT
# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -L -v
bu kural kümesinin aşağıdaki çıktıyı vermesi lazım:
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- lo any anywhere anywhere
0 0 ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
şimdi teker teker bu 8 komutun ne işe yaradığına bakıp ne yaptığımızı daha iyi anlamaya çalışalım:
- iptables -F Öncelikle -F flush özelliğini kullanıp bulunan bütün kurallardan kurtulduk. Bu sayede yeni kurallar ekleyebileceğimiz temiz bir durum oluşturmuş olduk.
- iptables -A INPUT -p tcp --dport 22 -j ACCEPT burada TCP üzerinden SSH bağlantılarını 22. porttan yapmaya izin vermekteyiz. Bu kural, uzak sistemler üzerinde SSH'la bağlantı kurarak çalışırken olası kaza kilitlenmelerini önlemek için alınan bir önlemdir.
- iptables -P INPUT DROP -P seçeneği bahsedilen zincirdeki öntanımlı kuralı belirlemektedir. Yani INPUT zinciri üzerindeki öntanımlı seçeneği DROP'a eşitledik. Yani bundan sonraki kuralların hiçbirine uymayan bir paketle karşılaşırsak, kural zincirimiz o paketi reddedecek. Aynı zamanda, kural zincirinin bu haliyle, bir üstteki kuralı yazmamış olsaydık, ssh'la bağlandığımız uzaktaki bir makinaya erişimimizi kapatıp bir daha giremez hale getirecektik kendimizi.
- iptables -P FORWARD DROP Aynı şekilde FORWARD zinciri için de öntanımlı davranışı DROP'a çevirdik. Zaten bilgisayarı yönlendirici(router) olarak kullanmadığımız için bilgisayarımızdan geçip giden hiç bir pakedin olmaması gerekir.
- iptables -P OUTPUT ACCEPT Sonunda OUTPUT zincirinin öntanımlı davranışını da ACCEPT olarak ayarladık, bilgisayarımızdan çıkan bütün trafiğe izin vermek istiyoruz (kullanıcılarımıza güveniyoruz ;) )
- iptables -A INPUT -i lo -j ACCEPT Şimdi sıra bazı kuralları eklemeye geldi. -A seçeneğini yeni bir kural eklemek istediğimiz zaman kullanıyoruz. Bu örnekte INPUT zincirine kural eklemeye çalışıyoruz. -i seçeneği hangi arayüze giden paketleri seçeceğimizi gösteriyor, bu örnekte lo (localhost, 127.0.0.1) ve -j seçeneği de hangi işlemin yapılacağını seçmemizi sağlar. Yani bu kural; lo arayüzüne yol almakta olan bütün paketleri kabul etmemizi sağlamaktadır. Genel olarak bu kural da gereklidir, çünkü bir çok yazılım, localhost adaptörüyle iletişim halinde olmayı bekler.
- iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT En çok işi yapan aslında bu kuraldır; yine kuralımızı INPUT zincirine eklemekteyiz(-A).. -m seçeneği ile bir modül(durum) yüklemeye çalışıyoruz. Bu durum modülü (state module), paketin ne durumda olduğunu inceler ve NEW, ESTABLISHED ya da RELATED seçeneklerinden hangisi olduğuna karar verir. NEW, ana makina(host) tarafından başlatılmamış bağlantıları sağlamaya çalışan gelen paketlerine verilen addır; ESTABLISHED ve RELATED ise kurulmuş bir bağlantının bir parçası olan ya da kurulmuş bir bağlantı ile alakası olan gelen paketlerini adlandırmak için kullanılırlar.
- iptables -L -v En sonunda -L seçeneği ile kuralları listeleyebilir, ve henüz eklediğimiz bu kuralların doğru çalışıp çalışmadıklarını kontrol edebiliriz.
Bütün bunları yaptıktan sonra yapmamız gereken şey, bu ayarları kaydetmektir. Redhat temelli bir dağıtım kullanıyorsanız;
# /sbin/service iptables save
komutuyla ayarlarınızı kaydedebilirsiniz; ki bilgisayarınızı yeniden başlattığınızda yeni ayarlarınız otomatik olarak uygulanmaya başlansın..
Bu komut redhat tabanlı sistemlerde iptables init betiğini çalıştırır, bu betik /sbin/iptables-save komutunu çalıştırır ve mevcut iptables konfigürasyonunu /etc/sysconfig/iptables altına yazar. Yeniden başlatmanın ardından iptables init betiği /etc/sysconfig/iptables altında kaydedilmiş olan kuralları /sbin/iptables-restore komutunu kullanarak yeniden uygular.
Tabi ki bu yukarıdaki komutların hepsini tek tek elle girmek oldukça yorucu ve gereksiz bir iş. Bu yüzden verdiğimiz komutları aşağıdaki gibi bir betikle çalıştırmamız da mümkün:
#!/bin/bash
#
# iptables ornek konfigurasyon betigi
#
# Yuklu olan butun kurallardan kurtul (Flush)
#
iptables -F
#
# 22\. port uzerinden SSH baglantilarina izin ver
# Ozellikle uzak baglanti kurulan sunuculara SSH'la baglanabilmeyi engellememek icin onemli bu satir.
#
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#
# INPUT, FORWARD ve OUTPUT zincirleri icin ontanimli davranislari belirle
#
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
#
# localhost'a erisimi sagla
#
iptables -A INPUT -i lo -j ACCEPT
#
# ESTABLISHED ya da RELATED baglantilara ait olan paketleri kabul et
#
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#
# Ayarlari kaydet
#
/sbin/service iptables save
#
# Kurallari listele
#
iptables -L -v
Bu betiği bilgisayarınıza indirip, en sevdiğiniz metin düzenleyicinizle açarak kaydedip, çalıştırma hakkı verdiğinizde (chmod x firewall_dosyamiz) ./firewall_dosyamiz komutuyla çalıştırabilirsiniz.
ARAYÜZLER
Bir önceki örneğimizde belirli bir arayüze gelen bütün paketleri nasıl kabul edebileceğimiz öğrenmiştik:
iptables -A INPUT -i lo -j ACCEPT
İki ayrı arayüzümüz olduğunu düşünelim şimdi de, eth0 ve ppp0(ya da nic için eth1 de olabilir). eth0 içeriye dönük olan yerel ağ bağlantımız için, ppp0 ise dışarıya dönük olan çevirmeli ağ bağlantımız için kullanılıyor olsun. Yerel ağımızdan gelen bütün paketleri kabul etmek ama dış ağdan gelen paketleri filtrelemeye devam etmek isteyebiliriz. Bunun için önce şunu yapmalıyız:
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth0 -j ACCEPT
!! DİKKAT !! Eğer dış internet bağlantımızı sağlayan arayüzden(misal ppp0 çevirmeli ağ modemi) gelen paketlerin hepsini kabul etmek isteyip de
iptables -A INPUT -i ppp0 -j ACCEPT
yazmış olsaydık, güvenlik duvarımızı tamamen kaldırmış olacaktık :)
IP Adresleri
Bütün bir arayüzü gelen paketlere açmak yeterli miktarda kısıtlayıcılıkta olmayabilir tabi ki. Gelen paketleri kabul etmek ve reddetmek konusunda daha seçici davranabilmek için ip adresleri üzerinden kısıtlamalara da gidebilmemiz gerekir. 192.168.0.x gizli alt ağını kullanan küçük bir bilgisayar ağı oluşturduğumuzu varsayalım. Güvenlik duvarımızı güvenli bir adresten (misal 192.168.0.4) gelen paketlere açabiliriz:
# Guvenilir IP adreslerinden gelen paketleri kabul et
iptables -A INPUT -s 192.168.0.4 -j ACCEPT # IP adresini ihtiyaciniza gore degistirin.
Bu komutu açıklamaya çalışırsak, -A ile INPUT zincirine kuralımızı eklemeye karar veriyoruz. -s ile 192.168.0.4 ip adresini kaynak olarak gösteriyoruz. komut olarak da -j ile ACCEPT komutunu veriyoruz ki bu adresten gelen bütün paketleri güvenlik duvarımız kabul etsin.
Peki sadece bir adres değil birden çok adrese izin vermek istiyorsak? Hepsini elle ekleyebiliriz tabi ki, ama bunun için bir başka yol daha var. Alt ağ maskesini ya da standart bölü işaretini kullanabiliriz bunun için(ayrıntılı bilgi için bkz: [1] ve [2]). Mesela 192.168.0.x(1'den 254'e kadar) aralığındaki ip adreslerinden gelen paketlere izin vermek için aşağıdaki kodların ikisini de kullanabiliriz:
# Guvenilir IP adreslerinden gelen paketleri kabul et
iptables -A INPUT -s 192.168.0.0/24 -j ACCEPT # standard bolu isaretini kullanarak
iptables -A INPUT -s 192.168.0.0/255.255.255.0 -j ACCEPT # alt ag maskesi kullanarak
Peki ip adresine göre, belli bir ip aralığına göre filtreleme yapabiliyoruz, neden belirli bir MAC adresine göre filtreleme yapmayalım? Bunun için mac modülünü yüklememiz gerekli. Hatırlarsanız daha önce ESTABLISHED ve RELATED paketlerinin karşılaştırılması için state modülünü yüklemiştik. Şimdi de mac modülünü kullanarak ip adresinin yanında belirli bir MAC adresine sahip bir bilgisayardan gelen paketlerin kabul edilmesini nasıl sağlayabiliriz, ona bir bakalım:
# Guvenilir IP adreslerinden gelen paketleri kabul et
iptables -A INPUT -s 192.168.0.4 -m mac --mac-source 00:50:8D:FD:E6:32 -j ACCEPT
Gördüğünüz üzere --mac-source parametresiyle filtreden geçmesini istediğimiz bilgisayarın ağ kartının adresini verebiliyoruz. Hatırlatmakta yarar var, bilgisayarınızın MAC adreslerini görebilmeniz için ifconfig (kablosuz ağ kartları içinse iwconfig) komutlarını kullanabilirsiniz.
IP adresinin üzerinden yapılabilecek aldatmalara karşı mac adresini de filtre kuralları içinde belirtmek daha fazla güvenlik sağlamaktadır. Tabi dikkat etmeniz gereken bir diğer nokta, MAC adresi filtreleme internet üzerinden işinize yaramayabilir, ama yerel ağ'da oldukça iyi çalışmaktadır.
Port ve Protokoller
Yukarıda ip adreslerine ve belli arayüzlere göre filtrelemeyi nasıl yapacağımızı gördük. Bu sayede belirli güvenilir kaynaklara güvenlik duvarımız üzerinden tam erişimi sağlamaktayız. Şimdi belirli protokollere ve portlara göre nasıl filtreleme yapacağımızı göreceğiz.
Başlamadan önce filtrelemek istediğimiz servisin hangi ağ protokolü ve hangi portları kullandığını bilmemiz lazım. Mesela bittorent tcp protokolünü 6881 nolu port üzerinden kullanmaktadır, yani tcp protokolünü kullanıp bilgisayarımızın 6881 nolu portuna gelen bütün paketlere izin vermemiz gerekmektedir:
# Guvenilir IP adreslerinden gelen paketleri kabul et
iptables -A INPUT -p tcp --dport 6881 -j ACCEPT
Bu örnekte INPUT zincirine (-A) tcp protokolünü (-p ) kullanıp makinemize 6881 nolu porta gelen (--dport) [destination port] paketleri kabul etme kuralını ekliyoruz.
!! Dikkat !! : makinemize giriş yapılan portlar(destination) ve makinemize belirli bir kaynaktan gelen(source) portlar için filtre kuralı düzenlerken (--dport veya --sport komutlarını kullanırken) önce hangi protokolün kullanılacağını belirtmemiz gerekmektedir (tcp, udp, icmp, all).
Sadece tek bir port değil de bir port aralığı kullanabilmek içinse yukarıdaki örneği şu şekilde değiştirebiliriz:
# Guvenilir IP adreslerinden gelen paketleri kabul et
iptables -A INPUT -p tcp --dport 6881:6890 -j ACCEPT
Bu komut, 6881-6890 port aralığından gelen tcp paketlerine izin vermektedir.
Kavramları Birleştirmek
Temelleri gördükten sonra bu kuralları birleştirmeye başlayabiliriz. En popüler Linux/Unix hizmetlerinden biri olan güvenli kabuk(SSH) uzak bağlantılara izin veren bir programdır. SSH, öntanımlı olarak 22 nolu portu ve tcp protokolünü kullanmaktadır. Eğer makinemize dışarıdan bağlantılar yapılmasına izin vermek istiyorsak, 22. porta gelen tcp bağlantılarına izin vermemiz gereklidir:
# 22\. porta gelen tcp paketlerine izin ver (SSH)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Bu kural 22. porta gelen bütün tcp bağlantılarının açık olmasını sağlar ki bu durum büyük bir potansiyel tehlike arz etmektedir. Çünkü hackerlar kaba kuvvet yöntemiyle(brute force) kolay parola konulmuş hesapları kırabilirler. Ama makinemize bağlanacak bilgisayarların ip adreslerini bilirsek, hangi adreslere güvenebileceğimizi biliriz ve SSH için yazacağımız kuralda bu kısıtlamayı yansıtabiliriz. Mesela sadece yerel ağ adresimizden(192.168.0.x) SSH bağlantısı yapılmasına izin vermek istiyorsak:
# 22\. porta yerel ağdan gelen tcp paketlerine izin ver (SSH)
iptables -A INPUT -p tcp -s 192.168.0.0/24 --dport 22 -j ACCEPT
bu sayede port tarama yapan hackerlardan kendinizi korumuş olursunuz.
Bitirirken
Bu yazımızda paket filtreleme konusuna değinmeye çalıştık. Iptables programının temelde nasıl çalıştığını, filtreleme için kullanılan zincirleri, bu zincirlere nasıl kural eklendiğini ve kuralların neler içerdiklerini anlatmaya çalıştık. Bunun dışında TCP başlık değişikliği ve Ağ Adres Çeviricisi(NAT) üzerinde yapılacak güvenlik duvarı değişiklikleri de mümkündür, ama bu yazımızda bunlara yer vermedik.
Günümüzde güvenlik duvarı olarak her dağıtım özelleşmiş seçenekler sunmakta.. Ayrıca güvenlik duvarı olarak kullanılan ya da iptables kurallarını daha kolay yazmayı sağlayan programlar da mevcut. Internetin yaygınlaşmasıyla beraber güvenlik açıklarına dikkat etmeyen kullanıcı sayısı da artmakta. Bunun farkında olan kötü niyetli kullanıcılar ve hackerlar da sizin bilgisayarınıza sızıp bilgisayarınızı kötü emellerine alet etmekten çekinmemektedirler. Gerek kişisel bilgisayarınız olsun, gerekse yerel ağınızı kontrol eden bilgisayar olsun, güvenlik duvarı kullanmalısınız.
Güvenli ve özgür günlere..
Kaynaklar:
- [1] http://tr.wikipedia.org/wiki/Alt_a%C4%9F_maskesi , http://en.wikipedia.org/wiki/Subnetwork
- [2] http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing
- [*] http://wiki.centos.org/HowTos/Network/IPTables
- [*] http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables
- [*] http://wiki.debian.org/Firewalls