From 337490d9959deba63f96c3b944c8158ca4cec971 Mon Sep 17 00:00:00 2001 From: unkin-agent Date: Sat, 3 Oct 2026 23:01:29 +1000 Subject: [PATCH] Reject fw source on prerouting conntrack and pin global omitted-zone entries --- internal/nftables/compiler.go | 2 ++ internal/nftables/compiler_test.go | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/internal/nftables/compiler.go b/internal/nftables/compiler.go index 660c872..c8170e1 100644 --- a/internal/nftables/compiler.go +++ b/internal/nftables/compiler.go @@ -230,6 +230,8 @@ func (c *Compiler) compileConntrack(state *FirewallState) error { switch { case ct.Chain == config.ConntrackOutput && src.Zone != fwZone && src.Zone != "": return fmt.Errorf("conntrack[%d]: chain output needs SOURCE %s, got %q", i, fwZone, src.Zone) + case ct.Chain == config.ConntrackPrerouting && src.Zone == fwZone: + return fmt.Errorf("conntrack[%d]: SOURCE %s cannot use chain prerouting", i, fwZone) case ct.Chain != config.ConntrackPrerouting && src.Zone == fwZone, ct.Chain == config.ConntrackOutput: chains = []string{"raw_output"} case ct.Chain == config.ConntrackBoth && src.Zone == "": diff --git a/internal/nftables/compiler_test.go b/internal/nftables/compiler_test.go index 7a2cb6f..6ba6086 100644 --- a/internal/nftables/compiler_test.go +++ b/internal/nftables/compiler_test.go @@ -2462,6 +2462,16 @@ func TestCompile_ConntrackZones(t *testing.T) { ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Dest: "fw", Chain: config.ConntrackOutput}, wantErr: "chain output needs SOURCE fw", }, + { + name: "chain prerouting with fw source is rejected", + ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "fw", Dest: "net", Chain: config.ConntrackPrerouting}, + wantErr: "SOURCE fw cannot use chain prerouting", + }, + { + name: "omitted source and dest is global in both chains", + ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Proto: "udp", DPort: config.PortSpec{"53"}, Chain: config.ConntrackBoth}, + want: map[string][]string{"raw_prerouting": {""}, "raw_output": {""}}, + }, { name: "chain both with non-fw source emits prerouting only", ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Dest: "fw", Proto: "udp", DPort: config.PortSpec{"53"}, Chain: config.ConntrackBoth},