Kas
17
2009
0

Temel Linux Komutları

KOMUTLAR

Linux temel olarak kullanıcıyla X Pencere Sistemi adı verilen (startx buyruğuyla başlatıldığını daha önce görmüştük.) bir pencere ortamı olmaksızın, komut satırından iletişim sağlayan bir sistemdir.

root@aku: ~# _
tipik bir komut yorumlayıcı komut (prompt). Komutların biçim ya da yapısı kullanıcının isteğine göre oluşturulabilir. Bizim özel örneğimizde “@” iminden önceki etiket (root ) şu anda geçerli olan kullanıcıyı, aku ise sistemin konak adını belirtiyor. ~ karakteri, yöneticinin hesabı halinde /root olacak olan kullanıcıların anayerleşim (home) dizinini gösteriyor ve son olarak da “#” komutu bu özel hesabın süper kullanıcıya ait olduğunu belli ediyor. Kullanıcı şimdi hareketeden imleçten sonra herhangi bir komutu girebilir.

ls: dizin içeriğini listeler
Örneğin: root@aku:~$ ls
BasiliX/ dead.letter mail/
root@yonca:~# ls -l deneme
Bu örnekte kullanıcının nasıl bir komut (ls), bir komut seçeneği (-l) ve bir parametreden (deneme) oluşan bir deyim oluşturduğunu görebiliriz. Kullanıcı enter tuşuna bastığında, Linux deneme dosyasını listeleyecektir (dosyanın büyüklüğü, oluşturulduğu tarih, ve birkaç başka özelliğini görüntüleyecektir.) Bir kabuk deyiminin genel yapısı, bir karakter boşluktan sonra komut adını izleyen seçeneklerden oluşur.

ls -l -a deneme
Seçenekler aşağıdaki gibi birlikte de kullanılabirler:

ls -la deneme
Son olarak, komut dosya olarak birden fazla dosyaadı belirtilebilir, bunlar da birbirinden boşluk karakteriyle ayrılmalıdır.

ls deneme word yedek
Bu, deneme, word ve yedek dosyalarını ayrıntı vermeden listeler. Dosyaların daha ayrıntılı bir tanımlamasını almak isteyen daha önceki gibi -l seçeneğini kullanabilir.

ls -l deneme word yedek

Linux, sistemin nasıl kullanılacağı hakkında çok geniş ağiletişimli (online) bilgiye sahiptir. Bir komutun adını biliyor ve nasıl kullanıldığını öğrenmek istiyorsanız :
man [komut]
Bu, komutunun elyordam sayfasını oluşturacaktır. Hemen hemen tüm sistem komutları için elyordam sayfaları sistemde var durumdadır. man komutunun kendisinin seçenekleri hakkında daha çok bilgi almak isterseniz, yalnızca man man yazmanız yeterli. Bir UNIX buyruğunun seçeneklerini akılda tutmak asla gerekmez. Çünkü ağiletişimli elyordam sayfaları her zaman belleğimizi tazelemek için hızlı ve kolay bir yol sağlar. Öte yandan öğrenmek istediğiniz şeyin konusunu ya da bir açkı sözcüğünü biliyorsanız şunu deneyin:

apropos [subject]
Bu, konuyla ilişkili tüm komutların bir listesini verecektir. root@yonca:~$ apropos zip
atalkd (8) - AppleTalk RTMP, NBP, ZIP, and AEP manager
bzip2, bunzip2 (1) - a block-sorting file compressor, v1.0 bzcat - decompresses files to stdout bzip2recover - recovers data from damaged bzip2 files
explodepkg (8) - Extract the contents of a tar+GNUzip package (such as a Slackware software package) in the current directory.
funzip (1) - filter for extracting from a ZIP archive in a pipe
gzip, gunzip, zcat (1) - compress or expand files
jaztool, ziptool (1) - Tool for Iomega JAZ and ZIP drives
mzip (1) - change protection mode and eject disk on Zip/Jaz drive ‘” t TQ $1 ..
unzip (1) - list, test and extract compressed files in a ZIP archive
unzipsfx (1) - self-extracting stub for prepending to ZIP archives
zforce (1) - force a ‘.gz’ extension on all gzip files
zip, zipcloak, zipnote, zipsplit (1) - package and compress (archive) files
zipgrep (1) - search files in a ZIP archive for lines matching a pattern
zipinfo (1) - list detailed information about a ZIP archive

ls –help:
Bazı komutlar –help parametresiyle birlikte verildiğinde mümkün olan tüm seçeneklerin kısa bir tanımını verirler.
Bir komutun çıktısı bir ekrandan fazlasını dolduruyorsa kaygılanmak için bir neden yoktur, çıktıyı okumak için klavye üzerindeki PageUp ve PageDown tuşlarını kullanmak yeterlidir. Çoğu Linux sürümü çeşitli programlar ve yararları hakkında birçok kaynakbilgi (document) içerir. Bu kaynakbilgiler /usr/doc dizinindedir. Örneğin tetex ile ilgili bilgi için yalnızca bu dizine girip more tetex yazmanız yeterlidir. /usr/doc dizinindeki dosyaların çoğu ASCII dosyalarıdır. Daha da çoğu var. info sayfaları komutların tanımlarını ve uygulamalarını içerir. emacs editöründen [Control+h][Control+i] tuşlarıyla kolayca erişilebilen info sayfalarında da açıklamalar bulabiliriz.

$ ls -l
drwxr-xr-x 3 fenix fenix 1024 Jun 15 1997 Calendar
drwx—— 5 fenix fenix 1024 Nov 6 19:35 Desktop
drwx—— 2 fenix fenix 1024 May 16 1997 Mail
drwxrwxr-x 2 fenix fenix 1024 Mar 10 00:28 X11
lrwxrwxrwx 1 root root 11 Mar 13 20:53 ada -> private/ada
drwxrwxr-x 2 fenix fenix 1024 Mar 10 00:28 bin

cp: Dosya kopyalama
Bu komut dosyayı başka bir dizinde bulmak veya yeni başka bir ad vermek için dosya kopyalamaya izin verir.
root@aku:/home/web# cp index.html /home/www/
Eğer, yedek varolan bir dizin değilse, komut, dosyayı başka bir ad altında kopyasının yaratılmasının istendiği yorumunu yapacaktır. Buradaki yedek dizini home altındaki son klasörünün içine kopyalanacaktır.

