All of lore.kernel.org
 help / color / mirror / Atom feed
* New logging module
@ 2003-08-25 12:59 Philipp Gühring
  2003-08-30 19:04 ` Harald Welte
  0 siblings, 1 reply; 7+ messages in thread
From: Philipp Gühring @ 2003-08-25 12:59 UTC (permalink / raw)
  To: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 488 bytes --]

Hi,

I developed a Netfilter module, that collects and logs the traffic of all IP 
addresses of several subnets, and dumps the traffic log regulary in a similar 
format as ipt_LOG, so that it can transparently replace the normal logging 
module.

It was developed to enhance the speed of our traffic analysis software, by 
filtering and aggregating the packets directly in the kernel instead of the 
userspace.

The license is GPL.

Many greetings,
Philipp Gühring





[-- Attachment #2: ipt_REGIONET.c --]
[-- Type: text/x-csrc, Size: 5237 bytes --]

/*
 * This is a module which is logging the regionet_traffic of IPs of whole subnets.
 */
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
#include <net/icmp.h>
#include <net/udp.h>
#include <net/tcp.h>
#include <linux/netfilter_ipv4/ip_tables.h>

struct in_device;
#include <net/route.h>
#include <linux/netfilter_ipv4/ipt_LOG.h>

#if 1
#define DEBUGP printk
#else
#define DEBUGP(format, args...)
#endif

/* Use lock to serialize, so printks don't overlap */
static spinlock_t regionet_lock = SPIN_LOCK_UNLOCKED;

static u_int32_t regionet_network[10];
static u_int32_t regionet_netmask[10];
static long regionet_netsize[10];
static int *regionet_traffic[10];
static int regionet_networks;
static unsigned int regionet_counter;
static int regionet_traffic1[256*256*4];
static int regionet_traffic2[256*4];
static int regionet_traffic3[32*4];

static unsigned int
ipt_regionet_target(struct sk_buff **pskb,
	       unsigned int hooknum,
	       const struct net_device *in,
	       const struct net_device *out,
	       const void *targinfo,
	       void *userinfo)
{
	struct iphdr *iph = (*pskb)->nh.iph;
	const struct ipt_log_info *loginfo = targinfo;
	char level_string[4] = "< >";


        int i;

        regionet_counter++;
 
        //printk("saddr: %u\n",ntohl(iph->saddr));
        for(i=0;i<regionet_networks;i++)
        {
          if((ntohl(iph->saddr) & regionet_netmask[i])==regionet_network[i])
          {
            //printk("Incoming Traffic from Network %u ...\n",i);
            (regionet_traffic[i])[ntohl(iph->saddr) - regionet_network[i]] += ntohs(iph->tot_len);
          }
          if((ntohl(iph->daddr) & regionet_netmask[i])==regionet_network[i])
          {
            (regionet_traffic[i])[ntohl(iph->daddr) - regionet_network[i]] += ntohs(iph->tot_len);
          }
          if(regionet_counter>10000)
          {
            printk("Neue Traffic Liste:\n");
 
            unsigned int j=0;
            for(j=0;j<regionet_netsize[i];j++)
            {
              if((regionet_traffic[i])[j])
              {
                int myip=regionet_network[i]+j;
                level_string[1] = '0' + (loginfo->level % 8);
                spin_lock_bh(&regionet_lock);
                printk(level_string);
                printk("SRC=%u.%u.%u.%u LEN=%u\n",HIPQUAD(myip),(regionet_traffic[i])[j]);
	        spin_unlock_bh(&regionet_lock);
              }
            }
          }
        }
       
        if(regionet_counter>10000)
        {
          regionet_counter=0;
        }

	return IPT_CONTINUE;
}

static int ipt_regionet_checkentry(const char *tablename,
			      const struct ipt_entry *e,
			      void *targinfo,
			      unsigned int targinfosize,
			      unsigned int hook_mask)
{
	const struct ipt_log_info *loginfo = targinfo;

	if (targinfosize != IPT_ALIGN(sizeof(struct ipt_log_info))) {
		DEBUGP("LOG: targinfosize %u != %u\n",
		       targinfosize, IPT_ALIGN(sizeof(struct ipt_log_info)));
		return 0;
	}

	if (loginfo->level >= 8) {
		DEBUGP("LOG: level %u >= 8\n", loginfo->level);
		return 0;
	}

	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
		DEBUGP("LOG: prefix term %i\n",
		       loginfo->prefix[sizeof(loginfo->prefix)-1]);
		return 0;
	}

	return 1;
}

static struct ipt_target ipt_regionet_reg
= { { NULL, NULL }, "LOG", ipt_regionet_target, ipt_regionet_checkentry, NULL, 
    THIS_MODULE };

static int __init init(void)
{
	regionet_counter=0;
        regionet_networks=0;

#if 1
        regionet_network[regionet_networks]=0xAC1A0000; // 172.26.0.0
        regionet_netmask[regionet_networks]=0xFFFF0000; // 255.255.0.0
        regionet_netsize[regionet_networks]=256*256;
        regionet_traffic[regionet_networks]=regionet_traffic1;
        if(regionet_traffic[regionet_networks]!=NULL)
        {
          memset(regionet_traffic[regionet_networks],0,regionet_netsize[0]*sizeof(int));
          regionet_networks++;
        }
#endif

#if 0
        regionet_network[regionet_networks]=0xC0A80100; // 192.168.1.0
        regionet_netmask[regionet_networks]=0xFFFFFF00; // 255.255.255.0
        regionet_netsize[regionet_networks]=256;
        regionet_traffic[regionet_networks]=regionet_traffic2;
        if(regionet_traffic[regionet_networks]!=NULL)
        {
          memset(regionet_traffic[regionet_networks],0,regionet_netsize[0]*sizeof(int));
          regionet_networks++;
        }
#endif

        regionet_network[regionet_networks]=0xC36ED680; // 195.110.214.128
        regionet_netmask[regionet_networks]=0xFFFFFFE0; // 255.255.255.0
        regionet_netsize[regionet_networks]=32;
        regionet_traffic[regionet_networks]=regionet_traffic3;
        if(regionet_traffic[regionet_networks]!=NULL)
        {
          memset(regionet_traffic[regionet_networks],0,regionet_netsize[0]*sizeof(int));
          regionet_networks++;
        }

      	DEBUGP("REGIONET: Number of monitoring regionet_networks: %u\n", regionet_networks);
	
	if (ipt_register_target(&ipt_regionet_reg))
		return -EINVAL;

	return 0;
}

static void __exit fini(void)
{
	ipt_unregister_target(&ipt_regionet_reg);
}

module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");


[-- Attachment #3: Makefile --]
[-- Type: text/x-makefile, Size: 588 bytes --]

all: ipt_REGIONET.o

ipt_REGIONET.o: ipt_REGIONET.c
	gcc -D__KERNEL__ -I/usr/src/linux-2.4.20.SuSE/include -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -fno-strict-aliasing -fno-common -Wno-sign-compare -finline-limit=2000 -fomit-frame-pointer -pipe -mpreferred-stack-boundary=2 -march=athlon  -DMODULE  -nostdinc -iwithprefix include -DKBUILD_BASENAME=ipt_REGIONET  -c -o ipt_REGIONET.o ipt_REGIONET.c


test:	ipt_REGIONET.o
	/etc/rc.d/SuSEfirewall2_setup stop	
	rmmod ipt_REGIONET || true
	insmod ipt_REGIONET.o
	/etc/rc.d/SuSEfirewall2_setup start
	/etc/rc.d/SuSEfirewall2_final start

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: New logging module
  2003-08-25 12:59 New logging module Philipp Gühring
@ 2003-08-30 19:04 ` Harald Welte
       [not found]   ` <200308302248.h7UMm5r04111@linux1.futureware.at>
  0 siblings, 1 reply; 7+ messages in thread
From: Harald Welte @ 2003-08-30 19:04 UTC (permalink / raw)
  To: pg; +Cc: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 1548 bytes --]

On Mon, Aug 25, 2003 at 02:59:02PM +0200, Philipp Gühring wrote:
> Hi,
> 
> I developed a Netfilter module, that collects and logs the traffic of all IP 
> addresses of several subnets, and dumps the traffic log regulary in a similar 
> format as ipt_LOG, so that it can transparently replace the normal logging 
> module.

Why did you do that?  I think it's from an architectural point of view
the wrong choice.  ipt_ULOG was invented for the sole reason that string
processing and parsing/interpretation of logged packets should not be
done inside a softirq inside the kernel.  All this should be offloaded
to userspace.

and: iptables rules are not an ideal infrastructure for accounting
anyway.

> It was developed to enhance the speed of our traffic analysis software, by 
> filtering and aggregating the packets directly in the kernel instead of the 
> userspace.

So what you really want is a session log, similar to netflow?  This
should be easy to implement with adding packet/byte counters to struct
ip_conntrack.  Several people have been working on session-log systems
based on netfilter/iptables.

> Many greetings,
> Philipp Gühring

-- 
- Harald Welte <laforge@netfilter.org>             http://www.netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: New logging module
       [not found]   ` <200308302248.h7UMm5r04111@linux1.futureware.at>
