1. Introduction

py-pf is a pure-Python module that allows you to manage OpenBSD's Packet Filter from Python scripts. Packet Filter is OpenBSD's firewalling subsystem, renowned for its performance and security and providing, among other features:

py-pf allows you to control all these functions from Python in a very simple and flexible way.

Well, you might object that OpenBSD already provides a powerful utility for controlling Packet Filter, pfctl(8), which covers the most commonly used functions. It's true, but nevertheless, py-pf aims to provide something different: a scripting tool that brings together the flexibility of Packet Filter's C API and the power of Python, making it easier to parse and manage PF data (such as addresses, rules, state tables) and to integrate firewalling capabilities in more complex applications.

Similarly to pfctl(8), py-pf sends commands to the kernel through the ioctl(2) interface provided by the pf(4) pseudo-device; this allows Python to natively communicate with the kernel, thanks to the fcntl and ctypes modules, with no need to write a specific C extension module.

py-pf is still under development, but already supports most of Packet Filter's functionalities, including:

OS fingerprint support will be added in the next future.

This document assumes that you are familiar with Packet Filter; if you are not, I would suggest that you first take a look at the official PF User's guide.

1.1 The pf module

py-pf is made up of a single module, pf, which provides a number of classes for controlling the behavior of OpenBSD's Packet Filter and managing PF data, such as rules, anchors, network addresses, and so on.

The pf module exports the following exception:

pf.PFError
This is a generic exception for PF-related errors; argument is a string describing what caused the error.