mv: Dosya taşıma
mv “MoVe” demektir ve taşı anlamına gelir. Bu komut ile dosyaları yeniden adlandırabilir veya diğer bir dizine taşıyabilirsiniz.
root@aku:/home/web# mv index.html /home/www/
Eğer yedek varolan bir dizin olmasaydı, dosyayı yeniden adlandırmak istediğiniz yorumu yapılacaktı. Yedek dizini home altına taşınacaktır.

cd: dizinin içine girmek
Argümansız cd buyruçu ilk dizine geçişi sağlar. Eğer yetkin kullanıcı (superuser) iseniz bu komut size /root/ dizinini verecektir; eğer hasan iseniz /home/hasan’a gideceksiniz. Burada görebildiğiniz şey dizinlerin sağ tarafa eğimli çubuklara sahip olduğu gerçeğidir Son olarak, /home ~ karakteri ile yer değiştirebilir. Bu nedenle, cd ~yedek bizi /home/yedek ‘ğe götürür. root@sezer:/home/webadmin# cd linuxweb
root@sezer:/home/webadmin/linuxweb#

mkdir: dizin oluşturmak
root@sezer:/home/webadmin# mkdir linuxweb
root@sezer:/home/webadmin/linuxweb#
mkdir [dizinadı] biçiminde çok basit bir yapıdır ve bu ad altında bir dizin yaratır.

rmdir: boş bir dizini silmek
root@sezer:/home/webadmin# rmdir linuxweb

İçinde dosyalar bulunmayan bir dizini yok etmek istiyorsanız, rmdir [dosyaadı] komutuyla yapılır. Eğer dosyalara sahip dizinleri yok etmek istiyorsanız (ya da diğer dizinler) rm komutuna bakın.

rm: dosyayı silmek
rm [dosyaadı] ile her tür dosya silinir.
Diğer ek komutları: -i Dosyayı silmeden önce doğrulama gerektirir.
-r Bir dizini ve onun tüm içeriğini siler.
-rf Bir dizini ve onun içeriğini herhangi bir doğrulama gerektirmeksizin siler.

ln: diğer dosyalara link vermek
Linux dosyaların ayrı adlara sahip olduğunu veya onlara ayrı dizinlerden erişebileceğimizi varsayar. Bu, bağlantılar ile yapılır. İki türü vardır: ” katı: bağlantıda dosya içeriğinin tamamını kopyalar, kaynak dosya veya tersine bağlantı değiştiğinde karşılığı da değişir. ” simgesel: Kopyalamaz, kaynak dosyaymış gibi çalışır. Bu yolda dosya içeriğinin kopyası yoktur, böylece tekerde boş yer kalır. Bugünlerde neredeyse yalnızca bu tür bağlantılar kurulmaktadır. Bu yolla dizinler sadece simgesel bağlantılara izin verir. Katı bağlantılar ln ile yapılır. Ve simgesel bağlantılar ln -s [kaynakdosyalar] [erekdosya] ile yapılır.

cat:dosyanın içini gösterir
cat [dosyaadı]

more: sayfalamalı dosya içeriği gösterimi, eğer göreceğimiz dosya çok uzunsa (ekranda görmek istediğimiz birçok satırı varsa), en üstteki ilk satırları yitireceğiz. Çözüm ise ekran buffer kullanmaktır. Bu buffer altında, Mays+Repag ile yer değişimi sağlanabilir. Fakat bu buffer sınırlı büyüklüktedir ve çoğu kez yardımcı olmaz. more buyruğu dosyaları sayfalayarak görmemizi sağlar.
more [dosya-adı]
Bu etkileşimli bir programdır. Daha ilginç olan “keys” (etkileşimli komutlar) aşağıdadır: Açkı Fonksiyon (Key Function)
spacebar Bir sayfa ileri
b bir sayfa geriye al
return bir satır ilerle

/[string] katar’ın dosya içindeki bir sonraki yerini bul
?[string] katar’ın dosya içindeki son görüldüğü yeri bul
q bırak çık

chmod:dosya izin haklarının değiştirilmesi
Düzenli kullanıcılar (root her şeyi yapabilir) yalnızca sahip oldukları dosyaların erişim izinlerini değiştirebilirler. Bu, boşlukla ayrılmış 2 parametre türünün birleşimidir.
chmod [kim][+/-] [yenihaklar] [dosya]
kim’de aşağıdakilere gönderim yapabiliriz: Kim Betimlemesi u dosyaya sahip olan kullanıcı
g dosyaya sahip olan grup
o geriye kalan kullanıcılar
a herhangi bir kullanıcı (sahip, grup, diğerleri)
+ ile izin hakları ekler - ile izin haklarını çıkartırız.
Yeni izinlerde hangi izinlerin eklendiğini veya kaldırıldığını gösteriyoruz. Bunlar ls yardımı ile uzun listenin ilk alanındaki harfler ile betimlenirler (Bunun anlamı, r:oku, w:yaz, x:çalıştır veya konuk ol, s:SetUID şeklindedir).

chmod u+rw my
Bununla sahip (bu genellikle sizsiniz), my dosyası üzerinde okuma ve yazma iznine sahip olur.

chmod a-x directory
Ve bununla tüm kullanıcıların (siz ve sahip dahil) directory dizinine konuk olma izinlerini kaldırıyoruz.
chmod diğer ve daha gelişmiş niteliklere sahiptir, bunları burada görmeyeceğiz, fakat man chmod komutunu kullanarak elyordam sayfaları kullanabilirsiniz:.

man chmod
* : Herhangi bir katara (0 veya daha çok sayıda) gönderme yapar

rm *:Bütün dosyaları sil.

rm a* :a ile başlayan tüm dosyaları sil.

rm bet*as :bet ile başlayıp as ile biten tüm dosyaları sil.

? :herhangi karakter (yalnızca bir)

cat c?t : c ile başlayan ve sonu t ile biten tüm dosyaların içeriklerini görüntüler.

[group]: köşeli parantezler arasındaki karakter grubu

more [tp]erez:Eğer varsa, sayfa düzeninde terez ve perez dosyalarını gösterir.
cp c[AEIOU]endo directory c ile başlayan, [ ve ] arasında verilen büyük harflerle süren ve endo ile sona eren dosyaları directory adlı dizine kopyalar. Aralıkları yaratmak için “-” kullanabiliriz:

mv *[a-z] trash :Büyük harf ile bitmeyen tüm dosyaları trash adlı dizine taşır. Aralıkların dışı da taban alınabilir:

ls [!a-zA-Z]* :İlk karakteri büyük veya küçük harf olmayan dosyaları listeler.

nl :Bir dosyayı satırlarını numaralamak ve mantıksal sayfalar halinde göstermek için kullanılır.
nl komutu nl [seçenekler][dosya] şeklinde kullanılır. $nl x _file
1 aku
2 bim

wc:Dosyada bulunan satır,kelime veya karakter sayısını gösterir.
$wc index.html
59 95 1188 index.html

pwd: Kullanıcı dizinler üzerinde hareket ederken zaman zaman hangi dizin üzerinde çalıştığını öğrenmek için bu komut kullanılır.
$pwd
/usr/ser

chown:Bir dosyanın veya dizinin paremetresinde tanımlı bulanan dosya veya dizinin sahibi parametrelerini değiştirir. Dosya veya dizin sahibi parametresi /etc/passwd dosyasında, kullanıcı kimliği(user ID) veya bağlantıı ismi (login name) olarak kayıtlı bulunmak zorundadır.Dosya ve dizin parametreside /etc/group dosyasında, group kimliği (group ID)veya gurup ismi (group name ) olarak kayıtlı olmak zorundadır.
chown [-f][-h][-R] sahibi[:grubu]{dosya I dizin}

ps:Aktif işlemler hakkında çeşitli bilgileri görüntüler root@yonca:~/mail$ ps
PID TTY TIME CMD
15085 ttyp1 00:00:00 bash
15232 ttyp1 00:00:00 ps
You have new mail in /var/mail/root

kill:Çalışan süreci durdurmak için singal gönderir.Bir root kullanıcı herhangi bir süreci kil komuduyla öldürebilir.Eğer root kullanıcısı değilseniz sadece kendinize ait işlemleri öldürebilirsiniz.
kill [-s{sinyal ismi Isinyalnumarası}]süreç tanıtım numarası (PID)

lprm:(line printer remove)Printer’da döküm için bekleyen işlemleri sıran çıkarır.
lprm[-P Printer][görev sırası][Kullanıcı adı..][-]

echo:İfadeleri görüntülmek için bu komut kullanılır,kabuk programlarında kullanılır.
Önce a değişkenini “hasan”‘a aktaralım sonra da echo komutula hasanı görüntüleyebiliriz.
$ a=hasan
$echo $a
hasan
$_

date:Sistemin tarihini ve zamanını gösterir.date komutu “date+%X”şeklinde kullanılır.
$date
Mon Jan 11 13:29:48 Mest 2002

tail:Dosyanın son bölümünü görüntüler.
$tail yedek
yedek dosyasının son 10 satırını görüntüler.

uname:İşletim sistemi hakkında bilgi verir
-m Makinanın donanımının adını verir.
-n Nodename i yazar. Nodename sistemin network iletişimi için kullanılır..
-r Print the operating system release
-s Sistem ismini yazar
-v İşletim sisteminin versiyonuu yazar
-a yukarıdaki bilgilerin tamamını yazar

ping :(packet internet groper)Bir network bilgisayara ICMP(Internet Control Message Protocol)echo paketi gönderir ve geri dönen paketleri bildirir.

Hostname:Paketlerin gönderildiği bilgisayarın ismini belirtir.

mount :Üzerinde bir dosya sistemi olan bir disk birimine veya parçasına okuma veya yazma amacıyla ulaşabilmek için bu birim veya parçayı / dosya yapısında bir alt dizine mount edilmiş olması gerekir./dizini bilgisayarın açılması sırasında otomatik olarak mount edilmektedir. Eğer bu kök dizini bilgisayarın açılması aşamasında mount edilmezse , o bilgisayar zaten açılmaz.Diğer disk ve disk parçalrı otomatik olarak mount edilmesi için gerekli işlemler ise sistem yöneticisi root tarafından yapılır. Otomatik olarak mount edilmesi istenen diskler ve mount edilecekleri dizinler /etc/filesystems dosyasında tanımlanır.
aku@yonca:~$ mount

/dev/sda1 on / type ext2 (rw)

/dev/sda3 on /home type xfs (rw)

none on /proc type proc (rw)

mailx:Mesajların elektronik olarak alınması ve gönderilmesi için ortam sağlayan bir yazılımdır. “mailx”komutu mesaj okunurken saklama silme ve mesajla yanıtlama olanağı sağlar.
mailx [seçenekler] [isim]
utebay@yonca:~$ mailx
Mail version 8.1 6/6/93. Type ? for help.
“/var/mail/utebay”: 26 messages 25 unread
1 MAILER-DAEMON@yonca. Sat Jun 29 09:37 13/546 “DON’T DELETE THIS MES”
2 ukarabudak@cizgi.com Fri Jun 28 17:44 67/2841 “[Linux] Re: ntfs moun”

grep: Karekterlerden oluşan belirli kalpıları bir veya daha fazla dosya içinde aramınızı sağlayan komuttur.
grep[seçenekler]ifade [dosya...] $ cat deneme.c
include “stdio.h”
main ()
{
printf (”merhaba”);
return(0)

du Komutu (Diskin Durumu):Sistem yöneticisi zaman zaman disklerin nasıl kullanıldığını öğrenmek için bu komut kullanılır.Aşırı büyüyen dosyalar ve dizinleri belirlemesi,sağlar.
utebay@yonca: ~$ du
8 ./BasiliX
12 ./mail
0 ./.ssh

cut:Bir dosya içerisindeki satırların içerdiğialanların keserek belirli bir yere kopyalamak için kullanılır.
cut [seçenekler][dosya]

chgrp:Bir dosyanın yada klasörün grup sahipliğini değiştirmeye yarar.
chgrp[-f][-h][-R]Grup{Dosya….|Klasör….}

who komutu:Sistemde o anda kimlerin çalıştığını saptayan komuttur.
who [seçenekler][isimler]

umount: Mount edilmiş bir kütük sistemini, bilgiisayarın /kütük sisteminden ayırmak için kullanılır.Bu işlem genellikle CD ler için kullanılır.
{umount|unmount}[-f][-a]|[all|allr|Device |Directory|File|FileSystem|-n Nome|-t Type]

Paste: Aynı bir dosyanın veya başka dosyaların bellirli kısımlarını bir araya getirmek için kullanılır. Paste komutuyla ister yatay, isterse düşey olarak birleştirme işlemi yapılabilir.
paste[seçenekler][dosya..]

head: Dosyalrın ilk kısmını listeler.Verilen dosyanın belirtilen kadar satırını, belirtilmemişse ilk 10 satırını listeler. Eğer dosya verilmemişse veya’-'dosya adıyla karsılaşılasırsa standart girdiler okunur.Eğer birden fazla dosya verilmişse her dosya listelemesinde önce ==> ve <== içine koyulmuş dosyaların adlarından oluşan başlıklar listeler.

FTP: İki Bilgisayar arasında dosya transferini sağlar.Uzaktaki bilgisayara dosyalar koyabilirsiniz, yada uzaktaki bilgisayardan yerel bilgisayarlardan yerel bilgisayarlara dosyalar indirebilirsiniz.

diff: Dosyalar arasındaki farklılıkları ortaya koyarak,gerekiyorsa değişiklik kullanılır.
diff [seçenekler] dosya-1 dosya-2

Yaziyi gonderen CK in: Linux | Etiketler: , , , ,
Kas
17
2009
0

cPanel lisans hatası

Eğer cPanel’iniz lisans hatası veriyor ve lisansın halen aktif olduğundan emin iseniz :

/usr/local/cpanel/cpkeyclt komutunu verdikten sonra “Done…” yazısını alıyorsanız, probleminiz artık giderilmiştir.

Licence Expired yazısı ise lisansın deaktif durumda olduğunu göstermektedir.

Kas
17
2009
0

cPanel Kurulumu

Sunucunuza cPanel kurulumu için yapmanız gereken:

mkdir /home/cpins
cd /home/cpins
wget http://layer1.cpanel.net/latest
sh latest

Komut zincirini sshtan yapıştırıp, ardından bağlantı hızınıza ve donanım performansınıza göre 30 dakika ila 2 saat arası beklemektir.

Önemli not: Sunucunuzun stabil çalışması açısından lütfen serverda sadece tek panel kurulumu yapınız. Başka panellerle birlikte ya da ardından kurulum yapılması problem yaratabilir.

Kas
17
2009
0

Iptables kullanımı

Bu arada, FrontSITE’da çalıştığım dönemde eğitim belgelerinde kullanılmak üzere hazırlanan örnek ağ şemalarından ve firewall script’lerinden birini kullanmama izin vererek bu belgeyi hazırlama süremi kısalttığı için Murat Koç’a teşekkürler.

İçindekiler:

•Netfilter nedir?
•Peki, IPTables nedir?
•Bu ikisi sürekli birlikte anılıyor, farkları nedir?
•Temel kavramlar: IP paketinin yapısı
•Nelerden bahsedeceğiz?
•Netfilter nasıl çalışıyor?
•Haydi NAT yapalım
•Bu parametreler ne anlama geliyor? Nasıl kullanılıyor?
•Filtreleyelim
•IP Forwarding nedir, nasıl çalıştırılır?
•Öntanımlı zincir kuralları
•Öneriler
•Kapsamlı bir firewall yapılandırması örneği
Netfilter nedir?
Netfilter, en basit ifade biçimi ile 2.3 ve daha yeni Linux çekirdeği sürümleri içerisinde bulunan yetenekli ve yüksek performanslı NAT, filtering ve packet mangling sistemi olarak biliniyor.

Peki, IPTables nedir?
iptables, çekirdek içerisinde yer alan Netfilter sistemini userspace içerisinden denetlemek amacıyla kullandığımız araç ve yazılımın adı.

Bu ikisi sürekli birlikte anılıyor, farkları nedir?
Netfilter, Linux çekirdeği içerisinde sürekli olarak çalışır ve Linux sistem çağrıları (syscall) yoluyla yönetilir. IPTables ise, çekirdek içerisinde çalışan netfilter yapısını yönetmek amacıyla kullandığımız araç. Her ikisi de Netfilter projesi kapsamında, aynı kişiler ve gruplar tarafından geliştiriliyor. Buna karşın netfilter kodu resmi Linux çekirdeği ile birlikte gelirken, iptables adındaki araç ayrı bir yazılım ve kullanılan dağıtım tarafından sağlanıyor.

Temel kavramlar: IP paketinin yapısı
IP paketlerini mektup zarflarına kadar basitleştirecek olursak, temel anlamda bir IP paketi:

Şekil 1: Basit bir IP paketi

bu kadar basit algılanabilir (tabii gerçekte böyle değil, IP paketleri çok daha fazla bilgi içeriyor fakat şimdilik bu bölümlerle ilgilenmeyeceğiz). Bir IP paketini şimdilik yalnızca nereden geldiğini, nereye gitmek üzere gönderildiğini ve veriyi içeren bir mantıksal bir birim olarak düşünelim.

Nelerden bahsedeceğiz?
Bu belge içerisinde, yalnızca Netfilter’ın çok sık kullanılan NAT ve Filtering özelliklerinden bahsedeceğim; packet mangling ve bandwidth shaping gibi daha ileri düzey konulara şimdilik girmeyeceğim.

Ayrıca kullanıcı tanımlı kural zincirlerinin yönetimi, REJECT ve LOG target konularından ve paketlerin bağlantı durumlarına göre incelenmeleri gibi konulardan da detaylı olarak bahsetmeyeceğim.

Bu konulardan bahsetmeme nedenim, belgeyi olabildiğince basit ve giriş düzeyinde tutmak. Bahsetmediğim konular gelişkin bir güvenlik duvarı yapılandırması için değerli ve gerekli konular. Bu konularda vakit bulduğumda ayrıca geniş bir belge hazırlayacağım.

Netfilter nasıl çalışıyor?

Şekil 2: Netfilter, tablolar ve zincirler

Yalnızca NAT ve IP Filtering konularından bahsedecek olmanın verdiği rahatlıkla yukarıdaki şekli çizdim.

Netfilter temel anlamda iki farklı türden ve mantıksal olarak birbirine benzerlik gösteren işlemler gerçekleştiriyor. Bunlar:

•NAT (Network Address Translation): IP paketlerinin kaynak veya hedef adreslerinin (IP adresi ve port numarası gibi bilgilerin) routing (ip paketinin bir arayüzden bir diğerine aktarılması işlemi) öncesinde veya sonrasında, çeşitli biçimlerde değiştirilmesi işlemine verilen genel ad. NAT işlemi, routing’den önce (PREROUTING) yapılırsa routing sürecinin davranışını etkiler. Routing’den sonra (POSTROUTING) yapılırsa, tahmin edebileceğiniz gibi, routing sürecinin davranışı bu durumdan etkilenmez.
•Filtering: IP paketlerinin kaynak ve hedef adreslerinin tanımlanan çeşitli kriterlere göre geçişine/kabulüne izin verilmesi veya verilmemesi ile ilgili tüm işlemler filtreleme kapsamda anılır.
Haydi NAT yapalım
Bence ideal bir dünyada NAT olmamalıydı. Eğer herkese yetecek kadar çok IP adresimiz olsaydı ve her IP adresi için ek bedel ödemek gibi anlamsız koşullar olmasaydı, NAT gibi bir işleme gerek kalmazdı :) Her neyse, NAT var ve bunu kullanıyoruz. Bununla yaşamamız gerek.