@ 2003-09-05 14:04     ` Harald Welte
  2003-09-06  1:13       ` Henrik Nordstrom
  0 siblings, 1 reply; 7+ messages in thread
From: Harald Welte @ 2003-09-05 14:04 UTC (permalink / raw)
  To: Philipp Gühring; +Cc: Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 5029 bytes --]

On Sun, Aug 31, 2003 at 12:47:36AM +0200, Philipp Gühring wrote:

> I think that my implementation is very efficient.
> * ipt_LOG is doing far more parsing/interpretation work on every
>   packet than my module.

yes, indeed.

> * IPtables already analyzed the packet (NAT reversing)

true.

> * There is no kernel/userspace switch necessary

> * The accounting rule is very simple, just IP based traffic, nothing more 
> complex
> 
> I agree that it would not make much sense, if it would need more complex 
> rules to do it that way in kernelspace.
> 
> > and: iptables rules are not an ideal infrastructure for accounting
> > anyway.
> 
> Why not?

You basically have different ways of doing an accounting system:

0) via raw or packet socket

this is what solutions like nacctd do.  

pro: very flexible, very portable
con: high CPU utilization

1) as a netfilter module

then you basically implement an accounting system that captures packets
within the kernel.  There is no relation to iptables - you're just
using a netfilter hook.

