Skip to content

Add firewallv3 module#77

Open
m-hau wants to merge 2 commits intoZPESystems:mainfrom
m-hau:feature/firewallv3
Open

Add firewallv3 module#77
m-hau wants to merge 2 commits intoZPESystems:mainfrom
m-hau:feature/firewallv3

Conversation

@m-hau
Copy link
Copy Markdown

@m-hau m-hau commented Aug 11, 2025

Spiritual successor to firewall (v1), allowing (almost) atomic chain/ rule creation/update/deletion in the ipv4/ipv6 nat/firewall tables. It does a diff between the current and defined/desired ruleset, and executes nodegrid cli commands to transition from former to later. This is done as atomically as possible, to reduce the possibility for an error to leave the device's firewall in a half-configured/-updated state, leaving it potentially vulnerable or unreachable.

Updates and Deletions are straight forward: queue them using set and delete commands, and then apply them all in one go with a single commit command. Additions are more complicated because the required add command starts edit-mode, and the save command to leave it will always implicitly do a commit. To make this work, first create all required new objects as no-ops so even when committed they do not change the effective behaviour. For chains that is easy, because new chains (and any new rules in it) can't be referenced by the current ruleset yet. Rules need to be numbered gap-less increasing from zero, so new rules can only be appended at the end of a chain; never inserted in the middle. Instead of creating the new no-op rules using some impossible-to-match conditions, use the RETURN target to exit the chain, as it would do without the no-op rule present anyway. The actual rule contents will then be applied in one go together with all the other updates and deletions. And even of that fails for some reason, the created and committed no-op chains/rules don't change the previous behaviour of the firewall ruleset.

Config transactions allow an automatic rollback after 30s if not confirmed, for example when the device becomes unreachable due to a flawed firewall ruleset. But that timeout is fixed, and depending on the amount of changes/commands could be too short. Since the rollback will be to the last committed state and thus also revert any queued changes, only the final commit command needs to be in the config transaction. Should a rollback be triggered, it will revert all updates and deletions but keep the already-committed no-op additions.

The actual atomicity of the whole process depends solely on how atomic the commit implementation in the nodegrid cli is. But no matter how good it is, iptable updates can by design never be fully atomic; one of the many advantages of nftables, where full/true atomicity is possible.

This should still be considered PoC quality, requiring further review.

@zpe-reneneumann zpe-reneneumann marked this pull request as ready for review September 14, 2025 14:31
Spiritual successor to firewall (v1), allowing (almost) atomic chain/
rule creation/update/deletion in the ipv4/ipv6 nat/firewall tables. It
does a diff between the current and defined/desired ruleset, and
executes nodegrid cli commands to transition from former to later. This
is done as atomically as possible, to reduce the possibility for an
error to leave the device's firewall in a half-configured/-updated
state, leaving it potentially vulnerable or unreachable.

Updates and Deletions are straight forward: queue them using `set` and
`delete` commands, and then apply them all in one go with a single
`commit` command. Additions are more complicated because the required
`add` command starts edit-mode, and the `save` command to leave it will
always implicitly do a commit. To make this work, first create all
required new objects as no-ops so even when committed they do not
change the effective behaviour. For chains that is easy, because new
chains (and any new rules in it) can't be referenced by the current
ruleset yet. Rules need to be numbered gap-less increasing from zero,
so new rules can only be appended at the end of a chain; never inserted
in the middle. Instead of creating the new no-op rules using some
impossible-to-match conditions, use the `RETURN` target to exit the
chain, as it would do without the no-op rule present anyway. The actual
rule contents will then be applied in one go together with all the
other updates and deletions. And even of that fails for some reason,
the created and committed no-op chains/rules don't change the previous
behaviour of the firewall ruleset.

Config transactions allow an automatic rollback after 30s if not
confirmed, for example when the device becomes unreachable due to a
flawed firewall ruleset. But that timeout is fixed, and depending on
the amount of changes/commands could be too short. Since the rollback
will be to the last committed state and thus also revert any queued
changes, only the final `commit` command needs to be in the config
transaction. Should a rollback be triggered, it will revert all updates
and deletions but keep the already-committed no-op additions.

The actual atomicity of the whole process depends solely on how atomic
the commit implementation in the nodegrid cli is. But no matter how
good it is, iptable updates can by design never be fully atomic; one of
the many advantages of nftables, where full/true atomicity is possible.

This should still be considered PoC quality, requiring further review.
@m-hau m-hau force-pushed the feature/firewallv3 branch from f36b43b to c9a9e51 Compare January 7, 2026 10:23
For some reason from v6.0.35 onward you can't set `target=LOG` and
`log_level` in one `set` statement anymore. You have to now first
`set target=LOG` and only then can `set loglevel=…`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants