package netstack
import (
"context"
"fmt"
"reflect"
"strings"
"testing"
)
func TestValidateSandboxNetworkInputConfig(t *testing.T) {
if err := ValidateSandboxNetworkInputConfig(context.Background(), &SandboxNetworkConfig{
AllowOut: []string{"192.0.2.10", "198.51.100.0/24"},
DenyIn: []string{"203.0.113.7"},
}); err != nil {
t.Fatalf("ValidateSandboxNetworkInputConfig() error = %v", err)
}
for _, destination := range []string{"example.com", "2001:db8::1", "not-an-address"} {
err := ValidateSandboxNetworkInputConfig(context.Background(), &SandboxNetworkConfig{AllowOut: []string{destination}})
if err == nil || !strings.Contains(err.Error(), destination) {
t.Fatalf("ValidateSandboxNetworkInputConfig(%q) error = %v", destination, err)
}
}
}
func TestBuildPolicyChainOrderingAndDefaults(t *testing.T) {
allowInternet := false
config := &SandboxNetworkConfig{
AllowOut: []string{"192.0.2.10"},
DenyOut: []string{"192.0.2.11"},
AllowIn: []string{"198.51.100.10"},
DenyIn: []string{"198.51.100.11"},
AllowInternetAccess: &allowInternet,
}
wantEgress := [][]string{
{"-m", "conntrack", "--ctstate", "ESTABLISHED,RELATED", "-j", "ACCEPT"},
{"-d", "192.0.2.11", "-j", "REJECT"},
{"-d", "192.0.2.10", "-j", "ACCEPT"},
{"-j", "REJECT"},
}
wantIngress := [][]string{
{"-m", "conntrack", "--ctstate", "ESTABLISHED,RELATED", "-j", "ACCEPT"},
{"-s", "198.51.100.11", "-j", "REJECT"},
{"-s", "198.51.100.10", "-j", "ACCEPT"},
{"-j", "REJECT"},
}
if got := sandboxPolicyRules(config, false); !reflect.DeepEqual(got, wantEgress) {
t.Fatalf("egress rules = %v, want %v", got, wantEgress)
}
if got := sandboxPolicyRules(config, true); !reflect.DeepEqual(got, wantIngress) {
t.Fatalf("ingress rules = %v, want %v", got, wantIngress)
}
}
func TestValidateSandboxNetworkInputConfigLimitsDestinations(t *testing.T) {
entries := make([]string, MaxSandboxNetworkDestinations+1)
for i := range entries {
entries[i] = fmt.Sprintf("10.%d.%d.%d", i>>16, i>>8&255, i&255)
}
if err := ValidateSandboxNetworkInputConfig(context.Background(), &SandboxNetworkConfig{AllowOut: entries}); err == nil {
t.Fatal("ValidateSandboxNetworkInputConfig() accepted an oversized policy")
}
}
func TestRestoreSandboxNetworkPolicyUsesDirectionalHooks(t *testing.T) {
original := runSandboxPolicyRestore
t.Cleanup(func() { runSandboxPolicyRestore = original })
var got string
runSandboxPolicyRestore = func(_ context.Context, rules string) error {
got = rules
return nil
}
if err := applySandboxNetworkPolicyBatch(context.Background(), "tap0", true, true, &SandboxNetworkConfig{}); err != nil {
t.Fatalf("applySandboxNetworkPolicyBatch() error = %v", err)
}
for _, rule := range []string{
"-F CONCH-EGRESS",
"-F CONCH-INGRESS",
"-I FORWARD 1 -i tap0 -j CONCH-EGRESS",
"-I FORWARD 1 -o tap0 -j CONCH-INGRESS",
} {
if !strings.Contains(got, rule) {
t.Fatalf("restore rules %q do not contain %q", got, rule)
}
}
}