diff --git a/internal/nftables/compiler.go b/internal/nftables/compiler.go index ed90cd5..4f3f430 100644 --- a/internal/nftables/compiler.go +++ b/internal/nftables/compiler.go @@ -264,7 +264,7 @@ func (c *Compiler) compileConntrackPair(state *FirewallState, tag, chain string, if ct.Action == config.ConntrackHelper { return nil } - if z, ok := c.cfg.Zones[dstZone]; ok && z.Type != config.ZoneFirewall && chain == "raw_prerouting" && + if _, ok := c.cfg.Zones[dstZone]; ok && chain == "raw_prerouting" && (dstAddr == "" || strings.HasPrefix(dstAddr, "!")) { return fmt.Errorf("conntrack DEST zone %q needs an address in prerouting", dstZone) } diff --git a/internal/nftables/compiler_test.go b/internal/nftables/compiler_test.go index 04bb4f3..d0eae9b 100644 --- a/internal/nftables/compiler_test.go +++ b/internal/nftables/compiler_test.go @@ -583,7 +583,7 @@ func TestCompile_ConntrackNoTrack(t *testing.T) { { Action: config.ConntrackNoTrack, Source: "net", - Dest: "fw", + Dest: "fw:192.0.2.1", Proto: "udp", DPort: config.PortSpec{"53"}, }, @@ -2433,7 +2433,7 @@ func TestCompile_ConntrackZones(t *testing.T) { }{ { name: "source zone matches iif", - ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Dest: "fw", Proto: "udp", DPort: config.PortSpec{"53"}}, + ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Proto: "udp", DPort: config.PortSpec{"53"}}, want: map[string][]string{"raw_prerouting": {"iif=eth0"}}, }, { @@ -2453,7 +2453,7 @@ func TestCompile_ConntrackZones(t *testing.T) { }, { name: "interface-less zone fails closed", - ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "dmz", Dest: "fw"}, + ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "dmz"}, want: map[string][]string{}, }, { @@ -2498,7 +2498,7 @@ func TestCompile_ConntrackZones(t *testing.T) { }, { 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}, + ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Proto: "udp", DPort: config.PortSpec{"53"}, Chain: config.ConntrackBoth}, want: map[string][]string{"raw_prerouting": {"iif=eth0"}}, }, { @@ -2508,12 +2508,12 @@ func TestCompile_ConntrackZones(t *testing.T) { }, { name: "negated addresses stay one AND-ed match", - ct: config.ConntrackRule{Action: config.ConntrackDrop, Source: "net:!192.0.2.1,198.51.100.1", Dest: "fw"}, + ct: config.ConntrackRule{Action: config.ConntrackDrop, Source: "net:!192.0.2.1,198.51.100.1"}, want: map[string][]string{"raw_prerouting": {"iif=eth0 !saddr=192.0.2.1 !saddr=198.51.100.1"}}, }, { name: "sport", - ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Dest: "fw", Proto: "udp", SPort: config.PortSpec{"123"}}, + ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Proto: "udp", SPort: config.PortSpec{"123"}}, want: map[string][]string{"raw_prerouting": {"iif=eth0 sport=123"}}, }, { @@ -2521,9 +2521,19 @@ func TestCompile_ConntrackZones(t *testing.T) { ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Dest: "lan"}, wantErr: `conntrack DEST zone "lan" needs an address in prerouting`, }, + { + name: "fw dest zone without address is rejected in prerouting", + ct: config.ConntrackRule{Action: config.ConntrackDrop, Source: "net", Dest: "fw"}, + wantErr: `conntrack DEST zone "fw" needs an address in prerouting`, + }, + { + name: "fw dest zone with address matches daddr", + ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "net", Dest: "fw:192.0.2.1"}, + want: map[string][]string{"raw_prerouting": {"iif=eth0 daddr=192.0.2.1"}}, + }, { name: "unknown zone fails closed", - ct: config.ConntrackRule{Action: config.ConntrackDrop, Source: "nte", Dest: "fw"}, + ct: config.ConntrackRule{Action: config.ConntrackDrop, Source: "nte"}, want: map[string][]string{}, }, { diff --git a/tomswall.example.yaml b/tomswall.example.yaml index 452f0d1..bc3e3b8 100644 --- a/tomswall.example.yaml +++ b/tomswall.example.yaml @@ -191,7 +191,7 @@ snat: # conntrack: # - action: notrack # source: net -# dest: fw +# dest: fw:203.0.113.1 # proto: udp # dport: [53] # comment: "Skip conntrack for DNS"