pro: no per-packet contex switch
con: have to implement everything from scratch

2) as an iptables target

then all the logic (and different users have different accounting
criteria) needs to be within the target.  All configuration information
has to be passed back and forth via the targinfo structure.

pro: easy implementation, you can use iptables to account only certain
packets
con: very limited scope.
con: you'd need a very flexible language to tell the module _what_ to
account 

3) as part of ip_conntrack

this means that every struct ip_conntrack gets two byte counters (one
for each direction).  when a connection is terminated, you send the
accounting information about this connection to usrerspace (preferrably
via netlink).   you can sum up traffic for certain ports / addresses in
userspace.

pro: very easy implementation 
pro: you can easily generate industry-standard netflow logfiles
pro: at most one context switch per _connection_

4) in userspace, receiving packets via ULOG 

this means that the first n (user-defined) bytes of every packet gets
copied into a buffer, and this buffer is flushed to userspace when it
fills up (usually every 1000-5000 packets) or a timer goes off.  all
further processing is just like nacctd completely userspace based

pro: easy implementation, you can use iptables to select what you want
to account
pro: low number of context switches
pro: very flexible, all information is in userspace


From my point of view, either solutions 3 or 4 should be used (depending
on the specific case).   Solution 2 has the inherent problem that it
might cover a very specific case, but is difficult to generalize.
Solution 1 is just too much work...

> But without ARP Spoofing (which started one week ago), the accounting system 
> worked perfectly, since the beginning.

I'm not stating that it doesn't work.  I'm just saying that there are
different architectures that might enable more functionality (and thus
make it more usful to other users).

> I have the following proposal to solve the ARP spoofing problem, as much as 
> possible:
> 
> 1. Create a real static ARP table system, that not only has immutable ARP 
> entries, but also does not take up new ARP entries from the network

you can insert static arp entries from userspace, and use a
netfilter-arp module to block all incoming arp traffic.

> But I am not yet sure, where the correct point to work on it is.

Sounds interesting, and definitely doable.

> I am not quite sure what you mean with session here. I do not see sessions, 
> since I am not using Radius (Radius Sessions), I want to account all IP 
> traffic (so no TCP Sessions), I am doing both NAT and plain routing (so no 
> NAT Sessions), and it is for 24/7 internet access, so there are no naturally 
> time-based sessions.

ok.  I understand the setup now.  The module might be doing a good job
for your case - but it is not suitable as a general-purpose accounting
infrastructure.

