Go to file
Matt f4f0828066 Minor README format changes 2011-05-13 10:02:54 -07:00
.gitignore Various packaging updates and bugfixes 2011-05-12 14:08:37 -07:00
CHANGES.txt Add to CHANGES 2011-05-13 09:25:19 -07:00
LICENSE.txt Initial commit 2011-05-12 13:45:14 -07:00
MANIFEST.in Add MANIFEST.in 2011-05-12 14:10:15 -07:00
README.rst Minor README format changes 2011-05-13 10:02:54 -07:00
netfilterqueue.c Regenerated by Cython. 2011-05-13 09:48:29 -07:00
netfilterqueue.pxd Add API to README. 2011-05-13 09:23:17 -07:00
netfilterqueue.pyx Add API to README. 2011-05-13 09:23:17 -07:00
setup.py Update version to 0.2. 2011-05-13 09:26:13 -07:00

README.rst

==============
NetfilterQueue
==============

NetfilterQueue provides access to packets matched by an iptables rule in
Linux. Packets so matched can be accepted, dropped, altered, or given a mark.

Libnetfilter_queue (the netfilter library, not this module) is part of the
`Netfilter project <http://netfilter.org/projects/libnetfilter_queue/>`_.

Example
=======

The following script prints a short description of each packet before accepting
it. ::

    from netfilterqueue import QueueHandler
    
    class PacketPrinter(QueueHandler):
        def handle(self, packet):
            print packet
            packet.accept()
    
    p = PacketPrinter()
    p.bind(1)
    try:
        p.run()
    except KeyboardInterrupt:
        print

To send packets destined for your LAN to the script, type something like::

    iptables -I INPUT -d 192.168.0.0/24 -j NFQUEUE --queue-num 1

Installation
============

NetfilterQueue is a C extention module that links against libnetfilter_queue. 
Before installing, ensure you have:

1. A C compiler

2. Python development files

3. Libnetfilter_queue development files and associated dependencies

On Debian or Ubuntu, install these files with::

    sudo apt-get install build-essential python-dev libnetfilter-queue-dev

From PyPI
---------

To install from PyPI by pip::

    pip install NetfilterQueue

From source
-----------

To install from source::

    wget http://pypi.python.org/packages/source/N/NetfilterQueue/NetfilterQueue-0.2.tar.gz
    tar -xvzf NetfilterQueue-0.2.tar.gz
    cd NetfilterQueue-0.2
    python setup.py install

Setup will use Cython if it is installed, regenerating the .c source from the
.pyx before compiling the .so.

API
===

``NetfilterQueue.COPY_NONE``

``NetfilterQueue.COPY_META``

``NetfilterQueue.COPY_PACKET``
    These constants specify how much of the packet should be given to the
    script- nothing, metadata, or the whole packet.

QueueHandler objects
--------------------

You should define a class that inherits from QueueHandler and implenents the
handle() method. Handle() is called for each packet that appears in the queue.

``QueueHandler.bind(queue_num[, max_len[, mode[, range]]])``
    Create and bind to the queue. ``queue_num`` must match the number in your
    iptables rule. ``max_len`` sets the largest number of packets that can be
    in the queue; new packets are dropped if the size of the queue reaches this
    number. ``mode`` determines how much of the packet data is provided to
    your script. Use the constants above. ``range`` defines how many bytes of
    the packet you want to get. For example, if you only want the source and
    destination IPs of a IPv4 packet, ``range`` could be 20.

``QueueHandler.unbind()``
    Remove the queue. Packets matched by your iptables rule will be dropped.

``QueueHandler.run()``
    Begin accepting packets.

``QueueHandler.handle(packet)``
    Handle a single packet from the queue. You must call either
    ``packet.accept()`` or ``packet.drop()``. If you don't override this
    method, all packets will be accepted.

Packet objects
--------------

Objects of this type are passed to your handle() method.

``Packet.get_payload()``
    Return the packet's payload as a string.

``Packet.get_payload_len()``
    Return the size of the payload.

``Packet.set_mark(mark)``
    Give the packet a kernel mark. ``mark`` is a 32-bit number.

``Packet.accept()``
    Accept the packet.

``Packet.drop()``
    Drop the packet.

Usage
=====

To route packets to the queue::

    iptables -I <table or chain> <match specification> -j NFQUEUE --queue-num <queue number>
    
For example::

    iptables -I INPUT -d 192.168.0.0/24 -j NFQUEUE --queue-num 1
    
The only special part of the rule is the target. Rules can have any match and 
can be added to any table or chain.

Valid queue numbers are integers from 0 to 65,536 inclusive.

To view libnetfilter_queue stats, refer to /proc/net/netfilter/nfnetlink_queue::

    cat /proc/net/netfilter/nfnetlink_queue
    1  31621     0 2  4016     0     0        2  1

The fields are:

1. Queue ID

2. Bound process ID

3. Number of currently queued packets

4. Copy mode

5. Copy size

6. Number of packets dropped due to reaching max queue size

7. Number of packets dropped due to netlink socket failure

8. Total number of packets sent to queue

9. Libnetfilter_queue internal use

Limitations
===========

More details coming soon...

* Compiled with a 4096-byte buffer for packets, so it probably won't work on
  loopback or Ethernet with jumbo packets. If this is a problem, either lower
  MTU on your loopback, disable jumbo packets, or get Cython,
  change ``DEF BufferSize = 4096`` in ``netfilterqueue.pyx``, and rebuild.
* Full libnetfilter_queue API is not yet implemented:

    * Omits ``packet.set_payload()`` for altering packet data
    * Omits methods for getting information about the interface a packet has
      arrived on or is leaving on
    * Probably other stuff is omitted too
    
* When a packet has been marked, we use nfq_set_verdict_mark rather than
  nfq_set_verdict2. Apparently nfq_set_verdict_mark is 
  `broken <http://netfilter.org/projects/libnetfilter_queue/doxygen/group__Queue.html#ga1986d6387c5aa2a837c02e87ae3b45ff>`_,
  although it works for me.

Source
======

https://github.com/kti/python-netfilterqueue

License
=======

Copyright (c) 2011, Kerkhoff Technologies, Inc. All rights reserved.

`BSD <https://github.com/kti/python-netfilterqueue/blob/master/LICENSE.txt>`_
licensed.