Flux RSS

Monday 16 June 2008

Linux kernel and entropy

Since recent versions, entropy generation is very slooooooow on Linux (mainly because the entropy generation algorithm has been changed for security). This can be really painful when generating certificates, for ex. for Prelude. Reading /dev/random only gives a few bytes per second !

If you're lucky, you will have a hardware random generator (RNG). However this is generally not the case, so how to speed up random generation ?

One solution is to take random data from another source and then inject if to the kernel random pool. You have to be careful though, because if you read data from /dev/null it will be fast, but you will have problems !

Install rng-tools, which reads data from a configurable input source (hardware RNG, or, in our case, /dev/urandom). Before injecting data to the kernel, rng-tools test data with the FIPS 140-2 test, and then add it.

Warning: if you want to generate, for ex, certificates for Prelude, you must fully install and configure rng-tools before installing Prelude !

apt-get install rng-tools
vi /etc/default/rng-tools

Change the values, for ex:

HRNGDEVICE=/dev/urandom
RNGDOPTIONS="-W 80% -t 20"

The second line tells rng-tools to fill 80% of the kernel random pool (default is 50%) every 20 seconds maximum (default is 60). You may want to adjust these not to be too aggressive, or your "tainted" random data will completely replace real random data. See man rngd for more information.

/etc/init.d/rng-tools start

Caution: if you want 100%-sure random data, then stick to the default random generator, or use other libraries

Sunday 8 June 2008

NFQueue bindings (2)

The code for nfqueue-bindings is now almost ready, I have made some progress since last week:

* you can now modify packets in live, and send the new packet with the verdict
* new functions are wrapped, and the creation of the queue can be done in one function
* more examples

I have presented a special script for SSTIC, using the weather to decide if a packet should be accepted or dropped :) While the utility of the module still has to be proven, it is a good example of how easy it is to use the new bindings.

The slides can be found online here, and contains some code examples (with some funny things ;). They are in french, but they should be quite easy to understand.

Random ideas:

* The Netfilter workshop will be held in Paris from 30 September to 3 October 2008.
* Eric has presented nf3d, a nice tool to view netfilter logs (from ulogd2) in 3D.

Gamers will recognize a nice try to convert network logs into Guitar Hero tracks ;)

* Some people have weird habits at SSTIC !

Sunday 1 June 2008

NFQueue bindings

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:

* example Perl script
* example Python script
* Packet dumper, in pcap format (use scapy)
* HTTP request checker
* A surprise I will present in a lightning talk at SSTIC :)

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

* libnetfilter_queue
* nfqueue-bindings project site
* nfqueue-bindings source (git browser)
* Get source: git clone http://git.inl.fr/git/nfqueue-bindings.git