IPFIREWALL(IPFW), isminden de anlaşıldığı gibi ip based bir paket filtreleme sistemidir. IPFIREWALL'u diğer güvenlik duvarlarından ayıran en büyük özelliği ek bir yazılıma ihtiyaç duymadan traffic shaping yapabilmesidir. IPFIREWALL, tamamen kernel'a dayanır. Hatta tcpdump ile geçen paketleri sniff ettikten sonra en altta ???? packets received by filter, ???? packets dropped by kernel ifadesi geçer. IPFWye bir kural eklediğiniz zaman IPFWyi yeniden başlatmak gerekmez çünkü yeniden başlatamazsınız zaten :) Kural çalıştırıldığı anda uygulanır.
Firewall ağ üzerinde Router ile Yerel Ağ arasında ağ geçidi olarak yer alır. Burada dikkat edilmesi gereken nokta clientlarda ağ geçidi olarak router'i değil, firewallun tanımlanması. Firewall'un ağ geçidi ise router olarak tanımlanmalıdır.
Öncelikle, Yerel ağınızın büyüklüğüne göre bir bilgisayar seçmelisiniz. Şekilde görüldüğü gibi Firewalla iki ayri bağlantı bağlanıyor. Bunun için 2 adet ethernet kartına ihtiyacımız olacak. Yalnız ethernet kartının markasının seçiminde çok dikkatli olmamız gerekiyor. Çünkü bütün internet trafiği bu ethernetlerden geçeceği için trafiği mümkün olduğunca hızlı iletmeliyiz. En çok tercih edilen marka Intel.
Ethernetinizin markası Intel ise, FreeBSD ethernet kartlarınızı fxp0 ve fxp1 olarak tanıyacaktır. Router'a bağlanan ethernet fxp0, Yerel Ağ'a bağlanan ethernet ise fxp1 olsun. fxp0'a size verilen registered IPlerden birini atayın. fxp1'e ise yerel ağınızın büyüklüğüne göre bir unregistered IP bloğu seçip bir IP atayın.
Örnek olarak fxp0'a 212.152.10.5 nolu ipyi, fxp1'e ise 192.168.0.1 nolu ipyi verdiğimizi kabul ediyorum.
Ağ ayarlarımız tamamlandıktan sonra sistemi cvsup ile stable hale getirin.
İlk yapmamız gereken şey ethernet kartları arasında paket geçişine izin vermek. Bunun için /etc/sysctl.conf dosyasına net.inet.ip.forwarding=1 satırını ekleyin.
Açılış scriptlerinde düzenlemeler yapmamız gerekiyor. Burada kullanmadığımız tüm daemonları kapatmalıyız. Bunun için /etc/rc.conf dosyasına aşağıdaki satırları ekleyin veya var olanları değiştirin:
firewall_enable="YES"
firewall_type="open"
gateway_enable="YES"
tcp_drop_synfin="YES"
portmap_enable="NO"
inetd_enable="NO"
usbd_enable="NO"
IPFW'nin kernel tabanlı olduğundan bahsetmiştim. Gerekli tüm binary dosyalar FreeBSD kurulurken yükleniyor. Ancak kernel ayarları yapılmadan kullanmayı denediğinizde "ipfw: getsockopt(IP_FW_GET): Protocol not available" diye bir hata alırsınız. Yani gerekli fonksiyonlar mevcut değil. bu durumda kernel'da bir takım değişiklikler yapacağız.
Eğer kernel'ın ismini değiştirmediyseniz GENERIC olarak sisteminizde yer almalı. Aşağıdaki satırları /usr/src/sys/i386/conf/GENERIC isimli dosyaya ekleyin.
options ICMP_BANDLIM | #ICMP hata cevaplarına band genişliği sınırlaması getirir. D.O.S. attacklardan korunmaya yardımcı olur. |
options IPFIREWALL | #Firewall'ı aktif eder |
options IPFIREWALL_VERBOSE | #Log tutma (syslogd) |
options IPFIREWALL_VERBOSE_LIMIT=200 | #Kural başına düşen log limiti |
options IPFIREWALL_FORWARD | #TransparentProxy desteği |
options IPDIVERT | #Port Yönlendirme |
options DUMMYNET | #Traffic Shaper. Band genişliği ve kuyruk(queue) ayarları için gereklidir. |
options IPSTEALTH | #Bu firewalldan geçen paketlerin TTL'lerinin değiştirmeden geçmesini sağlar. Firewall'u traceroute gibi araçlardan gizlemek için gereklidir. |
options TCP_DROP_SYNFIN | #SFN+FINi düşür |
Aşağıda kerneli nasıl derleyip yükleyeceğimizi basit olarak anlattım:
console# /usr/sbin/config GENERIC
console# cd ../../compile/GENERIC
console# make depend
console# make
console# make install
Kernel'i install ettikten sonra bilgisayarınızı yeniden başlatın.
Uyarı: Eğer KernelSecurityLevel 2 veya daha yukarısı ise make install işlemini single-user mod'a geçip öyle yapmanız gerekiyor.
Sözdizimi çeşitleri:
ipfw [-f | -q] flush
ipfw [-q] {resetlog | delete} [kuralno ...]
ipfw [-q] add [kuralno] <rule-body>
ipfw pipe <kuralno> config <opsiyonlar>
ipfw pipe {delete | list | show} [kuralno ...]
Parametreler:
-a | Listeleme esnasında sayaçları gösterir. show parametresi default olarak -a parametresini barındırır. |
-f | flush parametresi için onay istemez. Ancak ifade herhangi bir tty'den çalıştırılmamışsa -f default olarak uygulanır (Ör: flush isteği crontab'tan çağrılmışsa herhangi bir tty'ye bağlı olmadığı için -f default olarak uygulanır.) |
-t | Kuralların son eşleşme zamanını gösterir.(timestamp) |
-q | Yapılan işlemlerin çıktısının ekrana verilmesini engeller (sessiz) |
-N | Kuralları listelerken IP adreslerini ve servisleri çözümleyip(resolve) göstermeye çalışır. |
Kural düzeni:
ipfw add [kuralno] [prob match_probability] <action> [log [logamount number]] <proto> from <src> to <dst> [interface-spec] [options]
allow kurala uyan paketlerin geçmesine izin verir count kurala uyan paketlerin sayaçlarını günceller deny kurala uyan paketleri siler. divert port kurala uyan paketi verilen port'a yönlendirir. (bu action için kernel'a IPDIVERT seçeneğinin yüklenmesi gerekir) fwd ip[,port] kurala uyan paketleri verilen ip ve port numarasına yönlendirir. IP adresi local bir IP ise port dikkate alınır. Ancak IP local değilse port numarası dikkate alınmaz ve route ile routing tablosuna göre yönlendirilir. pipe pipe_no Paketi dummynete yönlendirir. Dummynet bir trafik düzenleme kütüphanesidir. (Bandgenişliği, kuyruk ayarları, paket bekletme vb.) reset kurala uyan paketleri reddeder. TCP reset (RST) paketi göndermeye çalışır. skipto kuralno kurala uyan paketleri verilen kural numarasina gönderir. Paket kurallardan geçmeye devam eder. tee port paketlerin birer kopyasını verilen port numarasına gönderir. unreache kod gelen paketleri reddeder ve cevaben ICMP unreach paketi gönderir. ICMP unreach paketi ise belirlenen kod numarası ile belirlenir. kod numarası 0 ile 255 arasındadır. En çok bilinen kodlar: net, host, protocol, port, needfrag, srcfail, net-unknown, host-unknown ...
{any | me | [not] <ip adresi/maske> [portlar]}
any: tüm paketleri kapsar
me: Sistemin ethernet arayüznün ip numarasına uyan paketleri kapsar
<ip adresi/maske> aşağıdaki şekillerde kullanılabilir:ipno: 1.2.3.4 şeklinde olan ip adresleridir. Porta ve prokole bakılmaksızın bu ipyi içeren tüm paketleri kapsar[portlar]: {port | port-port} [,port[,...]] biçiminde kullanılır. port-port ifadesi birinci port ile ikinci port arasındaki tüm portları kapsar
ipno/bit: 1.2.3.4/24 biçiminde olan ip adresleridir. Bu ifade 1.2.3.0 dan 1.2.3.255'e kadar olan tüm ip adreslerini kapsar
ipno:mask: 1.2.3.4:255.255.240.0 biçiminde olan ip adresleridir. Bu ifade 1.2.3.0 dan 1.2.15.255'e kadar olan tüm ip adreslerini kapsar
in: Sadece gelen paketleri kapsar
out: Sadece giden paketleri kapsar
via <ifX>: Sadece <ifX> arayüzünden geçen paketleri kapsar via any: Herhangi bir arayüzden geçen tüm paketleri kapsar
established: RST veya ACK bitlerini içeren TCP paketlerini kapsar
icmptypes <types>: ICMP tipi, types parametresinde yer alan ICMP paketlerini kapsar. Deskteklenen ICMP tipleri aşağıda listelenmiştir.
iplen <uzunluk>: Toplam (header+data) uzunluğu uzunluk kadar olan IP paketlerini kapsar.
0 echo reply 3 destination unreachable 4 source quench 5 redirect 8 echo request 9 router advisement 10 router solicitation 11 time-to-live exceeded 12 IP header bad 13 timestamp request 14 timestamp reply 15 information request 16 information reply 17 address mask request 18 address mask reply
ipoptions <spec>: IP Header'ında spec parametresinde yer alan özellikleri taşıyan paketleri kapsar. <spec> parametresinin alabileceği değerler aşağıda listelenmiştir.
ipttl <ttl>: Time To Live değeri ttl kadar olan IP paketlerini kapsar.
ssrr strict source route lsrr loose source route rr record packet route ts time stamp
ipversion <ver>: IP versiyonu ver olan IP paketlerini kapsar (ipv4, ipv6)
layer2 Sadece Layer 2 paketleri kapsar. Bu bir IPFW2 opsiyonudur. IPFW1 ile çalışmaz.
mac <dst-mac> <src-mac>: Hedef mac adresi dst-mac ve kaynal mac adresi src-mac olan paketleri kapsar. Bu bir IPFW2 opsiyonudur. IPFW1 ile çalışmaz.
setup: SYN bit'ini içerip ACK bit'ini içermeyen TCP paketlerini kapsar. Bu opsiyon "tcpflags syn, !ack" opsiyonunun kısaltılmış halidir.
tcpack: Sadece ACK bit'ini içeren TCP paketlerini kapsar.
tcpoptions <spec> TCP header'ında spec ile belirtilmiş özellikleri taşıyan paketleri kapsar. Desteklenen TCP opsiyonları aşağıda listelenmiştir.
mss maximum segment size window tcp window advertisement sack selective ack ts time stamp (rfc1323) cc t/tcp connection count (rfc1644)
ipfw, paket filtrelemenin yanında dummynet aracılığı ile trafik düzenlemesi de yapabilmektedir.
Trafik düzenleyicisi, belirlenen özellikteki paketleri ayırır ve aynı statüde olan paketler için pipe denilen sanal bir bağlantı açar.
pipe, verilen bantgenişliği, paket bekletme süresi, kuruk boyutu ve paket kayıp oranlarında sanal bir bağlantı yaratır. Paket geçerken, ait olduğu pipe'ın kurallarına göre geçer.
pipe konfigürasyonu aşağıdaki düzende uygulanır:
bw <bandwidth>:Bantgenişliği [K|M] {bit/s | Byte/s } ile ölçülür.delay ms-delay:
Default değeri 0 dır. 0 limitsiz bantgenişliği anlamındadır. Bantgenişliğinin miktarı ile birimi arasında boşluk bırakılmamalıdır.ipfw pipe 1 config bw 1Mbit/sPaket bekletme süresi milisaniye ile ölçülür. Standart değeri 0 ms dir. Yani bekletme yoktur.plr kayıp_oranı:PLR=Packet Loss Rate, paket kayıp oranı. kayıp_oranı 0 ile 1 arasında bir değerdir. 0 kayıp yok, 1 ise %100 kayıp anlamına gelir.
Aşağıdaki örnekte pipe 1'den geçen paketlerin %50si kaybolacaktır.ipfw pipe 1 config plr 0.50
ipfw'nin çok fazla kullanım şekli var. Bunların birkaçı açıklamaları ile birlikte aşağıda örneklenmiştir:
BASİT PAKET FİLTRELEME:Aşağıdaki komut mevcut kuralları hit sayıları ile birlikte listelemer:TRAFİK DÜZENLEME:
ipfw -a listAşağıdaki komut mevcut kuralları, hit sayıları ve son eşleşme zamanı ile birlikte listeler:
ipfw -at listAşağıdaki örnek, www.kaynak.com dan gelen www.hedef.com un SSH portuna giden TCP paketlerin geçmesini engeller.
ipfw add deny tcp from www.kaynak.com to www.hedef.com 22Bu örnek, 123.45.0.0/16 dan my.host.orga gönderilen tüm paketlerinin geçmesini engeller. (123.45.0.0/16 = 123.45.0.0:255.255.0.0)
ipfw add deny all from 123.45.0.0/16 to my.host.org
Aşağıdaki örnek gelen paketlerin %10'unu siler.
ipfw add prob 0.10 deny all from any to any inSıradaki örnek, yukarda yapılan işlemi dummynet aracılığı ile pipe kullanarak yapmaktadıripfw add pipe 2 all from any to anyAğ geçidi olarak kullanılan bir firewallda pipe'ları kullanarak bantgenişliği yapılabilir. Yerel ağdaki 10.0.1.0/24 iplerinin trafiğini limitleyelim.
ipfw pipe 2 config plr 0.10ipfw add pipe 1 all from 10.0.1.0/24 to any outMevcut bantgenişliğinin giriş ve çıkış olarak eşit bir biçimde bölüştürmesi de giren ve çıkan paketler için ayrı kullar yazılmasıyla sağlanır. (Bantgenişliği toplam 512Kbit/s kabul ediliyor.)
ipfw pipe 1 config bw 300Kbit/s queue 50KBytesipfw add pipe 1 all from any to any outTrafik Düzenlemenin bir diğer özelliği de paket bekletme aşağıdaki örnek dışarı çıkan paketleri 250ms bekletmekte ve 512Kbit/s bantgenişliği limiti getirmektedir.
ipfw add pipe 2 all from any to any in
ipfw pipe 1 config bw 256Kbit/s
ipfw pipe 2 config bw 256Kbit/sipfw add pipe 1 all from any to any out
ipfw pipe 1 config delay 250ms bw 512Kbit/s