I am currently working (amongst other projects ..) on nfqueue-bindings, set of high-level modules for several languages (Python and Perl, for the moment), for libnetfilter_queue.

The goal is to provide a library to gain access to packets queued by the kernel packet filter. For more details, see nfqueue-bindings project site.

Current state

Actually, you can

  • access the module in Perl or Python
  • create a queue connected to netfilter
  • register a callback
  • access the contents of the packet. As I do not want to do what was already done many times, I use some other libraries to decode the packet:
  • NetPacket::IP for Perl
  • dpkg for Python.
    • If you know some other libraries, please let me know.
  • set the verdict (decision) to ACCEPT or DROP for the packet

I have written some scripts to show what can be done in a few lines of code. The current examples are:

I will make a release as soon as the code is stable (and can be installed).

Examples

Create and bind the queue (Perl)

use nfqueue;

use NetPacket::IP qw(IP_PROTO_TCP);
use NetPacket::TCP;

my $q;

sub cb
{
...
}

$q = new nfqueue::queue();
$q->open();
$q->bind();
$q->set_callback(\&cb);

$q->try_run();

Create and bind the queue (Python)

import nfqueue
from dpkt import ip

q = None

def cb(dummy, payload):
  ...

q = nfqueue.queue()
q.open()
q.bind()
q.set_callback(cb)
q.create_queue(0)

q.try_run()

Decode packet (Perl)

Now all we have to do is to use the callback !

my $ip_obj = NetPacket::IP->decode($payload->get_data());
print("$ip_obj->{src_ip} => $ip_obj->{dest_ip} $ip_obj->{proto}\n");

if($ip_obj->{proto} == IP_PROTO_TCP) {
  my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data});
    print "TCP src_port: $tcp_obj->{src_port}\n";

Decode packet (Python)

data = payload.get_data()
pkt = ip.IP(data)
print "proto:", pkt.p
print "source: %s" % inet_ntoa(pkt.src)
print "dest: %s" % inet_ntoa(pkt.dst)
if pkt.p == ip.IP_PROTO_TCP:
  print "  sport: %s" % pkt.tcp.sport
  print "  dport: %s" % pkt.tcp.dport

Set verdict

Perl:

$payload->set_verdict($nfqueue::NF_DROP);

Python:

payload.set_verdict(nfqueue.NF_DROP)

Links