2011-05-12 22:45:14 +02:00
|
|
|
==============
|
|
|
|
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
|
|
|
|
=======
|
|
|
|
|
2011-05-13 18:23:17 +02:00
|
|
|
The following script prints a short description of each packet before accepting it. ::
|
2011-05-13 17:42:05 +02:00
|
|
|
|
2011-05-13 18:23:17 +02:00
|
|
|
from netfilterqueue import QueueHandler
|
2011-05-13 17:42:05 +02:00
|
|
|
|
2011-05-13 18:23:17 +02:00
|
|
|
class PacketPrinter(QueueHandler):
|
2011-05-13 17:42:05 +02:00
|
|
|
def handle(self, packet):
|
|
|
|
print packet
|
|
|
|
packet.accept()
|
|
|
|
|
|
|
|
p = PacketPrinter()
|
|
|
|
p.bind(1)
|
2011-05-13 18:23:17 +02:00
|
|
|
try:
|
|
|
|
p.run()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
print
|
|
|
|
|
2011-05-13 17:42:05 +02:00
|
|
|
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
|
2011-05-12 22:45:14 +02:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2011-05-13 18:23:17 +02:00
|
|
|
On Debian or Ubuntu, install these files with::
|
2011-05-12 22:45:14 +02:00
|
|
|
|
|
|
|
sudo apt-get install build-essential python-dev libnetfilter-queue-dev
|
|
|
|
|
|
|
|
From PyPI
|
|
|
|
---------
|
|
|
|
|
|
|
|
To install from PyPI by pip::
|
|
|
|
|
2011-05-12 23:08:37 +02:00
|
|
|
pip install NetfilterQueue
|
2011-05-12 22:45:14 +02:00
|
|
|
|
|
|
|
From source
|
|
|
|
-----------
|
|
|
|
|
|
|
|
To install from source::
|
|
|
|
|
2011-05-13 18:23:17 +02:00
|
|
|
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
|
2011-05-12 22:45:14 +02:00
|
|
|
python setup.py install
|
|
|
|
|
|
|
|
Setup will use Cython if it is installed, regenerating the .c source from the .pyx before compiling the .so.
|
|
|
|
|
2011-05-13 17:42:05 +02:00
|
|
|
API
|
|
|
|
===
|
|
|
|
|
2011-05-13 18:23:17 +02:00
|
|
|
``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()``.
|
|
|
|
|
|
|
|
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.
|
2011-05-13 17:42:05 +02:00
|
|
|
|
2011-05-12 22:45:14 +02:00
|
|
|
Usage
|
|
|
|
=====
|
|
|
|
|
2011-05-13 17:42:05 +02:00
|
|
|
To route packets to the queue::
|
2011-05-12 22:45:14 +02:00
|
|
|
|
2011-05-13 17:42:05 +02:00
|
|
|
iptables -I <table or chain> <match specification> -j NFQUEUE --queue-num <queue number>
|
|
|
|
|
|
|
|
For example::
|
2011-05-12 22:45:14 +02:00
|
|
|
|
2011-05-13 17:42:05 +02:00
|
|
|
iptables -I INPUT -d 192.168.0.0/24 -j NFQUEUE --queue-num 1
|
2011-05-12 22:45:14 +02:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
2011-05-13 17:42:05 +02:00
|
|
|
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
|
|
|
|
|
2011-05-12 22:45:14 +02:00
|
|
|
Limitations
|
|
|
|
===========
|
|
|
|
|
2011-05-13 18:48:03 +02:00
|
|
|
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
|
|
|
|
=======
|
|
|
|
|
2011-05-13 18:51:29 +02:00
|
|
|
Copyright (c) 2011, Kerkhoff Technologies, Inc. All rights reserved.
|
2011-05-12 22:45:14 +02:00
|
|
|
|
2011-05-13 18:51:29 +02:00
|
|
|
`BSD <https://github.com/kti/python-netfilterqueue/blob/master/LICENSE.txt>`_ licensed.
|