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.

ConcernCloud security groupspf
Where the policy livesA console, several tabsOne file, in your repository
Readable end to endRarelyThat is the design goal
Evaluation modelGroups, NACLs, routes, interactingLast match wins, or quick
Change reviewAn IAM audit log, after the factA pull request, before the fact
Reload semanticsEventually consistentAtomic
Rate limiting and banningA separate paid serviceBuilt into the ruleset
PortabilityLocked to the providerRuns anywhere OpenBSD or FreeBSD does
CostPer rule, per endpoint, per hourFree
Ecosystem toolingEnormousModest — 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 nftables is 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.

Nästa steg

Tell us what you are running.
We will tell you what it should be.

A first conversation costs nothing and takes forty minutes. You will leave it with an honest opinion about your stack — including, occasionally, that you should change nothing at all.