Import: keep what rulesets mean, name zones as asked

Fixes from an audit of the importer, each of which could change what an
imported ruleset does: two base chains on one hook imported their rules
twice (and hoisted the second's built-ins), now in priority order with
the stricter policy; raw rules from a jumped-to chain lost the jump's
condition, now put in front; a jump and a rule matching one field are
combined only when one's addresses lie within the other's; a second
match on a field replaced the first, and != on hop limit and TCP flags
read as ==, now kept raw; a forward accept without ct status dnat no
longer folds into the port forward, nor an interface-limited IPv6
accept into an open pinhole; raw rules' set references are renamed
(NAME_v4/_v6) or written out, so nftables takes them; DNATs with
matches a forward can't hold are left out with a note.

Sets with flags timeout become dynamic sets; a DNAT of several ports one
forward per port. Zone names: --zone IFACE=NAME (and on the Import
page), VLAN defines, more suffixes, and a note on where each name came
from. testdata/audit.nft covers the cases, checked with nft 1.1.3.

make test and make e2e (246 checks) pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-20 08:43:42 +01:00
1 parent c17f5cd9f0
commit 47bae07d42
15 files changed
+823 -117

No files matched your search

+3
View File
@@ -198,6 +198,9 @@ type ImportInput struct {
// Replace replaces Housecarl's configuration; without it, the import
// is refused when there is one.
Replace bool `json:"replace,omitempty"`
// Zones names the zones by interface ({"enp2s0": "lan"}); interfaces
// given the same name share a zone.
Zones map[string]string `json:"zones,omitempty"`
}
// ImportResult reports an import.