关于Snort和NetFilter或IPTables的联动

关于SnortNetFilterIPTables的联动,可以通过SnortUnix Socket来实现,Snort有几种格式发送报警信息,其中就包括Unix Socket

使用Unix Socket主要是因为可以通过写一个小的程序就可以实时收集报警信息,然后针对不同信息,来设置IPTables

如果使用Syslog或其他,就不能实时收集信息。这是采用Unix Socket的原因。下面是我写的一个收集SnortUnix Socket的程序。但我只是把

收集到的信息显示到Console上。没有写针对特定报警信心设置IPTables的程序,事实上,第二部分的工作不会很难了。

这就是整个一个思路。

下面是源码,在RH Linux 9上运行通过。

#include  < sys / types.h >

#include 
< string .h >

#include 
< strings.h >

#include 
< sys / un.h >

#include 
< sys / socket.h >

#include 
< netinet / in .h >

#include 
< unistd.h >

#include 
< errno.h >

#include 
< sys / time.h >

#include 
< pcap.h >

 

#define  UNSOCK_FILE "/var/log/snort/snort_alert"

 

struct  EtherHdr 

{

           u_int8_t ether_dst[
6];

    u_int8_t ether_src[
6];

    u_int16_t ether_type;

}
;

 

struct  IPHdr

{

    u_int8_t ip_verhl;      
/* version & header length */

    u_int8_t ip_tos;        
/* type of service */

    u_int16_t ip_len;       
/* datagram length */

    u_int16_t ip_id;        
/* identification  */

    u_int16_t ip_off;       
/* fragment offset */

    u_int8_t ip_ttl;        
/* time to live field */

    u_int8_t ip_proto;      
/* datagram protocol */

    u_int16_t ip_csum;      
/* checksum */

    
struct in_addr ip_src;  /* source IP */

    
struct in_addr ip_dst;  /* dest IP */

}
;

 

struct  TCPHdr

{

    u_int16_t th_sport;     
/* source port */

    u_int16_t th_dport;     
/* destination port */

    u_int32_t th_seq;       
/* sequence number */

    u_int32_t th_ack;       
/* acknowledgement number */

    u_int8_t th_offx2;     
/* offset and reserved */

    u_int8_t th_flags;

    u_int16_t th_win;       
/* window */

    u_int16_t th_sum;       
/* checksum */

    u_int16_t th_urp;       
/* urgent pointer */

 

}
;

 

struct  UDPHdr

{

    u_int16_t uh_sport;

    u_int16_t uh_dport;

    u_int16_t uh_len;

    u_int16_t uh_chk;

}
;

 

struct  ICMPHdr

{

    u_int8_t type;

    u_int8_t code;

    u_int16_t csum;

    union

    
{

        u_int8_t pptr;

 

        
struct in_addr gwaddr;

 

        
struct idseq

        
{

            u_int16_t id;

            u_int16_t seq;

        }
 idseq;

 

        
int sih_void;

 

        
struct pmtu 

        
{

            u_int16_t ipm_void;

            u_int16_t nextmtu;

        }
 pmtu;

 

        
struct rtradv 

        
{

            u_int8_t num_addrs;

            u_int8_t wpa;

            u_int16_t lifetime;

        }
 rtradv;

    }
 icmp_hun;

 

    union 

    
{

        
/* timestamp */

        
struct ts 

        
{

            u_int32_t otime;

            u_int32_t rtime;

            u_int32_t ttime;

        }
 ts;

        

        

        
struct ra_addr 

        
{

            u_int32_t addr;

            u_int32_t preference;

        }
 radv;

 

        u_int32_t mask;

 

        
char    data[1];

 

    }
 icmp_dun;

}
;

 

struct  Packet

{

    u_int8_t pkt[
1514];              /* base pointer to the raw packet data */

    
struct EtherHdr eh;               /* standard TCP/IP/Ethernet/ARP headers */

    
struct IPHdr iph;   /* and orig. headers for ICMP_*_UNREACH family */

    
struct TCPHdr tcph;

    
struct UDPHdr udph;

    
struct ICMPHdr icmph;

 

}
;

 

struct  Event

{

    u_int32_t sig_generator;   
/* which part of snort generated the alert? */

    u_int32_t sig_id;          
/* sig id for this generator */

    u_int32_t sig_rev;         
/* sig revision for this id */

    u_int32_t classification;  
/* event classification */

    u_int32_t priority;        
/* event priority */

    u_int32_t event_id;        
/* event ID */

    u_int32_t event_reference; 
/* reference to other events that have gone off,

                                * such as in the case of tagged packets

                                
*/


    
struct timeval ref_time;   /* reference time for the event reference */

}
;

 

struct  Alertpkt

{

    u_int8_t alertmsg[
256]; /* variable.. */

    
struct pcap_pkthdr pkth;

    u_int32_t dlthdr;       
/* datalink header offset. (ethernet, etc.. ) */

    u_int32_t nethdr;       
/* network header offset. (ip etc*/

    u_int32_t transhdr;     
/* transport header offset (tcp/udp/icmp ..) */

    u_int32_t data;

    u_int32_t val; 

    
#define NOPACKET_STRUCT 0x1

 

    
#define NO_TRANSHDR    0x2

    u_int8_t pkt[
1514];

    
struct Event event;

}
;

 

void  ParsePacket( struct  Packet  * p, struct  Alertpkt  * alert) 

{

         

         printf(
"alert message=%s\n",alert->alertmsg);

         
if(alert->pkt)

  
{

      bcopy(alert
->pkt,p->pkt,sizeof(alert->pkt));

  }


  bcopy((alert
->pkt + alert->dlthdr),&p->eh,sizeof(struct EtherHdr));

  
if(ntohs(p->eh.ether_type)==0x0800)

  
{

             bcopy((alert
->pkt + alert->nethdr),&p->iph,sizeof(struct IPHdr));

                  
switch(p->iph.ip_proto) 

                  
{

                            
case 1:

                                                        bcopy((alert
->pkt + alert->transhdr),&p->icmph,sizeof(struct ICMPHdr));

                                                        
break;                                             

                            
case 6:

                                                        bcopy((alert
->pkt + alert->transhdr),&p->tcph,sizeof(struct TCPHdr));

                                                        
break;

                            
case 17:

                                         bcopy((alert
->pkt + alert->transhdr),&p->udph,sizeof(struct UDPHdr));

                                                        
break;

                            
default

                                              
break;

                  }


  }


}


 

int  main ( int  argc, char **  argv)

{

         
int sockfd,serverfd;

  
struct sockaddr_un snortaddr;

  
struct sockaddr_un bogus;

  
struct sockaddr_in serveraddr;

  
struct Packet *p;

  
struct Alertpkt alert;

  
int recv;

  

  
char *protocolnames[100];

  protocolnames[
1]="ICMP";

  protocolnames[
6]="TCP";

  protocolnames[
17]="UDP";

  

  socklen_t len 
= sizeof (struct sockaddr_un);

 

  
if ((sockfd = socket (AF_UNIX, SOCK_DGRAM, 0)) < 0)

  
{

    perror (
"socket");

    exit (
1);

  }


  
if ((serverfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

  
{

    perror (
"socket");

    exit (
1);

  }


 

  

  unlink(UNSOCK_FILE);

  bzero (
&snortaddr, sizeof (snortaddr));

  
/*

  serveraddr.sin_family=AF_INET;

  serveraddr.sin_port=htons(30000);

  serveraddr.sin_addr.s_addr = inet_addr("202.203.255.105");

  bzero(&(serveraddr.sin_zero), 8); 

 

  if(connect(serverfd,(struct sockaddr *)&serveraddr,sizeof(struct sockaddr)) == -1)

                   {

                     perror("connect");

                     exit(1);

                   } 

         
*/


  

  snortaddr.sun_family 
= AF_UNIX;

  strcpy (snortaddr.sun_path, UNSOCK_FILE); 

 

  
if (bind (sockfd, (struct sockaddr *&snortaddr, sizeof (snortaddr)) < 0)

    
{

      perror (
"bind");

      exit (
1);

    }


  
// receive from snort

  printf(
"receive from snort");

  
while ((recv = recvfrom (sockfd, (void *&alert, sizeof (alert),

                   
0, (struct sockaddr *&bogus, &len)) > 0)

         
{

                            printf(
"\n----------------------------------------------------------\n");

                            
if(&alert)

                            
{

                                               p 
= (struct Packet *)malloc(sizeof(struct Packet));

                                               ParsePacket(p,
&alert);

                                               
if(p)

                                               
{

                                                        printf(
"Protocol Name :{%s}\n", protocolnames[p->iph.ip_proto]);

                                                        
switch(p->iph.ip_proto)

                     
{

                         
case IPPROTO_UDP:

                             printf(
"Source IP:{%s}\n", inet_ntoa(p->iph.ip_src));

                             printf(
"Destination IP:{%s}\n", inet_ntoa(p->iph.ip_dst));

                                                                                                       printf(
"Source Port:{%d}\n",ntohs(p->udph.uh_sport));

                             printf(
"Destination Port:{%d}\n", ntohs(p->udph.uh_dport));              

                         
case IPPROTO_TCP:

                             printf(
"Source IP:{%s}\n", inet_ntoa(p->iph.ip_src));

                             printf(
"Destination IP:{%s}\n", inet_ntoa(p->iph.ip_dst));

                                                                                                       printf(
"Source Port:{%d}\n",ntohs(p->tcph.th_sport));

                             printf(
"Destination Port:{%d}\n", ntohs(p->tcph.th_dport));

                             
break;

                         
case IPPROTO_ICMP:

                         
default:

                            
break;

                     }


                                               }
        

                                               free(p);

                                               
/*send(serverfd,alert,sizeof(alert),0);*/

                                               

                             }


    }


  
return 0;

}


你可能感兴趣的:(iptables)