Reject zone exclusions in conntrack entries
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package config
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ConntrackAction string
|
||||
|
||||
@@ -68,6 +71,9 @@ func (c *Config) validateConntrack() error {
|
||||
return fmt.Errorf("conntrack[%d]: helper name required for helper action", i)
|
||||
}
|
||||
|
||||
if HasZoneExclusion(ct.Source) || HasZoneExclusion(ct.Dest) {
|
||||
return fmt.Errorf("conntrack[%d]: zone exclusions are not supported in conntrack entries", i)
|
||||
}
|
||||
if err := c.validateZoneRef(ct.Source); err != nil {
|
||||
return fmt.Errorf("conntrack[%d]: source %w", i, err)
|
||||
}
|
||||
@@ -87,3 +93,9 @@ func (c *Config) validateConntrack() error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// HasZoneExclusion reports an all/any zone ref with a "+" or "!" modifier (all+, all!x, any+!x, ...).
|
||||
func HasZoneExclusion(spec string) bool {
|
||||
zones, _, _ := strings.Cut(spec, ":")
|
||||
return (strings.HasPrefix(zones, "all") || strings.HasPrefix(zones, "any")) && strings.ContainsAny(zones[3:], "+!")
|
||||
}
|
||||
|
||||
@@ -67,13 +67,38 @@ func TestValidateConntrack(t *testing.T) {
|
||||
wantErr: `dest zone "nte" not defined`,
|
||||
},
|
||||
{
|
||||
name: "unknown excluded zone",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Source: "all!nte"}},
|
||||
wantErr: `excluded zone "nte" not defined`,
|
||||
name: "all and plain zone forms are valid",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Source: "net,fw", Dest: "all:192.0.2.1"}},
|
||||
},
|
||||
{
|
||||
name: "exclusion and all forms are valid",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Source: "all!net", Dest: "all:192.0.2.1"}},
|
||||
name: "Source all!net rejected",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Source: "all!net"}},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "Dest all!net:192.0.2.1 rejected",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Dest: "all!net:192.0.2.1"}},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "Source all+ rejected",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Source: "all+"}},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "Dest all+!net rejected",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Dest: "all+!net"}},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "Source any!net rejected",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Source: "any!net"}},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "Dest any+ rejected",
|
||||
rules: []ConntrackRule{{Action: ConntrackNoTrack, Dest: "any+"}},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "helper without source/dest is valid",
|
||||
|
||||
@@ -216,6 +216,9 @@ func (c *Compiler) compileConntrack(state *FirewallState) error {
|
||||
fwZone := c.cfg.FirewallZone()
|
||||
for i, ct := range c.cfg.Conntrack {
|
||||
tag := fmt.Sprintf("conntrack:%d", i)
|
||||
if config.HasZoneExclusion(ct.Source) || config.HasZoneExclusion(ct.Dest) {
|
||||
return fmt.Errorf("conntrack[%d]: zone exclusions are not supported in conntrack entries", i)
|
||||
}
|
||||
srcs, dsts := c.zoneSpecs(ct.Source), c.zoneSpecs(ct.Dest)
|
||||
if len(srcs) == 0 {
|
||||
srcs = []config.ZoneSpec{{}}
|
||||
@@ -225,11 +228,6 @@ func (c *Compiler) compileConntrack(state *FirewallState) error {
|
||||
}
|
||||
|
||||
for _, src := range srcs {
|
||||
// raw_output only sees locally generated traffic, so it applies to an fw (or omitted) source only.
|
||||
if isZoneExclusion(ct.Source) && (ct.Chain == config.ConntrackPrerouting && src.Zone == fwZone ||
|
||||
ct.Chain == config.ConntrackOutput && src.Zone != fwZone) {
|
||||
continue
|
||||
}
|
||||
chains := []string{"raw_prerouting"}
|
||||
switch {
|
||||
case ct.Chain == config.ConntrackOutput && src.Zone != fwZone && src.Zone != "":
|
||||
|
||||
@@ -2517,14 +2517,34 @@ func TestCompile_ConntrackZones(t *testing.T) {
|
||||
want: map[string][]string{},
|
||||
},
|
||||
{
|
||||
name: "all!net expands to every other zone",
|
||||
ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "all!net", Dest: "fw:192.0.2.53"},
|
||||
want: map[string][]string{"raw_output": {"daddr=192.0.2.53"}, "raw_prerouting": {"iif=eth1 daddr=192.0.2.53"}},
|
||||
name: "all!net rejected",
|
||||
ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "all!net"},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "all!net in prerouting skips fw",
|
||||
ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "all!net", Dest: "fw", Chain: config.ConntrackPrerouting},
|
||||
want: map[string][]string{"raw_prerouting": {"iif=eth1"}},
|
||||
name: "all!net rejected",
|
||||
ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Dest: "all!net"},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "all+ rejected",
|
||||
ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "all+"},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "all+!net rejected",
|
||||
ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Dest: "all+!net"},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "any!net rejected",
|
||||
ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Source: "any!net"},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "any+ rejected",
|
||||
ct: config.ConntrackRule{Action: config.ConntrackNoTrack, Dest: "any+"},
|
||||
wantErr: "zone exclusions are not supported in conntrack entries",
|
||||
},
|
||||
{
|
||||
name: "omitted source and dest is global",
|
||||
|
||||
Reference in New Issue
Block a user