original in fr Vincent Renardias
en to tr Özcan Güngör
1993'den beri GNU/Linux kullanıcısı olan Vincent Renardias, 1996'da kendi geliştirmelerine başladı:Debian geliştiricisi, GIMP ve GNOME'un Fransızca çevirmeni, Marseille (PLUG)'daki Linux Kullanıcı Grubu'nun kurucusu...Şu an EFB' şirketinde ARGE yöneticisi.GNU/Linux hakkında yazmaya devam ediyor.
Bu makale ilk defa Linux Magazine France'ın güvenlik üzerine olan bölümünde yayınlanmıştır.Editör, yazarlar ve tercümanlar, bu konu hakkındaki her makalenin LinuxFocus'ta yayınlanmasına izin vermişlerdir.LinuxFocus, bunları İngilizce'ye çevirir çevirmez size sunar.Bu işle ilgili bütün kişilere teşekkür ederim.Bu tanıtım, bu kökene ait bütün makalelerde yer alacaktır.
Davetsiz teşebbüslerden korunmanın iyi yolarından biri, ağdaki gereksiz herşeyi filtrelemektir.Bu iş genellikle firewall denilen makinalarla yapılır.
Bu makalede, böyle bir sistemin gerekli temel uygulamalarını ve ayarlarını nasıl yapabileceğinizi gösterceğiz.
Filtreleme mekanizması, baı istenmeyen paketleri yakalayan bir ağ olarak düşünülebilir.Önemli olan, uygun büyüklükte bir ay bulmak ve onu uygun bir yere yerleştirmektir.
Paketli iyi bir şekilde filtrelemek için filtreleme mekanizması, korunacak ağ ile "dünyanın geri kalan kısmı" arasına konmalıdır.Bu genelde, biri iç ağa, diğeri dışarıyla bağlatı kuran router'a bağlı iki ağ arayüzleri(genellikle ethernet) ile yapılır.Böylece veriler, içeriğine göre veri geçişine izin veren ya da vermeyen firewall içinden geçmek zorunda kalır.
Filterleme mekanizmasına sahip makina üç farklı şekilde ayarlanabilir:
- Basit" ağgeçidi: Bu en çok kullanılan ayarlamadır.Makina, iki ağ arasına veya altağlar arasında ağgeçidi olarak kullanılır.Yerel ağdaki bilgisayarlar, varsayılan route olarak router yerine bu ağgeçidini kullanırlar.
- Proxy-Arp" ağgeçidi: Bir önceki ayralama, ağı altağlara böler.Bu da IP adreslerinin yarısını yok eder ve biraz can sıkıcıdır.Ağ ve broadcast adresleri kullanlırken, 16 adresli(ağmaskesi 28 bit olan) bir altağ örneğinde sadece 14 adres kullanılabilir.Altağa bir bit eklersek, 14 adresi 6'ya düşürürüz(8 IP eksi ağ ve broadcast adresleri).Bu IP kayıplarını istemeyeceğiz için bu makalenin ileri bölümlerinde açıklanacak bir yöntemi kullanabilirsiniz.Dahası, bu yöntemle, ne var olan makinaların ağ ayarlarında ne de router'da bir değişiklik gerekmez.
- Ethernet Köprüsü: bir ethernet ağgeçidi(IP ağ geçidi değil) kurmak, filtereleme mekanizmasının diğer makinalar tarafından görünmesini engeller.Bu tür bir ayar, Ethernet arayüzlerine herhangi bir IP adresi vermeden yapılabilir.Bu makina, ping, traceroute gibi araçlarla bulunamaz.Bu yöntemi ancak 2.2.x kernel ile yapabilirsiz.Çünkü 2.4.x kernellerde bu özellik henüz tamamlanmadı.
Şimdi, filremizi nereye kuracağımızı biliyoruz ve neyi engelleyeceğini neyi kabul edeceğini tanımlamalıyız.
Böyle bir filtreyi ayarlama iki şekilde yapılabilir:
- İyi olanı: Sadece kuralın kabul etiği paketler geçer diğerleri geçemez.
- Kötü olan:(maalesef en sık kullanılanı) sadece istenmeyen paketler durdurulur ve diğerleri kabul edilir.
Açıklaması kolay:İlk durumda, bir kuralın unutulması servisin doğru çalımamasına veya hiç çalışmamasına sebep olur.Genellikle hemen farkedilir ve gerekli kuralın eklenmesi yeterlidir.
İkinci durumda, bir kuralın unutulması, bulunması zor olan bir açığa neden olabilir.
Linux 2.4 ile en çok kullanılan filtreleme yazılımı Netfilter'dir.Linux kernel 2.2'deki 'ipchains'i değiştirir.Netfilter iki bölümden oluşur:kernel ile derlenmesi gereken kernel desteği ve sisteminizde kullanılabilir olan 'iptables' komutu.
İçinde açılaması olan bir örnek, uzun bir konuşmadan daha iyidir.Sonra filtreleme mekanizmasının nasıl yükleneceğini ve nasıl ayarlanacağını açıklayacağız.Önce makina, Proxy-Arp kullanılarak bir ağgeçidi olarak çalışacak ve IP adreslerinin sayısını sınırlayacak.Sonra filtreleme mekanizmasını ayarlayacağız.
Yazar, Debian dağıtımı için bir önceliğe sahiptir ancak diğer dağıtımlarla da yapılır.
Önce, kernelinizde Netfilter desteği olup olmadığını kontrol edin.Eğer varsa açılış iletilerinde şunu görmelisiniz:
ip_conntrack (4095 buckets, 32760 max)
ip_tables: (c)2000 Netfilter core team
Yoksa, Netfilter desteğini seçtikten sonra kerneli tekrar derlemelisiniz.Aranan seçenekler, "Networking Options" altındaki "Network Packet Filtering" altmeüsündedir."Netfilter Configuration" bölümünden, gerekli seçenekleri işretleyin.Şüphe duyduüunuz seçeneklerde, hepsini seçebilirsiniz.Dahası, Netfilter'i kernel eklemek, modül olarak kullanmaktan daha iyidir.Eğer herhngi bir sebeple Netfilter modüllerinde bir çalışmazsa, filtreleme çalışmaz.En iyisi olabilecel risklerden bahsetmeyelim.
Ayrıca 'iproute2' paketini de yüklemelisiniz(Bu sonuncusu, zorunlu değil ancak örneğimizde kullancağız çünkü ayarlama scriptlerinin kolaylaşmasını sağlayacaktır).Debian ile, 'apt-get install iproute' komutunu vermeniz yeterlidir.
Diğer dağıtımlarda, karşı gelen paketi bulun.Yükleyin veya aşağıda kaynak kodu verilmiştir.İndirin ve derleyin:
ftp://ftp.inr.ac.ru/ip-routing/
Şimdi iki Ethernet kartı ayarlanmalıdır.Linux kernelinin, bir ethernet kartını bulduktan sonra diğerini aramayı bıraktığını belirtelim.Yani sadece ilk kart bulunacaktır.
Çözüm için şunu lilo.conf dosyasına ekleyin:
append="ether=0,0,eth1"
Şimdi Ethernet arayüzlerini ayarlayalım.Kullanacağımız yöntem, bir IP adresinden tasarruf edebilmemiz için her iki karta da aynı adresi vermemize izin vermektedir.
Örneğin: 10.1.2.96/28 altağına sahip olalım.IP adreslerimiz 10.1.2.96 - 10.1.2.111 aralığındadır.Router, 10.1.2.97 adresine ve filtreleme makinası 10.1.2.98 adresine sahiptir.eth0 arayüzü, eğer bir hub ya da switch kullanılmıyorsa, router'a bir RJ45 cross bağlantı ile bağlıdır. eth1 arayüzü, bir hub/switch'e bağlanıp ordan yerel ağa bağlanır.
Her iki arayüz için de aşağıdaki parametreler geçerlidir:
address : 10.1.2.98 netmask : 255.255.255.240 network : 10.1.2.96 broadcast: 10.1.2.111 gateway : 10.1.2.97
Sonra, ayarlamaları bitirmek için, ağ kartlarının ilk ayarlarının yapılmasından sonra aşağıdaki script kullanılır:
net.vars: ayarlama değişkenleri PREFIX=10.1.2 DMZ_ADDR=$PREFIX.96/28 # Arayüz tanımlamaları BAD_IFACE=eth0 DMZ_IFACE=eth1 ROUTER=$PREFIX.97 net-config.sh: ağ ayarları scripti #!/bin/sh # Script çalışırken komutlaır görebilmek için aşağıdaki satırın başındaki diyezi silin # set -x # etc/init.d/net.vars dosyasındaki önceden tanımlanmış değişkenleri okuruz # Yerel ağdan şu anki rotalrı sileriz. ip route del $PREFIX.96/28 dev $BAD_IFACE ip route del $PREFIX.96/28 dev $DMZ_IFACE # Yerel ağa eth1'den router'a eth0'da ulabilecek # şekilde ayarlarız. ip route add $ROUTER dev $BAD_IFACE ip route add $PREFIX.96/28 dev $DMZ_IFACE # Her iki arayüzüde de Proxy-Arp'ı açarız. echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp echo 1 > /proc/sys/net/ipv4/conf/eth1/proxy_arp # Bir karta gelen verileri diğer karta iletebilmek # için IP yönlendirmesini açarız. echo 1 > /proc/sys/net/ipv4/ip_forward
Bizim ayarlamalar için gerekli olan Proxy-Arp mekanizmasına geri dönelim.
Aynı ağ içerisindeki bir makina diğeriyle konuşurken, kendi IP adresine karşı gelen Ethernet adresini(MAC adresini, donanım adresini) bilmesi gerekmektedir.Sonra kaynak makina şu soruyu yayınlar: 1.2.3.4 IP ardesine sahip arayüzün MAC adresi nedir? ve karşı makina cevap vermek zorundadır.
Bu "konuşma"nın tcpdump ile alınmış bir örneği:
- istek: 172.16.6.72 IP'li makina, 172.16.6.10 IP'li makinanın MAC adresini sormaktadır:
19:46:15.702516 arp who-has 172.16.6.10 tell
172.16.6.72
- cevap: 172.16.6.10 IP'li makina kart adresini gönderir:
19:46:15.702747 arp reply 172.16.6.10 is-at
0:a0:4b:7:43:71
Bu, bizi şu kısa eçıklmamaya götürür: ARP istekleri, yayınlamalarla(broadcast) ile yapılır. Böylece sadece bir fiziksel ağ ile sınırlıdır.router'ın MAC adresini öğrenmeye çalışan korunan bir makinanın isteği, filtreleme makinası ile kesilmelidir. Proxy-ARP özelliğini açarak, sorunu çözmemiye yarım eder. Çünkü ARP istekleri sorar ve yayılmak için bir karta gelenleri diğer karta gönderir veya tam tersi.
Bu durumda, yerel ağ ile dışarısı arasındaki tefiği kontrol eden bir makina ile çalışan bir ağınız olmalı.
Netfilter, dorudan paketler üzerinde oynamazı sağlar.Temel ayralamada, paketler 3 kural zinciri tarafından yönetilir:
- INPUT: bir arayüze gelen paketler için,
- FORWARD: bir arayüzden diğerine yönlendirilen bütün paketler için,
- OUTPUT: bir arayüzden çıkan bütün paketler için.
'iptables' komutu ile herhangi bir zincire, filtreleme davranışını etkileyen kurallar ekleyebiliriz, kuralları silebiliriz veya değiştirebiliriz.
Dahası, her zincir kendi varsayılan poklitikasına sahiptir. Yani herhangi bir kurala uyman paket geldiğinde ne yapacağını bilir.
Çok kullanılan seçenekler şunlardır:
- ACCEPT: paket geçebilir
- REJECT: paket reddedilir ve gerekli hata gönderilir (ICMP port ulaşılamaz, TCP Sıfırlama, duruma göre)
- LOG: syslog'a paketle ilgili not yazar,
- DROP: paket reddedilir ve bir hata gönderilmez.
Burada, iptables'ın bütün zincirleri değiştirebilecek seçenekleri bulunmaktadır.Ayrıntılarına daha sonra gireceğiz:
-N: yani bir zincir oluşturur.
-X: boş bir zinciri siler.
-P: bir zincirin varsayılan ploitikasını değiştirir.
-L: bir zincirdeli kuralları listeler.
-F: bir zincirdeki bütün kuralları siler.
-Z: bir zincir içinde geçmiş bütün paket sayaçlarını ve byte'larını sıfırlar.
Bir zinciri değiştimek için aşağıdaki komular kullanılabilir:
-A: bir zincirin sonuna bir kural ekler.
-I: zincirin belirtilen yerine bir kural ekler
-R: belirtilen kuralın zincir içindeki yerini değiştirir.
-D: bir zincirde, tanıtılmış veya numarası verilmiş bir kuralı siler.
Pratik bir örnek görelim: Verilen bir makinadan gelen PING cevaplarını (yani 'echo-reply' tipindeki ICMP paketleri) engelleyelim.
Önce, verilen makinayı ping'leyebildiğimizi deneyelim:
# ping -c 1 172.16.6.74 PING 172.16.6.74 (172.16.6.74): 56 data bytes 64 bytes from 172.16.6.74: icmp_seq=0 ttl=255 time=0.6 ms --- 172.16.6.74 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.6/0.6/0.6 msŞimdi, 172.16.6.74 IP'li makinadan gelen ICMP-Reply ('-p icmp --icmp-type echo reply') paketlerini engelleyecek kuralı INPUT zincirine ekleyelim. Bu paketler, gözardı edileceklerdir ('-j DROP').
# iptables -A INPUT -s 172.16.6.74 -p icmp --icmp-type echo-reply -j DROP
Şimdi, bu makinayı ping'leyelelim:
# ping -c 3 172.16.6.74 PING 172.16.6.74 (172.16.6.74): 56 data bytes --- 172.16.6.74 ping statistics --- 3 packets transmitted, 0 packets received, 100% packet loss
Beklediğimiz gibi, cevaplar geçemiyor. 3 cevabın(252 byte'lık 3 paket) geçemediğini kontrol edebiliriz:
# iptables -L INPUT -v Chain INPUT (policy ACCEPT 604K packets, 482M bytes) pkts bytes target prot opt in out source destination 3 252 DROP icmp -- any any 172.16.6.74 anywhere
İlk duruma geri dönmek için, INPUT zincirindeki ilk kuralı silmeliyiz:
# iptables -D INPUT 1
Şimdi, PING tekrar çelışıyor:
# ping -c 1 172.16.6.74 PING 172.16.6.74 (172.16.6.74): 56 data bytes 64 bytes from 172.16.6.74: icmp_seq=0 ttl=255 time=0.6 ms --- 172.16.6.74 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max = 0.6/0.6/0.6 ms #
İşe yarıyor !
Var olan 3 zincire (bunlar hiçbir zaman silinemez) yenilerini ekleyebilrsiniz ve bunlar üzerinde de bir akış tanımlayabilirsiniz.Bu, örneğin, çeşitli zincirlerde aynı kuralı tekrarlamanınızı engeller.
Şimdi, bir firewall için minimum kuralları ayarlayalım. SSH'e, DNS'e, http ve smtp'ye izin verir ve siğerlerini engeller.
Basitleştirmek için, komutlar bir kabuk scriptinde yazılmıştır. Script, yeni kurallar eklemeden önce var olanları siler. Bu numara, kuralların ikinci kez yazılmasını engeller.
rc.firewall #!/bin/sh # Kuralların silinmesi iptables -F iptables -F INPUT iptables -F OUTPUT iptables -F FORWARD # Zincir, doğrultuya göre oluşturulur. # bad = eth0 (dışarı) # dmz = eth1 (içeri) iptables -X bad-dmz iptables -N bad-dmz iptables -X dmz-bad iptables -N dmz-bad iptables -X icmp-acc iptables -N icmp-acc iptables -X log-and-drop iptables -N log-and-drop # Belirli zincir, paketleri engellemeden önce onları kaydeder iptables -A log-and-drop -j LOG --log-prefix "drop " iptables -A log-and-drop -j DROP # TCP bayrakları kullanılan paketler # ve hiç kullanılmamış paketler engellenir. iptables -A FORWARD -p tcp --tcp-flags ALL ALL -j log-and-drop iptables -A FORWARD -p tcp --tcp-flags ALL NONE -j log-and-drop # Bilinen IP adreslerinden gelen paketler engellenir. iptables -A FORWARD -i eth+ -s 224.0.0.0/4 -j log-and-drop iptables -A FORWARD -i eth+ -s 192.168.0.0/16 -j log-and-drop iptables -A FORWARD -i eth+ -s 172.16.0.0/12 -j log-and-drop iptables -A FORWARD -i eth+ -s 10.0.0.0/8 -j log-and-drop # Kurulmuş bağlantılara ait paketler geçirilir. iptables -A FORWARD -m state --state INVALID -j log-and-drop iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT # Paketin köküna bağlı olarak, karşı gelen zincir gönderlir. iptables -A FORWARD -s $DMZ_ADDR -i $DMZ_IFACE -o $BAD_IFACE -j dmz-bad iptables -A FORWARD -o $DMZ_IFACE -j bad-dmz # kalanlar engellenir. iptables -A FORWARD -j log-and-drop # Geçirilen ICMPler iptables -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type echo-request -j ACCEPT iptables -A icmp-acc -p icmp --icmp-type echo-reply -j ACCEPT iptables -A icmp-acc -j log-and-drop # Dışarısı -> İçerisi # posta, DNS, http(s) ve SSH geçirilir iptables -A bad-dmz -p tcp --dport smtp -j ACCEPT iptables -A bad-dmz -p udp --dport domain -j ACCEPT iptables -A bad-dmz -p tcp --dport domain -j ACCEPT iptables -A bad-dmz -p tcp --dport www -j ACCEPT iptables -A bad-dmz -p tcp --dport https -j ACCEPT iptables -A bad-dmz -p tcp --dport ssh -j ACCEPT iptables -A bad-dmz -p icmp -j icmp-acc iptables -A bad-dmz -j log-and-drop # İçerisi -> Dışarısı # posta, DNS, http(s) ve telnet geçirilir iptables -A dmz-bad -p tcp --dport smtp -j ACCEPT iptables -A dmz-bad -p tcp --sport smtp -j ACCEPT iptables -A dmz-bad -p udp --dport domain -j ACCEPT iptables -A dmz-bad -p tcp --dport domain -j ACCEPT iptables -A dmz-bad -p tcp --dport www -j ACCEPT iptables -A dmz-bad -p tcp --dport https -j ACCEPT iptables -A dmz-bad -p tcp --dport telnet -j ACCEPT iptables -A dmz-bad -p icmp -j icmp-acc iptables -A dmz-bad -j log-and-drop # Makinanın kendisi için zincir iptables -N bad-if iptables -N dmz-if iptables -A INPUT -i $BAD_IFACE -j bad-if iptables -A INPUT -i $DMZ_IFACE -j dmz-if # Dış arayüz # Sadece SSH, bu makinaya geçirilir iptables -A bad-if -p icmp -j icmp-acc iptables -A bad-if -p tcp --dport ssh -j ACCEPT iptables -A bad-if -p tcp --sport ssh -j ACCEPT ipchains -A bad-if -j log-and-drop # İç arayüz iptables -A dmz-if -p icmp -j icmp-acc iptables -A dmz-if -j ACCEPT
Servis kalitesi hakkında birkaç söz. Linux, ToS(Type of service-servis tipi) alanını değiştirebilir ve pakete farklı öncelikler verebilir. Örneğin, aşağıdaki komut, dışarı giden SSH paketlerini, bağlantı cevabını artıracak şekilde değiştirir.
iptables -A OUTPUT -t mangle -p tcp --dport ssh -j TOS --set-tos Minimize-Delay
Aynı şekilde, '--set-tos Maximize-Throughput' ile FTP bağlantılarının, oturumun interaktifliğinin zararına, veri aktarım oranını artırabilirsiniz.
Hepsi bu. Artık etkili bir filtreleme sistemini ayarlamasının temellerini biliyorsunuz. Yine de, güvenlik söz konusunu olduğunda firewall'un her derde deva olmadığını akılınızdan çıkarmayın.Bu sadece bir önlemdir. Firewall kurulumu, güçlü şifreler kullanmanızı, son güvenlik yamalarını yapmanızı, saldırı algılama sistemleri kullanmanızı, vs. engellemez.