> > should be easy to implement with adding packet/byte counters to struct
> > ip_conntrack.  Several people have been working on session-log systems
> > based on netfilter/iptables.
> 
> That sounds interesting. Can you give me links or point me into the right 
> direction?

try to look in the list archives,  I would also have to search them.
Once there was a SLOG target for session logging - and I also remember a
'connbytes' match that at least adds the counters.

> ~ Philipp Gühring              p.guehring@futureware.at
-- 
- Harald Welte <laforge@netfilter.org>             http://www.netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: New logging module
  2003-09-05 14:04     ` Harald Welte
@ 2003-09-06  1:13       ` Henrik Nordstrom
  2003-09-07 19:13         ` Roberto Nibali
  2003-09-12 20:39         ` Harald Welte
  0 siblings, 2 replies; 7+ messages in thread
From: Henrik Nordstrom @ 2003-09-06  1:13 UTC (permalink / raw)
  To: Harald Welte; +Cc: Netfilter Development Mailinglist

On Fri, 5 Sep 2003, Harald Welte wrote:

> 3) as part of ip_conntrack
> 
> this means that every struct ip_conntrack gets two byte counters (one
> for each direction).  when a connection is terminated, you send the
> accounting information about this connection to usrerspace (preferrably
> via netlink).   you can sum up traffic for certain ports / addresses in
> userspace.
> 
> pro: very easy implementation 
> pro: you can easily generate industry-standard netflow logfiles
> pro: at most one context switch per _connection_
> 
> 4) in userspace, receiving packets via ULOG 
> 
> this means that the first n (user-defined) bytes of every packet gets
> copied into a buffer, and this buffer is flushed to userspace when it
> fills up (usually every 1000-5000 packets) or a timer goes off.  all
> further processing is just like nacctd completely userspace based
> 
> From my point of view, either solutions 3 or 4 should be used (depending
> on the specific case).


3 looks very intersting and is something which we have been thinking we
need for a long time to implement meaningful accounting in a
iptables+conntrack+NAT based firewall.

What we have considered to log from conntrack is maybe a little more than
described above:

1. Start of session

2. Periodically while the conntrack session is active (preferably 
by a configurable interval)

3. End of session

with byte and packet counters in both directions.

'2' to be able to account "last 5 minutes of traffic" even if there is 
long-running sessions, but not too often. Once per accounting interval 
used is required, more often is overhead, less gives less accuracy than 
desired for the accounting.

Do you know if anyone else is attempting to do this?  If not we might give
it a stab shortly..

