06 Module · Why pf
A firewall you can
read out loud.
The OpenBSD packet filter, where the ruleset is prose: macros give things your names, tables make a set of addresses a noun, and the whole policy can be read top to bottom by a human in one sitting.
- First released
- OpenBSD 3.0, 2001
- Project
- OpenBSD
- Ruleset reload
- Atomic
- Licence
- BSD
A good ruleset passes one test: a competent engineer who has never seen it can read it aloud in a meeting, and everyone in the room agrees on what it does.
That is a far higher bar than “it works”, and almost every long-lived firewall configuration fails it. We inherited one recently that had been appended to since 2011 — nine hundred lines, four authors, three of whom had left, and a comment on line 412 reading # temporary — remove after migration.
The problem was not competence. The configuration had simply stopped being a description of policy and become sediment: a record of every incident anyone had ever fixed under pressure.
pf is built for the higher bar. Its syntax is close enough to English that reading a rule out loud is literal rather than metaphorical, and its abstractions — macros, tables, anchors — let a ruleset stay the size of the policy rather than the size of the network.
Argumenten · The case
Seven reasons,
in order of how often they matter.
Ranked by what matters during an incident and during an audit, which is when a firewall configuration is actually read.
01 The syntax is legible
pass in on egress proto tcp to $web_servers port 443 means what it appears to mean. No vendor course, no object groups three levels deep, no guessing at implicit behaviour.
02 Macros and tables keep it short
The same eight addresses written longhand in thirty-one places becomes one macro. Rulesets shrink to the size of the policy, which is the only size a human can hold in their head.
03 Reloads are atomic
A new ruleset is validated and swapped in whole. There is no window during which half the old policy and half the new one are in force — a window that has embarrassed a great many people.
04 Evaluation order is one rule
Last match wins, unless a rule says quick. That is the entire model. Compare it to reasoning about the interaction of security groups, NACLs and a route table across three consoles.
05 Rules ship through code review
The config lives in the same repository as everything else and changes through pull requests. A rule with no author and no rationale does not survive review, which is what kills “temporary” rules from 2011.
06 Adaptive blocking is built in
State tracking with connection-rate limits and overload tables gives you brute-force protection in the firewall itself — no log-scraping daemon racing to react after the fact.
07 It comes from a project that means it
pf is OpenBSD's, and OpenBSD's entire reputation rests on auditing and conservative defaults. The documentation — the PF User's Guide — is genuinely worth reading end to end.
Jämförelse · Side by side
Against the alternatives
Compared with cloud security groups and with the Linux filtering stack, which are the two things it usually replaces.
| Concern | Cloud security groups | pf |
|---|---|---|
| Where the policy lives | A console, several tabs | One file, in your repository |
| Readable end to end | Rarely | That is the design goal |
| Evaluation model | Groups, NACLs, routes, interacting | Last match wins, or quick |
| Change review | An IAM audit log, after the fact | A pull request, before the fact |
| Reload semantics | Eventually consistent | Atomic |
| Rate limiting and banning | A separate paid service | Built into the ruleset |
| Portability | Locked to the provider | Runs anywhere OpenBSD or FreeBSD does |
| Cost | Per rule, per endpoint, per hour | Free |
| Ecosystem tooling | Enormous | Modest — the honest disadvantage |
Ärligt talat · Honestly
When pf is the wrong answer.
pf is a packet filter, not a security programme, and choosing it has a real operational cost that we would rather name in advance.
- It means running BSD at the edge. pf is OpenBSD's, with a FreeBSD port. If your team runs Linux exclusively and has no appetite for a second operating system, that is a legitimate objection — and
nftablesis a reasonable Linux answer with much of the same spirit. - It is layer 3 and 4. No deep packet inspection, no TLS interception, no application-aware policy. Where a regulator demands those, pf is one component of the answer rather than the whole of it.
- The tooling ecosystem is modest. Fewer dashboards, fewer integrations, fewer people who have seen it before. You gain legibility and lose a large commercial support surface.
- Inside a hyperscaler it is redundant. If the estate stays on a cloud provider, its native filtering is already in the packet path and adding pf mostly adds a second place to look.
- Somebody has to own the edge. A physical or virtual firewall is a machine that needs patching, monitoring and a failover story. That is exactly the work a managed appliance was sold to remove.
The case is strongest for organisations running their own edge — colo, dedicated servers, a European provider, multiple sites — where the ruleset will outlive the people who wrote it and will eventually be read by an auditor.
Further reading, and the best firewall documentation we know of: the OpenBSD PF User's Guide.