NAT gibi süreçler, bir tek IP adresine sahip olduğunuz fakat bu IP adresini çeşitli hizmetler için ortak kullanmanız gerektiği durumlarda, belirli sınırlar çerçevesinde faydalı oluyor. En popüler senaryolardan bir tanesini açıklamak gerekirse, dial-up bir modem ile edindiğiniz bir IP adresiniz var ve aynı zamanda bu bilgisayara bağlı bir ethernet üzerinden yerel ağınızdaki diğer bilgisayarlarla iletişim kurabiliyorsunuz. Yerel ağınıza bakan ağ arayüzünün 192.168.1.1 olduğunu, modem bağlantınızdan edindiğiniz IP adresinin de 123.123.123.123 olduğunu varsayalım. IP dolaştırma (routing) etkin olsun (nasıl etkinleştirileceğinden bahsedeceğim).

Yalnızca IP dolaştırma yapılanmasının etkin olduğu durumda yerel ağdan (örneğin IP adresi 192.168.1.5 olan “Ahmet”‘in bilgisayarından) gelen bir IP paketi; kaynak adresinde 192.168.1.5 bilgisi yer alacak biçimde Internet erişimimiz bulunan IP adresi üzerinden, değiştirilmeksizin iletilecek. Eğer bağlı bulunduğumuz ISP, IP dolaştırma sırasında özel bazı adresleri de yönlendirecek kadar dikkatsiz ise Ahmet’in Internet üzerinde bağlanmaya çalıştığı sunucuya kaynak adresi 192.168.1.5 olan bir IP paketi ulaşacak :) Ve karşıdaki sunucu da bu bağlantı isteğine vereceği tüm yanıtları 192.168.1.5 adresine göndermeye çalışacak, fakat başarısız olacak çünkü bildiğiniz gibi 192.168.0.0/24 gibi ayrılmış IP blokları Internet üzerinde kullanılmaz.

Bu durumda, Ahmet’in bağlandığı sunucunun yanıtları Ahmet’e gönderebilmesini sağlamak üzere, Ahmet’den gelen ve Internet yönüne doğru gidecek olan paketlerin hedef adreslerini, Internet’e bağlı bulunan sistemimizin Internet üzerindeki gerçek IP adresi ile değiştirmeliyiz ki Ahmet’in isteğine yanıt olarak gönderilecek IP paketleri Internet’e bağlı bulunan sistemimize kadar ulaşabilsin. Ayrıca, bu işlemi yapan sistemimiz hangi IP paketlerini nereden geldikleri ve nereye gittikleri gibi asıl bilgiler ile birlikte nasıl değiştirdiğini hatırlamalı ki yanıt niteliğinde gelen paketleri yerel ağımızdaki asıl hedeflerine (yani örneğimizde Ahmet’in bilgisayarına) tekrar, Internet üzerinden geliyormuş gibi gönderebilsin (stateful NAT). Bu işlem, basit bir NAT uygulamasıdır ve iptables kullanılarak tek satırlık ve birçok kişinin ne olup bittiğini anlamaksızın ezberlediği bir komut ile kolaylıkla gerçekleştirilebilir.

İlk bakışta görülebileceği gibi, NAT iki durumda yani iki farklı biçimde yapılabilir:

•SNAT (Source NAT): IP paketlerinin kaynak (source) adreslerinin değiştirilmesidir. Yukarıdaki örnek basit bir SNAT uygulamasıydı. SNAT daima POSTROUTING (yani routing işleminden sonra) yapılır.
•DNAT (Destination NAT): IP paketlerinin hedef (destination) adreslerinin değiştirilmesidir. DNAT daima PREROUTING (yani routing işleminden önce) yapılır.
Netfilter, daima stateful NAT yapar. Yani NAT yapılan her paketi ve TCP için paketlerin ilgili olduğu bağlantı oturumlarının durumlarını hatırlar.

Ayrıca, MASQUERADE adıyla bilinen özel bir SNAT türü var. Masquerading, sabit bir IP adresine veya sabit/güvenilir bir bağlantıya sahip olmayan sistemlerde kullanılması için tasarlanmış bir NAT türü. SNAT yerine MASQUERADE kullanıldığında, paketin hedef adresine, paketin sistemden ayrılacağı ağ arayüzünün IP adresi otomatik olarak yazılır (SNAT kullanıldığında paketin kaynak adresine yazılacak IP adresini belirtmek durumundasınız). Tek dezavantajı, SNAT’a kıyasla çok küçük performans kayıplarına neden olması. Ayrıca doğru kullanılmadığında ve küçük birkaç husus gözden kaçırıldığında MASQUERADE ile sisteminize küçük güvenlik açıkları oluşturmanız işten bile değil.

Şimdi örneğimizi tamamlayalım ve neler olup bittiğini açıklayalım:

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o ppp0 -j MASQUERADEiptables aracını kullanarak çekirdek içerisindeki Netfilter modüllerinin yapılandırmasına bir kural ekleyerek değiştirmiş olduk ve belirttiğimiz kural, 192.168.1.0/24 ağından gelen ve ppp0 arayüzü yönüne gidecek olan (routing’den sonra NAT yaptığımız için bu bilgiye sahibiz) tüm IP paketlerinin kaynak adreslerine gönderilmeden önce otomatik olarak ppp0 arayüzünün IP adresinin yazılmasını sağladı. Bu sayede hedef sunucudan dönen yanıt paketleri bize ulaşacak ve Netfilter yanıt niteliğindeki paketleri tersi yönde otomatik olarak DNAT yapacak ve routing işleminden önce bu paketlerin hedef adreslerini değiştirerek yerel ağımızdaki kullanıcılara ulaşmasını sağlayacak (bu işlem için ayrıca bir kural eklememize gerek yok).

