Match dest zone oif on output-chain rules and policies
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful

This commit is contained in:
2026-10-03 22:15:24 +10:00
parent 78afe7c242
commit b5be665902
2 changed files with 24 additions and 3 deletions
+2 -2
View File
@@ -599,7 +599,7 @@ func (c *Compiler) compilePolicies(state *FirewallState) error {
if si != "" {
exprs = append(exprs, matchIfaceName(true, si)...)
}
if di != "" && chain == "forward" {
if di != "" && chain != "input" {
exprs = append(exprs, matchIfaceName(false, di)...)
}
@@ -997,7 +997,7 @@ func (c *Compiler) buildMatchExprs(srcIface, dstIface, chain, proto string, dpor
if srcIface != "" {
exprs = append(exprs, matchIfaceName(true, srcIface)...)
}
if dstIface != "" && chain == "forward" {
if dstIface != "" && chain != "input" {
exprs = append(exprs, matchIfaceName(false, dstIface)...)
}
+22 -1
View File
@@ -1757,6 +1757,17 @@ func TestCompile_PortAndProtoLists(t *testing.T) {
})
}
}
func TestCompile_OutputPolicyMatchesOif(t *testing.T) {
cfg := listCfg(func(c *config.Config) {
c.Zones["lan"] = config.Zone{Type: config.ZoneIP}
c.Interfaces = append(c.Interfaces, config.Interface{Zone: "lan", Interface: "eth1"})
c.Policy = []config.Policy{{Source: "fw", Dest: "lan", Action: config.PolicyAccept}}
})
got := taggedRules(mustCompile(t, cfg), "output", "policy:0")
if len(got) != 1 || describeRule(got[0]) != "oif=eth1" {
t.Fatalf("fw->lan policy = %v, want one rule oif=eth1", got)
}
}
// describeRule renders a rule's iif/oif/saddr/daddr matches, e.g. "iif=eth1 oif=eth2 daddr=192.0.2.1".
func describeRule(r ManagedRule) string {
@@ -1803,7 +1814,7 @@ func TestCompile_CommaZoneLists(t *testing.T) {
{
name: "fw in source list goes to output",
rule: config.Rule{Action: config.RuleAccept, Source: "fw,lan", Dest: "svr", Proto: "tcp", DPort: config.PortSpec{"22"}},
want: map[string][]string{"output": {""}, "forward": {"iif=eth1 oif=eth2"}},
want: map[string][]string{"output": {"oif=eth2"}, "forward": {"iif=eth1 oif=eth2"}},
},
{
name: "dest list with fw splits input and forward",
@@ -1850,6 +1861,16 @@ func TestCompile_CommaZoneLists(t *testing.T) {
rule: config.Rule{Action: config.RuleAccept, Source: "lan", Dest: "vpn,dmz"},
want: map[string][]string{"forward": {"iif=eth1"}},
},
{
name: "fw source matches dest zone oif",
rule: config.Rule{Action: config.RuleAccept, Source: "fw", Dest: "lan,vpn,dmz", Proto: "tcp", DPort: config.PortSpec{"22"}},
want: map[string][]string{"output": {"oif=eth1", ""}},
},
{
name: "fw to all has no oif",
rule: config.Rule{Action: config.RuleAccept, Source: "fw", Dest: "all:192.0.2.1"},
want: map[string][]string{"output": {"daddr=192.0.2.1"}},
},
{
name: "blrule zone list",
blrule: &config.BlruleRule{Action: config.BlruleDrop, Source: "net,anycast", Dest: "fw"},