ryancdotorg / python-nflogr

An object-oriented Python interface to read data via NFLOG

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

What is Nflogr?

Nflogr is a Python extension module that allows access to messages and packet data logged via iptables/netfilter using NFLOG on Linux. There are other existing libraries that provide similar functionality. Nflogr offers the following improvements:

  • Works with Python threads.
  • Provides a simple object oriented API.

Getting Nflogr

Nflogr is available from https://github.com/ryancdotorg/python-nflogr.

Setup

Disclaimer

This is my first Python extension module, and I consider it ‘beta quality’. It may crash, contain exploitable security vulnerabilities, be unpythonic, etc. There aren’t currently any tests, though infrastructure to add them is in place.

Code review and/or patches to fix bugs would be appreciated.

Quick Start

git clone https://github.com/ryancdotorg/python-nflogr
cd python-nflogr
python3 setup.py install

Requirements

  • Python 3.6 or later, including header files.
  • The Python distutils and setuptools packages.
  • A C++ compiler. GCC G++ 8.3.0 is known to work.
  • Development versions of libnfnetlink and libnetfilter_log.

On Debian/Ubuntu, try:

sudo apt install libnetfilter-log-dev build-essential 
sudo apt install python3-{distutils,setuptools,dev}

Usage

Open an NFLOG group handler

NOTE: Either root or cap_net_admin is required to open the handler.

import nflogr

group_id = 123
nflog = nflogr.open(group_id)
"""
your code here
"""
nflog.close()

or

import nflogr

group_id = 123
with nflog as nflogr.open(group_id):
    """
    your code here
    """

Optional keyword arguments for the open() function

The open() function accepts the following optional keyword arguments:

timeout (float, default 0)

The maximum time that nflog waits until it pushes the log buffer to userspace if no new logged packets have occurred.

Specified in seconds with 0.01 granularity.

qthresh (int, default 1)

The maximum number of log entries in the buffer until it is pushed to userspace.

rcvbuf (int, default 0)

The maximum size (in bytes) of the receiving socket buffer. Large values may be needed to avoid dropping packets.

If set to 0, the system default value will be used.

nlbuf (int, default 0)

The size (in bytes) of the buffer that is used to stack log messages in nflog.

If set to 0, the kernel default (one memory page) will be used.

NOTE: Changing this from the default is strongly discouraged.

enobufs (int, default nflogr.ENOBUFS_RAISE)

Control what happens when recv() fails with ENOBUFS due to dropped packets.

  • nflogr.ENOBUFS_RAISE - raise an nflogr.NflogDroppedError exception
  • nflogr.ENOBUFS_HANDLE - increment the enbufs counter
  • nflogr.ENOBUFS_DISABLE - disable ENOBUFS errors entirely
copymode (int, default nflogr.COPY_PACKET)

The amount of data to be copied to userspace for each packet.

  • nflogr.COPY_NONE - do not copy any data
  • nflogr.COPY_META - copy only packet metadata
  • nflogr.COPY_PACKET - copy entire packet

Nflog objects

Nflog objects encapsulate NFLOG group handlers. They have the following attributes:

Name Description
rcvbuf Maximum size of the socket receive buffer in bytes. (int)
drops Number of times ENOBUFS has been received on the socket (int, can only be set to zero)
queued Number of messages received from the socket but not yet read by the application (int, read-only)

Functions available on the handler

nflog.queue(wait=True)

Reads messages from the socket, and queues them internally. Returns the number of messages queued (which may be zero), or -1 on error. If wait is set to False, the call will be non-blocking.

nflog.next(wait=True)

Returns the next message (NflogData). If wait is set to False, the call will be non-blocking, and None will be returned if no messages are available.

nflog.loop(fn, count=-1)

Passes messages (NflogData) to a callback function. The optional second argument specifies a maximum number of messages to handle before returning, with -1 meaning 'infinite'. Returns None.

nflog.close()

Closes the handler.

NOTE: Nflogr buffers packets, so reads continue to succeed.

nflog.getfd()

Returns the numeric file descriptor (int), or None if not applicable.

nflog.getgroup()

Returns the numeric log group id (int), or None if not applicable.

NflogData objects

Message handling functions provide NflogData objects, which have the following read-only attributes:

Name Description
proto Layer 3 protocol (EtherType) of the packet (int)
hwtype Hardware type identifier (int, see if_arp.h)
nfmark Netfilter packet mark value (int)
timestamp Timestamp of when the packet was logged (float)
indev Name of the logical interface the packet was received on (str), or None if not known/applicable
physindev Name of the physical interface the packet was received on (str), or None if not known/applicable
outdev Name of the logical interface the packet will be sent on (str), or None if not known/applicable
physoutdev Name of the physical interface the packet will be sent on (str), or None if not known/applicable
uid Numeric user id of the user that generated the packet (int), or None if not known/applicable
gid Numeric group id of the user that generated the packet (int), or None if not known/applicable
hwaddr Layer 2 source address (bytes)
hwhdr Layer 2 packet header (bytes)
payload Layer 3 packet data (bytes)
prefix String prefix specified in iptables’ NFLOG target (str)

NflogData is iterable, so dict(data) will work as expected.

Process messages from a handler

for data in nflog:
    """
    your code here
    """

or

while True:
    data = nflog.next()
    """
    your code here
    """

Process messages from a handler using a callback function

def nflog_callback(data):
    """
    your code here
    """

nflog.loop(nflog_callback)

License

This software is MIT licensed. See the LICENSE file for details.

About

An object-oriented Python interface to read data via NFLOG

License:MIT License


Languages

Language:C++ 85.2%Language:Python 11.8%Language:C 3.0%