Aynı senaryoya bir özellik daha ekleyelim; Internet’e modem ile bağlı olan sistemimiz, Internet yönünden kendisine ulaşan HTTP (TCP port 80) isteklerini Ahmet’in 192.168.1.5 adresindeki bilgisayarına iletsin. Kuralımız:

iptables -t nat -A PREROUTING -i ppp0 -p tcp –dport http -j DNAT –to 192.168.1.5Bu parametreler ne anlama geliyor? Nasıl kullanılıyor?
Netfilter, IP paketleri üzerinde yapılacak çeşitli işlem türlerini ve aşamalarını tablolar içerisinde gruplar. Bu belgede yalnızca nat ve filter tablolarından bahsedeceğiz. Bu tablolar içerisinde kural zincirleri bulunur (kural zincirleri sistem tarafından veya kullanıcılar tarafından gereksinimlere göre tanımlanır). Ayrıca her tablo, öntanımlı adı değiştirilemeyen ve silinemeyen belirli sayıda kural zinciri içerir, bunlar:

•nat tablosu:
◦PREROUTING (DNAT için kullanılır).
◦POSTROUTING (SNAT için kullanılır).
◦OUTPUT (sistemin kendisi tarafından üretilen paketlere nat uygulanması için kullanılır).
•filter tablosu (”iptables -t” ile ayrıca belirtilmezse öntanımlı tablodur)
◦INPUT (sistemin kendisine ulaşması için gönderilen paketlerin filtrelenmesi için kullanılır)
◦OUTPUT (sistemin kendisi tarafından üretilen paketlerin filtrelenmesi için kullanılır)
◦FORWARD (routing işlemi sırasında paketlerin filtrelenmesi için kullanılır)
Sık kullanılan parametrelerden bazıları:

Ad Kullanım biçimi Açıklama Örnek
Tablo seçimi -t iptables komutunun devamındaki parametrelerin hangi tablo üzerinde gerçekleştirileceğini belirtmek amacıyla kullanılır. -t nat
-t filter
Kuralları listele -L [] Bir tablodaki istenen veya tüm zincirlerde yer alan kuralları listeler. -L
-L POSTROUTING
Kuralları temizle -F [] Bir tablodaki istenen veya tüm zincirlerde yer alan kuralları temizler. -F
-F POSTROUTING
Öntanımlı davranış belirle -P Bir tablodaki belirtilen zincirin öntanımlı davranış kuralını belirler. Zincirdeki diğer kurallarden herhangi biri tarafından işlenmeyen bir paket, öntanımlı davranış kuralında belirtilen işleme tabi tutulur. -P INPUT DROP
-P INPUT LOG
Kural ekle -A Bir tablodaki belirtilen zincir içerisine belirtilen parametrelere göre bir kural ekler. -A POSTROUTING
-A FORWARD
Kural sil -D Bir tablodaki belirtilen zincirde yer alan ve belirtilen parametrelerle bire bir aynı olan kuralı siler. -D POSTROUTING
-D FORWARD
Kullanıcı tanımlı zincir sil -X [] Bir tablodaki belirtilen veya tüm kullanıcı tanımlı zincirleri siler. -X benim_zincirim
-X

Paket seçimi için kullanılan parametreler:

Ad Kullanım biçimi Açıklama Örnek
Kaynak adresi -s [!] İncelenen paketin kaynak adresi, belirtilen adres ile örtüşüyor ise paket üzerinde belirtilen işlem gerçekleştirilir. -s 192.168.1.5
-s 192.168.1.0/24
Hedef adresi -d [!] İncelenen paketin hedef adresi, belirtilen adres ile örtüşüyor ise paket üzerinde belirtilen işlem gerçekleştirilir. -d 192.168.1.10
-d 192.168.2.0/24
Protokol -p [!] < tcp | udp | icmp | all > İncelenen paket belirtilen taşıyıcı protokol ile örtüşüyor ise paket üzerinde belirtilen işlem gerçekleştirilir. Öntanımlı değeri (belirtilmediğinde): “all” -p tcp
-p udp
-p icmp
-p all
Hedef port –dport [!] İncelenen paketin hedef port adresi belirtilen port ile örtüşüyor ise paket üzerinde belirtilen işlem gerçekleştirilir. –dport 80
–dport ftp
Kaynak port –sport [!] İncelenen paketin kaynak port adresi belirtilen port ile örtüşüyor ise paket üzerinde belirtilen işlem gerçekleştirilir. –sport ftp-data
–sport 53
Geliş arayüzü -i [!] İncelenen paketin geldiği ağ arayüzü belirtilen ağ arayüzü ile örtüşüyorsa paket üzerinde belirtilen işlem gerçekleştirilir. Bu bilgiye yalnızca routing işleminden önce veya routing işlemi sırasında yapılan denetimlerde erişilebilir. -i eth1
-i ppp0
Gidiş arayüzü -o [!] İncelenen paketin gitmek üzere olduğu ağ arayüzü belirtilen ağ arayüzü ile örtüşüyorsa paket üzerinde belirtilen işlem gerçekleştirilir. Bu bilgiye yalnızca routing işleminden sonra erişilebilir. -o ppp0
-o eth1

Ayrıca bu parametrelerin tümünde, belirtilecek değerden önce kullanılabilecek ünlem işareti (!), olumsuzluk belirtmek anlamında kullanılır. Örneğin, –dport ! 80 biçimindeki bir tanımın bulunduğu kural, hedef port adresi 80 olmayan tüm paketlere uygulanacaktır.

Çeşitli ifadelere göre seçilen paketlere nasıl bir işlem uygulanacağı -j parametresi ile belirtilir ve bahsi geçen kuralın bulunduğu tabloya göre değişiklik gösterir:

