|
@@ -5,15 +5,40 @@ import (
|
|
|
"testing"
|
|
"testing"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-func TestSaveDNATRequiresDstnatChain(t *testing.T) {
|
|
|
|
|
- m := &FirewallManager{}
|
|
|
|
|
- for _, chain := range []string{"srcnat", "custom", "output"} {
|
|
|
|
|
- err := m.SaveNATRule(NATRule{Chain: chain, Action: "dst-nat"})
|
|
|
|
|
- if err == nil || !strings.Contains(err.Error(), "dstnat chain") {
|
|
|
|
|
- t.Fatalf("chain %s: expected dstnat error, got %v", chain, err)
|
|
|
|
|
|
|
+func TestChainPlacement(t *testing.T) {
|
|
|
|
|
+ cases := []struct {
|
|
|
|
|
+ kind string
|
|
|
|
|
+ rule any
|
|
|
|
|
+ valid bool
|
|
|
|
|
+ }{
|
|
|
|
|
+ {"nat", NATRule{Chain: "dstnat", Action: "dst-nat"}, true},
|
|
|
|
|
+ {"nat", NATRule{Chain: "prerouting", Action: "dst-nat"}, true},
|
|
|
|
|
+ {"nat", NATRule{Chain: "output", Action: "dst-nat"}, true},
|
|
|
|
|
+ {"nat", NATRule{Chain: "custom", Action: "dst-nat"}, true},
|
|
|
|
|
+ {"nat", NATRule{Chain: "srcnat", Action: "dst-nat"}, false},
|
|
|
|
|
+ {"nat", NATRule{Chain: "forward", Action: "accept"}, false},
|
|
|
|
|
+ {"nat", NATRule{Chain: "srcnat", Action: "masquerade", OutInterface: "eth0"}, true},
|
|
|
|
|
+ {"nat", NATRule{Chain: "input", Action: "masquerade"}, false},
|
|
|
|
|
+ {"nat", NATRule{Chain: "prerouting", Action: "accept", OutInterface: "eth0"}, false},
|
|
|
|
|
+ {"filter", FilterRule{Chain: "prerouting", Action: "accept"}, false},
|
|
|
|
|
+ {"filter", FilterRule{Chain: "input", Action: "accept", OutInterface: "eth0"}, false},
|
|
|
|
|
+ {"mangle", MangleRule{Chain: "output", Action: "accept", InInterface: "eth0"}, false},
|
|
|
|
|
+ {"mangle", MangleRule{Chain: "forward", Action: "accept", InInterface: "eth0", OutInterface: "eth1"}, true},
|
|
|
|
|
+ }
|
|
|
|
|
+ for _, c := range cases {
|
|
|
|
|
+ err := validateChainPlacement(c.kind, c.rule)
|
|
|
|
|
+ if (err == nil) != c.valid {
|
|
|
|
|
+ t.Errorf("%s %#v: %v", c.kind, c.rule, err)
|
|
|
}
|
|
}
|
|
|
- if len(m.natRules) != 0 {
|
|
|
|
|
- t.Fatal("rejected rule was saved")
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func TestNATChainHooks(t *testing.T) {
|
|
|
|
|
+ rules := []NATRule{{ID: "incoming", Chain: "dstnat", Action: "dst-nat", ToAddresses: "192.0.2.1"}, {ID: "local", Chain: "output", Action: "dst-nat", ToAddresses: "192.0.2.2"}, {ID: "outgoing", Chain: "srcnat", Action: "masquerade"}}
|
|
|
|
|
+ payload := ownedPayload(BuildIPTablesRestore(nil, rules, nil), "")
|
|
|
|
|
+ for _, want := range []string{"-A DT_nat_PREROUTING ", "-A DT_nat_OUTPUT ", "-A DT_nat_POSTROUTING ", "-I PREROUTING 1 -m comment --comment debtik:hook -j DT_nat_PREROUTING", "-I OUTPUT 1 -m comment --comment debtik:hook -j DT_nat_OUTPUT", "-I POSTROUTING 1 -m comment --comment debtik:hook -j DT_nat_POSTROUTING"} {
|
|
|
|
|
+ if !strings.Contains(payload, want) {
|
|
|
|
|
+ t.Errorf("missing %s", want)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|