FreeBSD sistemlerde

IPFIREWALL Kurulumu ve Konfigürasyonu

Güncellenme tarihi: 8 Aralık 2002


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.


* GÜVENLİK DUVARININ AĞ ÜZERİNDEKİ YERİ:


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.


* GEREKLİ DONANIM:

Ö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.


* BAŞLANGIÇ:

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"


* KERNEL:

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ÖZDİZİMİ ve KULLANIM ŞEKLİ:

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:
-aListeleme esnasında sayaçları gösterir. show parametresi default olarak -a parametresini barındırır.
-fflush 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.)
-tKuralların son eşleşme zamanını gösterir.(timestamp)
-qYapılan işlemlerin çıktısının ekrana verilmesini engeller (sessiz)
-NKuralları 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]

<actions>:
allowkurala uyan paketlerin geçmesine izin verir
countkurala uyan paketlerin sayaçlarını günceller
denykurala uyan paketleri siler.
divert portkurala 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_noPaketi dummynete yönlendirir. Dummynet bir trafik düzenleme kütüphanesidir. (Bandgenişliği, kuyruk ayarları, paket bekletme vb.)
resetkurala uyan paketleri reddeder. TCP reset (RST) paketi göndermeye çalışır.
skipto kuralnokurala uyan paketleri verilen kural numarasina gönderir. Paket kurallardan geçmeye devam eder.
tee portpaketlerin birer kopyasını verilen port numarasına gönderir.
unreache kodgelen 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 ...

<proto>: Kuralın protokolü (ip, tcp, udp veya all)

<src> to <dst>:
{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
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
[portlar]: {port | port-port} [,port[,...]] biçiminde kullanılır. port-port ifadesi birinci port ile ikinci port arasındaki tüm portları kapsar

[interface-spec]:
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

[options]:
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.
0echo reply
3destination unreachable
4source quench
5redirect
8echo request
9router advisement
10router solicitation
11time-to-live exceeded
12IP header bad
13timestamp request
14timestamp reply
15information request
16information reply
17address mask request
18address mask reply
iplen <uzunluk>: Toplam (header+data) uzunluğu uzunluk kadar olan IP paketlerini kapsar.
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.
ssrrstrict source route
lsrrloose source route
rrrecord packet route
tstime stamp
ipttl <ttl>: Time To Live değeri ttl kadar olan IP paketlerini kapsar.
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.
mssmaximum segment size
windowtcp window advertisement
sackselective ack
tstime stamp (rfc1323)
cct/tcp connection count (rfc1644)


* TRAFİK DÜZENLEME KONFİGÜRASYONU (DUMMYNET)

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:

ipfw pipe <pipe_no> config <pipe konfigürasyonu>

<pipe konfigürasyonu:>
bw <bandwidth>:
Bantgenişliği [K|M] {bit/s | Byte/s } ile ölçülür.
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/s
delay ms-delay:
Paket 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

* ÖRNEKLER

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:
ipfw -a list
Aşağıdaki komut mevcut kuralları, hit sayıları ve son eşleşme zamanı ile birlikte listeler:
ipfw -at list
Aş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 22
Bu ö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
TRAFİK DÜZENLEME:
Aşağıdaki örnek gelen paketlerin %10'unu siler.
ipfw add prob 0.10 deny all from any to any in
Sıradaki örnek, yukarda yapılan işlemi dummynet aracılığı ile pipe kullanarak yapmaktadır
ipfw add pipe 2 all from any to any
ipfw pipe 2 config plr 0.10
Ağ 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 add pipe 1 all from 10.0.1.0/24 to any out
ipfw pipe 1 config bw 300Kbit/s queue 50KBytes
Mevcut 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 add pipe 1 all from any to any out
ipfw add pipe 2 all from any to any in
ipfw pipe 1 config bw 256Kbit/s
ipfw pipe 2 config bw 256Kbit/s
Trafik 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 1 all from any to any out
ipfw pipe 1 config delay 250ms bw 512Kbit/s


Beni FreeBSD dünyasına kazandıran Sn. Kutluhan KİBRİT'e sonsuz saygı ve teşekkürlerimi sunarım.
Bu dökümantasyon, yazarın ismi ve ünvanı değiştirilmediği sürece, kaynak gösterilmek şartıyla kullanılabilir.

Hazırlayan:

Özkan KIRIK
ozkan@mersin.edu.tr

Mersin Universty
Computer Research and
Application Center
System Administrator