•NAT tablosu için: Ad Kullanım biçimi Açıklama Örnek
SNAT -j SNAT –to Sistemden ayrılmak üzere olan paketin kaynak adresini (ve belirtilmişse kaynak port numarasını) belirtilen adres (ve belirtilmişse port numarası) bilgisi ile değiştirir. Bu işlem yalnızca routing işleminden sonra gerçekleştirilebilir. -j SNAT –to 212.156.4.1
-j SNAT –to 212.156.4.20:53
-j SNAT –to 192.168.1.35:http
DNAT -j DNAT –to Sisteme henüz gelmiş bir paketin hedef adresini (ve belirtilmişse hedef port numarasını) belirtilen adres (ve belirtilmişse port numarası) bilgisi ile değiştirir. Bu işlem yalnızca routing işleminden önce gerçekleştirilebilir. -j DNAT –to 192.168.1.5
-j DNAT –to 212.156.123.123:10000
MASQUERADE -j MASQUERADE Sistemden ayrılmak üzere olan paketin kaynak adresini, paketin sistemden ayrılacağı ağ arayüzünün adresi ile değiştirir. Bu işlem yalnızca routing işleminden sonra gerçekleştirilebilir. -j MASQUERADE
REDIRECT -j REDIRECT –to Sisteme henüz gelmiş bir paketin, iptables kurallarının çalıştığı sistem üzerindeki belirtilen port adresine yönlendirilmesini sağlar. -j REDIRECT –to 3128

•Filter tablosu için: Ad Kullanım biçimi Açıklama Örnek
ACCEPT -j ACCEPT Belirtilen paket seçimi parametrelerine uyan paketin geçişine izin verilir. -j ACCEPT
DROP -j DROP Belirtilen paket seçimi parametrelerine uyan paket gözardı edilir, hiç alınmamış gibi davranılır. -j DROP
REJECT -j REJECT Belirtilen paket seçimi parametrelerine uyan paket uygun bir ICMP hata paketi ile yanıtlanarak, reddedilir. Bu konuda daha detaylı bilgi için man iptables komutu verin. -j REJECT
LOG -j LOG Belirtilen paket seçimi parametrelerine uyan paket sistem kayıtları içerisine kaydedilir. Bu konuda daha detaylı bilgi için man iptables komutu verin. -j LOG

Filtreleyelim!
Kısa bir senaryo, sistemimize SSH (tcp port 22) ile gelebilecek tüm bağlantıları kapatmak istiyoruz:

iptables -t filter -A INPUT -p tcp –dport ssh -j DROPkomutunu verdiğimizde, sistemimize herhangi bir ağ üzerinden SSH ile erişmek mümkün olmayacak, çünkü Netfilter paketlerin işletim sisteminin IP yığıtı içerisinde değerlendirmeye alınmasını engelleyecek ve gözardı edecektir.

Yeri gelmişken, daha önce bahsettiğim bir ipucunu kullanmak istiyorum. Son örneğimizde -t filter ile filter tablosunu ayrıca belirtmiştik, fakat -t parametresi belirtilmediğinde öntanımlı olarak zaten filter tablosu kullanılır, dolayısıyla bu ifade çok da gerekli değil.

Örneğimizi biraz geliştirelim; 192.168.1.5 dışında hiçbir yerden ssh kabul etmeyelim:

iptables -A INPUT -s ! 192.168.1.5 -p tcp –dport ssh -j DROPBir başka örnek, yerel ağdan gelmeyen tüm SSH isteklerini boşverelim:

iptables -A INPUT -i ! eth0 -p tcp –dport ssh -j DROPSanırım artık FORWARD zinciri ile de oynayabiliriz, yerel ağdan internet yönüne giden tüm SMTP iletişimini boşverelim örneğin (IP Forwarding’in açık olduğunu varsayıyorum):

iptables -A FORWARD -i eth0 -p tcp –dport smtp -j DROPIP Forwarding nedir, nasıl çalıştırılır?
IP Forwarding, daha önce de belirttiğim gibi IP paketlerinin bir ağ arayüzünden bir diğerine aktarılması; yani IP paketlerinin bir fiziksel ağdan bir diğerine aktarılması işlemidir. Linux çekirdeği, bu işlemi gerçekleştirmek için gerekli tüm yapıyı barındırır ve aktif hale getirmek kolaydır:

echo 1 > /proc/sys/net/ipv4/ip_forwardIP Forwarding işleminin düzgün çalışabilmesi için, en az bir ağ arayüzüne (Linux çekirdeği sanal arayüzler arasında da IP Forwarding yapabilir) ve en az iki IP subnet’in routing tablosunda tanımlı olmasına gereksinim duyulur:

roadrunner:~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
192.168.199.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
0.0.0.0 192.168.199.3 0.0.0.0 UG 0 0 0 eth1Örnekteki routing tablosuna göre, 192.168.1.0/24 ve 192.168.199.0/24 ağları arasında IP Forwarding işlemi gerçekleştirilebilir. Ayrıca bir default gateway (0.0.0.0: bilinmeyen ağlara 192.168.199.3 yoluyla eth1 üzerinden ulaşılacağı anlamına gelir) tanımlı olduğundan, diğer tüm ağlara erişim buradan sağlanır. IP paketlerinin hangi ağlara yönlendirileceği, routing tablosu içerisindeki kayıtlara göre belirlenir.

Öntanımlı zincir kuralları
IPTables, tüm zincirler için öntanımlı bir davranış kuralı tanımlanmasına izin verir. Eğer bir IP paketi, ilgili zincir içerisindeki kurallardan herhangi biri tarafından ACCEPT yada DROP/REJECT biçiminde işaretlenmemişse, zincirin öntanımlı kuralı tarafından yakalanır.

Örneğin, filter tablosundaki FORWARD zincirinin öntanımlı kuralını DROP olarak değiştirecek olursak:

iptables -P FORWARD DROPIP forwarding/routing sırasında, FORWARD zinciri içerisindeki kurallardan herhangi biri tarafından ACCEPT edilmeyen paketler, gözardı edilir. Özetle öntanımlı olarak tüm paketlerin forward edilmesini kapatmış oluruz, daha sonra FORWARD zincirine ekleyeceğimiz kurallarla da istisnalar tanımlayabiliriz:

iptables -P FORWARD DROP
iptables -A FORWARD -s 192.168.1.0/24 -o ppp0 -p tcp –dport ssh -j ACCEPTBu tanım sayesinde 192.168.1.0/24 ağı, ppp0 (Internet) yönüne yalnızca SSH protokolünü kullanarak erişebilir. Tabii NAT yapmazsak erişemeyecekler :)

Öneriler
Bu bölüme, iptables’i öğrenmeye başladığım günden bu yana edindiğim naçizane tecrübelerimi ve önerilerimi eklemek istedim.

