<$BlogIt
Bir kaç ay önce iptables üzerinden geçenleri detaylı bir şekilde incelemem gerekmişti, o vakit iptables kurallarından QUEUE 'yi keşfetmiştim. Linux üzerinde çalışan iptables firewall'u ile C veya perl ile yazacağım bir scripti konuşturabildiğimi öğrenince pek bir sevinmiştim.

Isınarak ve açıklayarak ilerlemek gerekirse;

IPTABLES nedir?
Iptables Linux işletim sistemleri üzerinde kernel'da gömülü olarak çalışan bir firewall(güvenlik duvarı)dır.

Makinaya gelen veya giden paketler mutlaka iptables'a gelir ve hikaye tam da bu noktada başlar. Eğer hiçbir kural yazmadıysanız iptables pakete hiçbir müdehale yapmadan geçip gitmesine izin verir.

# iptables -A OUTPUT -p tcp -j DROP

En basit kullanım şekli üstte ki gibidir, üstte ki satırda(kuralda) şunu demiş olduk;
* Linux işletim sistemi üzerinden dışarıya doğru gidecek olan herhangi bir TCP paketini DROP et. (yani izin verme)

Iptables konusu çok geniş olduğu için burda en basit hali ile değinip geçiyorum, daha fazla detay için yazılmış çok fazla türkçe ve ingilizce döküman mevcut, ufak bir google araması ile yığınla sonuca ulaşabilirsiniz..

QUEUE nedir?
Queue kelime anlamı olarak kuyruk anlamına gelmektedir. Iptables içinde kullanımı da pek farklı değildir aslında. Iptables'a gelen ya da giden paketler için bir QUEUE kuralı girilmişse , iptables gelen ya da giden her paketi memory'de bir kuyruğa koyar. Eğer sistemde queue paketlerini dinleyecek harici bir uygulama çalışmıyorsa paketler uzay boşluğunda kaybolur gider ve otomatik olarak DROP olurlar.

Script hakkında;
Ben araştırmam sırasında bir kaç tane C ile yazılmış kod buldum, tabii olduğu gibi çalıştıramadım. Üzerinde bazı manipülasyonlar yaptıktan sonra (bunlardan ayrıca bahsedeceğim) çalışır hale getirdim.

Script şu hali ile basitçe şu işi yapıyor: Queue ile scripte gelen paketlerin tamamını önce show_packet fonksiyonu ile hex karaterleri char olarak dönüştürdükten sonra ekranda anlamlı bilgilerin akıp gittiğini görebiliyorsunuz.

Ben output , yani makinadan giden paketleri queue yapıp ekranda ki bilgileri izlemiştim, güzel görünüyor, örneğin bir internet sitesine girdiğinizde, ya da ekli bir mail gönderdiğinizde dosya içeriği dahil herşey ekranınızdan ayna gibi akıp gidiyor...

Burda ki amacım paketlerin içeriklerini detaylı olarak görebilmekti, gördükten sonra paketlerin içeriğinde olmasını istemediğiniz bir durumu yakalamaya yönelik bir kod yazdıktan sonra paketi drop ya da accept(izin vermek) edebilirsiniz.

Ben altta göreceğiniz kodda bilgileri izledikten sonra tüm paketlerin geçip gitmesine izin verdim.

Script içinde kullanılan method'lar ve kısaca açıklamaları;
ipq_create_handle(0, PF_INET);
ip_queue tarafından kullanılan Netlink soketini handle etmek için kullanılır...

Parametre ve structure bilgisi altta ki gibi,

struct ipq_handle *ipq_create_handle(u_int32_t flags, u_int32_t protocol);

Geri dönüş değeri, başarılıysa bir pointer değilse NULL döner...

ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
Kendisine şahane fonksiyon diyebiliriz, scriptimiz ile yakaladığımız iptables paketini modify etmeye yaramaktadır.

Burada bizi en çok ilgilendiren parametre NF_ACCEPT/NF_DROP parametreleridir. İsimlerinden da anlayacağınız üzere izin vermek için NF_ACCEPT derken paketi engellemek için NF_DROP parametresini kullanıyoruz.

How To Run iptables queue script? / Scripti nasıl çalıştıracağız?
---------- |
| | --------- output packet ----->>> |
| Linux | | internet veya başka biryer
| | <<< --- input packet ------------- |
---------- |

