Networks

A firewall you can read out loud

We judge a ruleset by whether a new engineer can read it aloud in a meeting and have everyone agree on what it does.

We inherited a firewall configuration last spring that had been appended to since 2011. Nine hundred lines. Four authors, three of whom had left. A comment on line 412 that read # temporary — remove after migration.

Nobody could say what it did. Over the years the configuration had stopped describing a policy and turned into layers of sediment.

The test

A good ruleset passes one test: a competent engineer who has never seen it can read it out loud in a meeting, and everyone in the room agrees on what it does. That is a higher bar than “it works”, and almost every long-lived configuration fails it.

The OpenBSD packet filter makes that bar reachable. Macros let the rules use your own names for things, tables let you refer to a set of addresses by one name, and anchors let you reason about a section on its own. The syntax is close enough to English that you can literally read it aloud:

web_servers = "{ 10.44.0.10, 10.44.0.11 }"
table <admins> persist file "/etc/pf/admins"

block all
pass in on egress proto tcp to $web_servers port { 80 443 }
pass in on wg0 proto tcp from <admins> to any port 22

That is the whole thing. You do not need a vendor course to follow it, and there is no guessing about evaluation order: in pf the last matching rule wins, and quick marks the exceptions explicitly.

Rules are code

The second half of the fix is procedural. The ruleset lives in the same repository as everything else, changes through pull requests, and is reviewed by a person who has to approve the diff.

That alone gets rid of “temporary” rules like the one from 2011. A rule with no author and no rationale does not survive review, and the diff shows the gap between what you meant and what you typed before it reaches production, instead of during an audit.

What it came to

Nine hundred lines became a hundred and forty. Roughly two hundred of the originals were dead: hosts that no longer existed, and ports for a service decommissioned in 2017. Most of the rest collapsed into tables and macros, because the same eight addresses had been written out longhand in thirty-one places.

The new engineer read it through on their first morning.

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 our opinion of your stack, which is occasionally that you should change nothing at all.