Regards
Henrik

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: New logging module
  2003-09-06  1:13       ` Henrik Nordstrom
@ 2003-09-07 19:13         ` Roberto Nibali
  2003-09-12 20:39         ` Harald Welte
  1 sibling, 0 replies; 7+ messages in thread
From: Roberto Nibali @ 2003-09-07 19:13 UTC (permalink / raw)
  To: Henrik Nordstrom; +Cc: netfilter-devel

Hi Henrik,

> 3 looks very intersting and is something which we have been thinking we
> need for a long time to implement meaningful accounting in a
> iptables+conntrack+NAT based firewall.
> 
> What we have considered to log from conntrack is maybe a little more than
> described above:
> 
> 1. Start of session
> 
> 2. Periodically while the conntrack session is active (preferably 
> by a configurable interval)
> 
> 3. End of session

SLOG was designed to handle 1 and 3 but is easily extensible with 2, 
provided someone finishes the work.

> with byte and packet counters in both directions.
> 
> '2' to be able to account "last 5 minutes of traffic" even if there is 
> long-running sessions, but not too often. Once per accounting interval 
> used is required, more often is overhead, less gives less accuracy than 
> desired for the accounting.
> Do you know if anyone else is attempting to do this?  If not we might give
> it a stab shortly..

As Harald mentioned, there is the SLOG target patch which we started 
once in our company based on a student's semester work. You can find the 
current drop here:

http://www.drugphish.ch/patches/ratz/netfilter/

I have not touched much of it since its first write and it currently 
crashes the kernel. Another problem is that I simply didn't have the 
time to track {ct,nf}-netlink changes. So the status of the patch is the 
following:

o based on 2.4.18, which means that it will _not_ work and most
   definitely not even apply to recent kernels anymore.
o The development version (the one with the correct implementation of 1
   and 3) crashes upon reception of the first packet for SLOG which is
   most probably a missing initialisation in the timer handling.
o the user-space patch should be pretty easy to forward port.
o I had 4 people using the non-development version and giving me
   feedback but I haven't heard back from them since.

Please contact me privately if you're interested in working on SLOG.

Best regards,
Roberto Nibali, ratz
-- 
echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: New logging module
  2003-09-06  1:13       ` Henrik Nordstrom
  2003-09-07 19:13         ` Roberto Nibali
@ 2003-09-12 20:39         ` Harald Welte
  2003-09-13  7:54           ` Henrik Nordstrom
  1 sibling, 1 reply; 7+ messages in thread
From: Harald Welte @ 2003-09-12 20:39 UTC (permalink / raw)
  To: Henrik Nordstrom; +Cc: Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 2320 bytes --]

On Sat, Sep 06, 2003 at 03:13:08AM +0200, Henrik Nordstrom wrote:
> On Fri, 5 Sep 2003, Harald Welte wrote:

Sorry for my late reply.

> > 3) as part of ip_conntrack
> > 
> > this means that every struct ip_conntrack gets two byte counters (one
> > for each direction).  when a connection is terminated, you send the
> > accounting information about this connection to usrerspace (preferrably
> > via netlink).   you can sum up traffic for certain ports / addresses in
> > userspace.
> 
> 3 looks very intersting and is something which we have been thinking we
> need for a long time to implement meaningful accounting in a
> iptables+conntrack+NAT based firewall.
> 
> What we have considered to log from conntrack is maybe a little more than
> described above:
> 
> 1. Start of session

have you seen the last ctnetlink  changes from Patrick McHardy?  He
already has a event interface where you can receive notifications about
state changes (creation/deletion/...)

> 2. Periodically while the conntrack session is active (preferably 
> by a configurable interval)

this would be something new.  Does this have to be event-based from the
kernel?  Why can't you just periodically dump the whole table via GET
requests from userspace?

> 3. End of session

again covered by patrick's event code.  If you send the whole conntrack
for every event (start/stop of session), the counters would be included.

> with byte and packet counters in both directions.

> Do you know if anyone else is attempting to do this?  If not we might give
> it a stab shortly..

no, I am not aware of any ongoing effort.  If you would dig into this,
it would be greatly appreciated.

Please make sure that struct ip_conntrack is layed out in a way that all
writeable parts (timer, counters) are packed together in the same
cacheline. this way we don't get cache ping-pong for the whole
structure.

> Regards
> Henrik

-- 
- Harald Welte <laforge@netfilter.org>             http://www.netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: New logging module
  2003-09-12 20:39         ` Harald Welte
@ 2003-09-13  7:54           ` Henrik Nordstrom
  0 siblings, 0 replies; 7+ messages in thread
From: Henrik Nordstrom @ 2003-09-13  7:54 UTC (permalink / raw)
  To: Harald Welte; +Cc: Netfilter Development Mailinglist

On Fri, 12 Sep 2003, Harald Welte wrote:

> this would be something new.  Does this have to be event-based from the
> kernel?  Why can't you just periodically dump the whole table via GET
> requests from userspace?

Not sure. It depends on what is worst.. the overhead of event handling in
the kernel or the overhead of dumping all rules even those who does not
need to be logged as their start/stop was logged recently. But it sure
should be possible to use a conditional GET only returning open
long-running sessions.

> > 3. End of session
> 
> again covered by patrick's event code.  If you send the whole conntrack
> for every event (start/stop of session), the counters would be included.

Indeed.

> Please make sure that struct ip_conntrack is layed out in a way that all
> writeable parts (timer, counters) are packed together in the same
> cacheline. this way we don't get cache ping-pong for the whole
> structure.

Right.. this should be a problem for the tcp window tracking code as well, 
the difference being that the counters are not normally needed other than 
when producing the logs (unless a match using these counters are also 
done).

Regards
Henrik

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2003-09-13  7:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-08-25 12:59 New logging module Philipp Gühring
2003-08-30 19:04 ` Harald Welte
     [not found]   ` <200308302248.h7UMm5r04111@linux1.futureware.at>
2003-09-05 14:04     ` Harald Welte
2003-09-06  1:13       ` Henrik Nordstrom
2003-09-07 19:13         ` Roberto Nibali
2003-09-12 20:39         ` Harald Welte
2003-09-13  7:54           ` Henrik Nordstrom

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.