** Makinada gcc yüklüdür diye tahmin ediyorum :) değilse hemen gcc C kod derleyicisini kurun.

Sonra kosoldan altta ki kodu (adı : ipq.c olsun) ;

# gcc -o ipq ipq.c -lipq

diyerek derliyoruz. artık elimizde çalışır halde ipq programı var..

Şimdi iptables ile ilgili ayarları yapalım;

# modprobe ip_filter
# modprobe ip_queue
# echo "1" >/proc/sys/net/ipv4/ip_forward
# iptables -A OUTPUT -p tcp -j QUEUE

Bu komutlarla eğer yoksa sisteme ip_filter ve ip_queue modüllerini yükledik, sonra makina üzerinde forwarding işlemlerinin yapılabilmesi için ilgili parametreyi 1 olarak set ettik. Eğer 0 olursa iptables ile forwarding yapılmaz.

Ve en son makinadan giden paketlerin hepsini queue, ederek yazdığımız programa gönderiyoruz.

sonra altta ki komutu verip, bir kaç internet sayfasını ziyaret edin ve arkanıza yaslanıp konsoldan akıp giden site içeriğini izleyin..

# ./ipq

Not: Bu işlemler genellikle sisteminizi mahvetmez ama olur da birşeyler karışırsa sorumluluk kabul etmiyoruz. Zaten bu işleme ihtiyac duyacak birileri biraz da olsa sistem , iptables ve programcılık konusunda expert kullanıcıdır.

Herhangi bir soru veya yorumunuz olursa yorum yazabilir ya da bocuhk a t gmail dot com adresinden bana ulaşabilirsiniz.

Kolay gelsin...
/*
* This code is GPL.
*/

#include </root/dt/netfilter.h>
#include <libipq.h>

#include <stdio.h>
#define BUFSIZE 2048
static void die(struct ipq_handle *h)
{


ipq_perror("passer");
ipq_destroy_handle(h);
exit(1);
}


void
showPacket(ipq_packet_msg_t *pkt){
int
i=0;

printf("\n Raw packet: --------------------------\n");
for
(i=0;i<pkt->data_len;i++){

printf("%c ", (char)pkt->payload[i]);
}

printf("\n End of raw packet ------------------");
}



/* Checksum for IP header
*/

unsigned short
checksum(unsigned short *addr, int len)
{


int
nleft=len;
int
sum=0;
unsigned short
*w=addr;

unsigned short
answer=0;

while
(nleft>1){
sum+=*w++;

nleft-=2;
}

if
(nleft==1){
*(
unsigned char *)(&answer)=*(unsigned char *)w;

sum+=answer;
}

sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);

answer=~sum;
return
answer;
}


int
main(int argc, char **argv)
{


int
status;
int
c;
unsigned char
buf[BUFSIZE];

struct
ipq_handle *h;
h = ipq_create_handle(0, PF_INET);

if
(!h)
die(h);
status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);

if
(status < 0)
die(h);
c = 0;

do
{
c = c +1;
//printf("Donence.. %d ", c);

status = ipq_read(h, buf, BUFSIZE, 0);

printf("status: %d \n", status);
if
(status < 0)

die(h);
switch
(ipq_message_type(buf))
{

case
NLMSG_ERROR:

fprintf(stderr, "Received error message %d\n",
ipq_get_msgerr(buf));
break
;

case
IPQM_PACKET:
{

ipq_packet_msg_t *m = ipq_get_packet(buf);

showPacket(m);
printf("packet: %d\n",m->data_len);
status = ipq_set_verdict(h, m->packet_id,

NF_ACCEPT, 0, NULL);
if
(status < 0)

die(h);
break
;
}

default
:
fprintf(stderr, "Unknown message type!\n");

break
;
}
}
while (1);
ipq_destroy_handle(h);
return
0;
}


Etiketler: , , , , ,

class="post-footer"> by <$BlogItDavut Topcanref="<$BlogIthttp://davuttopcan.blogspot.com/2009/02/iptables-queue-nasl.html"permanent link"><$BlogIt18:45>

<$BlogIt0r!:

<$BlogItYorum Gönder

yazar hakkinda

Merhabalar, ben Davut Topcan

Buraya eminim ki bir sürü şey yazacağım ancak şimdi tasarımı tamamlamalıyım..!

eski yazılar