python-netfilterqueue/README.rst

245 lines
6.8 KiB
ReStructuredText
Raw Normal View History

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.
2011-05-13 19:02:54 +02:00
Libnetfilter_queue (the netfilter library, not this module) is part of the
`Netfilter project <http://netfilter.org/projects/libnetfilter_queue/>`_.
2011-05-12 22:45:14 +02:00
Example
=======
2011-05-13 19:02:54 +02:00
The following script prints a short description of each packet before accepting
it. ::
2011-05-13 17:42:05 +02:00
from netfilterqueue import NetfilterQueue
2011-05-13 17:42:05 +02:00
def print_and_accept(pkt):
2016-06-28 04:59:57 +02:00
print(pkt)
pkt.accept()
2011-05-13 17:42:05 +02:00
nfqueue = NetfilterQueue()
nfqueue.bind(1, print_and_accept)
2011-05-13 18:23:17 +02:00
try:
nfqueue.run()
2011-05-13 18:23:17 +02:00
except KeyboardInterrupt:
print('')
2016-06-28 05:03:55 +02:00
nfqueue.unbind()
2011-05-13 18:23:17 +02:00
You can also make your own socket so that it can be used with gevent, for example. ::
from netfilterqueue import NetfilterQueue
import socket
def print_and_accept(pkt):
print(pkt)
pkt.accept()
nfqueue = NetfilterQueue()
nfqueue.bind(1, print_and_accept)
s = socket.fromfd(nfqueue.get_fd(), socket.AF_UNIX, socket.SOCK_STREAM)
try:
nfqueue.run_socket(s)
except KeyboardInterrupt:
print('')
s.close()
nfqueue.unbind()
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
============
2011-05-13 19:02:54 +02:00
NetfilterQueue is a C extention module that links against libnetfilter_queue.
Before installing, ensure you have:
2011-05-12 22:45:14 +02:00
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
apt-get install build-essential python-dev libnetfilter-queue-dev
2011-05-12 22:45:14 +02:00
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::
wget https://pypi.python.org/packages/94/5b/83d10952c1312fe056f8f2f524a4a59fdc9d56b84a67cae1ed779e2da50b/NetfilterQueue-0.8.tar.gz#md5=8e78db992ad3a73dd86fef05293fff65
tar -xvzf NetfilterQueue-0.8.tar.gz
cd NetfilterQueue-0.8
2011-05-12 22:45:14 +02:00
python setup.py install
If Cython is installed, Distutils will use it to regenerate the .c source from the .pyx. It will then compile the .c into a .so.
2011-05-12 22:45:14 +02:00
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``
2011-05-13 19:02:54 +02:00
These constants specify how much of the packet should be given to the
script- nothing, metadata, or the whole packet.
2011-05-13 18:23:17 +02:00
NetfilterQueue objects
----------------------
2011-05-13 18:23:17 +02:00
A NetfilterQueue object represents a single queue. Configure your queue with
a call to ``bind``, then start receiving packets with a call to ``run``.
2011-05-13 18:23:17 +02:00
``QueueHandler.bind(queue_num, callback[, max_len[, mode[, range, [sock_len]]]])``
2011-05-13 18:23:17 +02:00
Create and bind to the queue. ``queue_num`` must match the number in your
iptables rule. ``callback`` is a function or method that takes one
argument, a Packet object (see below). ``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.
``sock_len`` sets the receive socket buffer size.
2011-05-13 18:23:17 +02:00
``QueueHandler.unbind()``
Remove the queue. Packets matched by your iptables rule will be dropped.
``QueueHandler.get_fd()``
Get the file descriptor of the queue handler.
``QueueHandler.run([block])``
Send packets to your callback. By default, this method blocks. Set
2016-06-28 06:18:34 +02:00
block=False to let your thread continue. You can get the file descriptor
of the socket with the ``get_fd`` method.
2011-05-13 18:23:17 +02:00
``QueueHandler.run_socket(socket)``
Send packets to your callback, but use the supplied socket instead of
recv, so that, for example, gevent can monkeypatch it. You can make a
socket with ``socket.fromfd(nfqueue.get_fd(), socket.AF_UNIX, socket.SOCK_STREAM)``
and optionally make it non-blocking with ``socket.setblocking(False)``.
2011-05-13 18:23:17 +02:00
Packet objects
--------------
Objects of this type are passed to your callback.
2011-05-13 18:23:17 +02:00
``Packet.get_payload()``
Return the packet's payload as a string (Python 2) or bytes (Python 3).
2011-05-13 18:23:17 +02:00
2016-06-28 04:59:57 +02:00
``Packet.set_payload(payload)``
Set the packet payload. ``payload`` is a bytes.
2016-06-28 04:59:57 +02:00
2011-05-13 18:23:17 +02:00
``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.
2016-06-28 04:59:57 +02:00
``Packet.get_mark()``
Get the mark already on the packet.
``Packet.get_hw()``
Return the hardware address as a Python string.
2011-05-13 18:23:17 +02:00
``Packet.accept()``
Accept the packet.
``Packet.drop()``
Drop the packet.
2016-06-28 04:59:57 +02:00
``Packet.repeat()``
Iterate the same cycle once more.
Callback objects
----------------
Your callback can be function or a method and must accept one argument, a
Packet object. You must call either Packet.accept() or Packet.drop() before
returning.
``callback(packet)`` or ``callback(self, packet)``
Handle a single packet from the queue. You must call either
``packet.accept()`` or ``packet.drop()``.
2011-05-13 17:42:05 +02:00
2011-05-12 22:45:14 +02:00
Usage
=====
To send 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,535 inclusive.
2011-05-12 22:45:14 +02:00
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. Something for libnetfilter_queue's internal use
2011-05-13 17:42:05 +02:00
2011-05-12 22:45:14 +02:00
Limitations
===========
* 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 methods for getting information about the interface a packet has
arrived on or is leaving on
* Probably other stuff is omitted too
Source
======
https://github.com/kti/python-netfilterqueue
License
=======
Copyright (c) 2011, Kerkhoff Technologies, Inc.
2011-05-12 22:45:14 +02:00
`MIT licensed <https://github.com/kti/python-netfilterqueue/blob/master/LICENSE.txt>`_
2011-05-12 22:45:14 +02:00