Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
61 lines
2.3 KiB
Go
61 lines
2.3 KiB
Go
package firewall
|
|
|
|
import (
|
|
"net/netip"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestTheRulesetGuardsOnlyLlmgwsPorts(t *testing.T) {
|
|
s := Script(Spec{
|
|
Ports: []Port{NodeExporter, Engines(20000, 20999), NodeExporter},
|
|
Allow: []netip.Prefix{netip.MustParsePrefix("10.0.0.147/24"), netip.MustParsePrefix("fd00::1/64"),
|
|
netip.MustParsePrefix("10.0.0.0/24")},
|
|
})
|
|
for _, want := range []string{
|
|
"table inet llmgw\ndelete table inet llmgw\ntable inet llmgw {",
|
|
"policy accept;",
|
|
`iif "lo" accept`,
|
|
"ip saddr { 10.0.0.0/24 } tcp dport { 9100, 20000-20999 } accept",
|
|
"ip6 saddr { fd00::/64 } tcp dport { 9100, 20000-20999 } accept",
|
|
"tcp dport { 9100, 20000-20999 } drop",
|
|
} {
|
|
if !strings.Contains(s, want) {
|
|
t.Errorf("no %q in:\n%s", want, s)
|
|
}
|
|
}
|
|
if strings.Contains(s, "policy drop") || strings.Contains(s, "flush ruleset") {
|
|
t.Errorf("the ruleset reaches beyond llmgw's ports:\n%s", s)
|
|
}
|
|
}
|
|
|
|
func TestTheNetworkIsTheInterfacesOrTheAddressAlone(t *testing.T) {
|
|
addrs := `1: lo inet 127.0.0.1/8 scope host lo\ valid_lft forever preferred_lft forever
|
|
2: eth0 inet 10.0.0.147/24 brd 10.0.0.255 scope global eth0\ valid_lft forever preferred_lft forever
|
|
3: eth1 inet 192.168.5.7/16 brd 192.168.255.255 scope global eth1\ valid_lft forever preferred_lft forever`
|
|
cases := []struct {
|
|
route, addr, want string
|
|
}{
|
|
{"10.0.0.140 dev eth0 src 10.0.0.147 uid 1000 \\ cache", "10.0.0.140", "10.0.0.0/24"},
|
|
{"172.16.3.4 via 10.0.0.1 dev eth0 src 10.0.0.147 uid 1000 \\ cache", "172.16.3.4", "172.16.3.4/32"},
|
|
{"192.168.9.9 dev eth1 src 192.168.5.7 uid 1000 \\ cache", "192.168.9.9", "192.168.0.0/16"},
|
|
// Its own address: the network it is on.
|
|
{"local 10.0.0.147 dev lo src 10.0.0.147 uid 1000 \\ cache <local>", "10.0.0.147", "10.0.0.0/24"},
|
|
}
|
|
for _, c := range cases {
|
|
got, ok := networkToward(c.route+"\n"+addrs, netip.MustParseAddr(c.addr))
|
|
if !ok || got.String() != c.want {
|
|
t.Errorf("toward %s: %v %v, expected %s", c.addr, got, ok, c.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestARulesetReadsBackAsItsSpec(t *testing.T) {
|
|
in := Spec{Ports: []Port{Postgres, Engines(20000, 20999)},
|
|
Allow: []netip.Prefix{netip.MustParsePrefix("10.0.0.0/24"), netip.MustParsePrefix("fd00::/64")}}
|
|
got := parse(Script(in))
|
|
if Script(got) != Script(in) {
|
|
t.Errorf("read back as\n%s\nfrom\n%s", Script(got), Script(in))
|
|
}
|
|
}
|