06 Module · Why pf
A firewall you can
read out loud.
The OpenBSD packet filter. Macros let you give things your own names, tables group a set of addresses under one name, and a whole policy can be read top to bottom 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 much higher bar than “it works”, and almost every long-lived firewall configuration fails it. We recently inherited one 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 authors were competent. Over the years the configuration had stopped describing a policy and turned into sediment, a record of every incident anyone had fixed under pressure.
pf is designed to meet that bar. Its syntax is close enough to English that you can read a rule aloud as written, and its abstractions (macros, tables and anchors) keep a ruleset proportional to the policy rather than to 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 people read a firewall configuration.
01 The syntax is legible
pass in on egress proto tcp to $web_servers port 443 means what it appears to mean. You do not need a vendor course, object groups nested three levels deep or guesswork about implicit behaviour.
02 Macros and tables keep it short
Eight addresses written out longhand in thirty-one places become one macro. The ruleset shrinks to the size of the policy, which is small enough for a person to keep in their head.
03 Reloads are atomic
pf validates a new ruleset and swaps it in as a whole, so parts of the old and new policies are never in force at the same time. Plenty of people have been caught out by firewalls where they can be.
04 Evaluation order is one rule
Last match wins, unless a rule says quick, and that is the whole model. Compare that with working out how security groups, NACLs and a route table interact 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 get through review, which is how “temporary” rules from 2011 get removed.
06 Adaptive blocking is built in
State tracking with connection-rate limits and overload tables gives you brute-force protection in the firewall itself, without a log-scraping daemon reacting after the fact.
07 It comes from OpenBSD
pf is part of OpenBSD, a project whose reputation rests on code auditing and conservative defaults. Its documentation, the PF User's Guide, is worth reading in full.
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 | Yes, by design |
| 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, which is the downside |
Nackdelar · The downsides
When pf is the wrong answer.
pf is a packet filter, not a security programme, and choosing it has operational costs that we prefer to list up front.
- It means running BSD at the edge. pf comes from OpenBSD and has a FreeBSD port. If your team runs only Linux and does not want a second operating system, that is a fair objection, and
nftablesis a reasonable Linux alternative with a similar approach. - It works at layers 3 and 4, with no deep packet inspection, TLS interception or application-aware policy. Where a regulator requires those, pf can only be one part of the answer.
- The tooling around it is modest. There are fewer dashboards and integrations, and fewer people who have used it before. You gain legibility and give up a large commercial support market.
- Inside a hyperscaler it is redundant. If the estate stays on a cloud provider, the provider's own filtering is already in the packet path, and 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 plan, which is the work a managed appliance was sold to remove.
pf suits organisations that run their own edge (colo, dedicated servers, a European provider, multiple sites), where the ruleset will outlive the people who wrote it and an auditor will eventually read it.
Further reading: the OpenBSD PF User's Guide.