•Birşeyler yapmaya başlamadan önce, tüm ağınızın bir detaylı ve bir de basit haritasını çıkarın. Ağ bileşenlerini birbirine bağladığınız çizgilerin her iki ucunda birer ok olduğunu, verinin ve bağlantıların iki yönü olabileceğini unutmayın.
•Önce herşeyi kapatın (öntanımlı zincir kurallarını kullanarak), daha sonra yalnızca ihtiyaç duyduğunuz portlara izin verin.
•Zincirlere eklediğiniz kuralların mümkün olduğunca detaylı olmasına dikkat edin. Kaynak ve hedef adres/ağ, port, ağ arayüzü gibi çeşitli parametreleri birlikte kullanarak paket seçimini olabildiğince kesin biçimde belirtin.
•Güvenliğin firewall’dan ibaret olmadığını aklınızda tutun. Kontrolünüzdeki Internet bağlantısı üzerinden yerel ağınıza erişimi engelleyebilirsiniz, ama kullanıcılarınızın kendi bilgisayarlarına modem bağlayıp Internet’e kendileri bağlanabileceklerini de hatırlayın. Güvenlik duvarınıza delik açmak veya arkasından dolaşmak için onlarca yol bulunduğunu bilin.
Kapsamlı bir firewall yapılandırması örneği
Önce örnek ağımızın neye benzediğine bir bakalım:

Şekil 3: Örnek ağ şeması

ve gereksinimlerimizi belirleyelim:

•Yerel ağımızdaki (LAN: 192.168.1.0/24) kullanıcıların 192.168.1.1 adresindeki güvenlik duvarı üzerinden yalnızca HTTP (port 80) ile web sayfalarına ulaşabilmelerini istiyoruz.
•Yerel ağımızdaki kullanıcıların DMZ (de-militarized zone, silahsızlandırılmış bölge: 10.0.0.0/8) içerisindeki dosya ve e-posta sunucularına yalnızca belirli portlardan ulaşabilmelerini istiyoruz.
•Internet üzerindeki kullanıcıların, DMZ içerisindeki e-posta sunucusuna POP3 ve SMTP portları ile, ayrıca webmail için HTTP ile erişebilmelerini istiyoruz.
•DMZ içerisindeki e-posta sunucusunun yalnızca SMTP portu ile Internet üzerindeki herhangi bir sunucuya ulaşabilmesini istiyoruz.
•DMZ içerisindeki sunucuların LAN erişimi olmamasını istiyoruz.
•Gayet tabii, Internet üzerinden LAN erişimi mümkün olmasın ve belirttiğimiz istisna dışında Internet üzerinden DMZ erişimi de mümkün olmasın istiyoruz.
Aşağıdaki shell script, gereksinimlerimizi karşılıyor olmalı:

01: #!/bin/sh
02: # Temizle
03: iptables -t nat -F
04: iptables -t nat -X
05:
06: iptables -F
07: iptables -X
08:
09: # NAT Kuralları
10: iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 -j SNAT –to 212.156.45.35
11: iptables -t nat -A POSTROUTING -s 10.0.0.0/8 -o eth1 -j SNAT –to 212.156.45.35
12: iptables -t nat -A PREROUTING -i eth1 -p tcp -m multiport –dports 25,80,110 -j DNAT –to 10.0.0.2
13:
14: # Filtering kuralları
15: iptables -P FORWARD DROP
16: # Internet üzerinden mail server erişimi izni
17: iptables -A FORWARD -i eth1 -p tcp -m multiport –dports 25,80,110 -d 10.0.0.2 -j ACCEPT
18: # Mail server’in Internet’e erişim izni
29: iptables -A FORWARD -i eth2 -s 10.0.0.2 -p tcp –dport 25 -o eth1 -j ACCEPT
20: # LAN -> Internet erisim izinleri
21: iptables -A FORWARD -i eth0 -p tcp –dport 80 -j ACCEPT
22:
23: # LAN -> DMZ erişim izinleri
24: # Mail server
25: iptables -A FORWARD -s 192.168.1.0/24 -d 10.0.0.2 -p tcp -m multiport –dports 25,110 -o eth2 -j ACCEPT
26: # File server
27: iptables -A FORWARD -s 192.168.1.0/24 -d 10.0.0.3 -p tcp -m multiport –dports 139 -o eth2 -j ACCEPT
28: iptables -A FORWARD -s 192.168.1.0/24 -d 10.0.0.3 -p udp -m multiport –dports 137,138 -o eth2 -j ACCEPT
29:
30: # Tüm gelen bağlantıları yasakla
31: iptables -P INPUT DROP
32:
33: # Loopback’den gelen bağlantıları kabul et
34: iptables -A INPUT -i lo -j ACCEPT
35: # SSH bağlantılarını yerel ağdan kabul et
36: iptables -A INPUT -i eth0 -p tcp –dport 22 -j ACCEPT
37: # Internet yönünden gelen SSH bağlantılarını kabul et
38: iptables -A INPUT -i eth1 -p tcp –dport 22 -j ACCEPT1. satır, bu dosyanın bir shell script olduğunu belirtmek için kullanılıyor. 3. ve 4. satırlar, NAT tablosu içerisindeki tüm kuralları ve kullanıcı tanımlı zincirleri silecek. 6. ve 7. satırlar bu işi Filter tablosu için yapacak. 10. satır, LAN -> Internet yönünde gidecek olan paketlere SNAT uygulayarak yerel ağdaki kullanıcıların Internet’e bağlanmasını sağlayacak. 11. satır, DMZ -> Internet yönünde erişimi SNAT ile sağlayacak. 12. satır, Internet üzerinden TCP port 25 (smtp), 80 (http) veya 110 (pop3) ile gelen kullanıcıların DMZ içerisindeki e-posta sunucusuna yönlendirilmelerini sağlayacak. 15. satır, filter tablosundaki FORWARD zincirinin öntanımlı kuralını DROP olarak değiştirecek, böylece öntanımlı olarak tüm routing işlemlerini kapatmış olacağız. Diğer satırlarda tanımlanan istisnalarla gerektiği kadarını açacağız. Diğer satırlar sanırım yerince açıklama içeriyor :)

Bu belgeyi hazırlamak biraz zamanımı aldı ve örneği istediğim kıvama getirmek için yeterince zaman bulamadım, önerilerinize açığım. Umarım birilerinin işine yarar.

İyi eğlenceler,

Bu yazı Enver Altın tarafından yazılmıştır.

All Rights Reserved.