Files
Andrew S Erwin b9721ff13f
release gate / check (push) Failing after 8m35s
initial commit on Federted servers
2026-10-19 16:23:55 -05:00

114 lines
4.2 KiB
Go

package netguard
import (
"context"
"fmt"
"net"
"testing"
"time"
)
func TestIsPublic(t *testing.T) {
public := []string{
"8.8.8.8", "1.1.1.1", "2001:4860:4860::8888",
// NAT64 and 6to4 wrapping a PUBLIC embedded IPv4 address a real
// public destination on IPv6-only networks — allowed by policy.
"64:ff9b::8.8.8.8", "2002:808:808::",
}
blocked := []string{
"127.0.0.1", "::1", // loopback
"10.1.2.3", "172.16.0.1", "192.168.1.1", "fc00::1", "fd12::1", "fec0::1", // RFC1918 + ULA + site-local
"169.254.169.254", "fe80::1", // link-local / cloud metadata
"100.64.0.1", "100.127.255.254", // RFC 6598 CGNAT
"198.18.0.1", "198.19.255.255", // benchmark
"192.0.0.1", // IETF protocol assignments
"192.0.2.1", "198.51.100.1", "203.0.113.1", "2001:db8::1", "3fff::1", // documentation space
"0.1.2.3", "240.0.0.1", "255.255.255.255", // this-network / reserved / broadcast
"0.0.0.0", "::", "224.0.0.1", "ff02::1", // unspecified / multicast
"::ffff:10.0.0.1", "::ffff:127.0.0.1", // IPv4-mapped private/loopback
"64:ff9b::7f00:1", "64:ff9b::a00:1", "64:ff9b::a9fe:a9fe", // NAT64-embedded loopback / private / metadata
"64:ff9b:1::8.8.8.8", // local-use NAT64 is never public
"2002:7f00:1::", "2002:a00:1::", "2002:a9fe:a9fe::", // 6to4-embedded loopback / private / metadata
"2001:0:0:0:0:0:7f00:1", "2001:0:4136:e378:8000:63bf:3fff:fdd2", // Teredo
"::127.0.0.1", "::10.0.0.1", "::ffff:0:7f00:1", "::ffff:0:10.0.0.1", // IPv4-compatible / translated
"100::1", "2001:2::1", "2001:10::1", "2001:20::1", "5f00::1", "3ffe::1", // discard, benchmark, ORCHID, SRv6, 6bone
}
for _, s := range public {
if !IsPublic(net.ParseIP(s)) {
t.Errorf("IsPublic(%s) = false, want true", s)
}
}
for _, s := range blocked {
if IsPublic(net.ParseIP(s)) {
t.Errorf("IsPublic(%s) = true, want false", s)
}
}
}
func TestAllowPrivateEnv(t *testing.T) {
if AllowPrivate() {
t.Fatal("AllowPrivate must default to false")
}
t.Setenv("INTEGRATIONS_ALLOW_PRIVATE", "1")
if !AllowPrivate() {
t.Fatal("AllowPrivate must honor INTEGRATIONS_ALLOW_PRIVATE=1")
}
}
func TestDialContextBlocksLoopbackByDefault(t *testing.T) {
if _, e := DialContext(context.Background(), "tcp", "127.0.0.1:5432"); e == nil {
t.Fatal("loopback destination accepted")
}
}
func TestDialContextPortsRejectsUnusualPorts(t *testing.T) {
// Port policy is checked before DNS, so this never dials.
if _, e := DialContextPorts(context.Background(), "tcp", "8.8.8.8:22", 80, 443); e == nil {
t.Fatal("SSH port accepted for a URL preview")
}
if _, e := DialContextPorts(context.Background(), "tcp", "8.8.8.8:not-a-port", 80, 443); e == nil {
t.Fatal("non-numeric port accepted")
}
}
// The NAT64 well-known prefix must not smuggle a non-public IPv4 destination
// past the guard (review follow-up: comprehensive special-range coverage).
func TestDialContextBlocksNAT64WrappedLoopback(t *testing.T) {
if _, e := DialContext(context.Background(), "tcp", "[64:ff9b::7f00:1]:80"); e == nil {
t.Fatal("NAT64-wrapped loopback destination accepted")
}
if _, e := DialContext(context.Background(), "tcp", "[64:ff9b::a9fe:a9fe]:80"); e == nil {
t.Fatal("NAT64-wrapped metadata destination accepted")
}
}
// Bounded fallback among already-validated addresses (review follow-up): a
// host that resolves to several addresses connects even when the first
// record is unreachable. "localhost" resolves to ::1 and/or 127.0.0.1
// depending on the resolver; the listener binds only IPv4 loopback, so on
// dual-stack machines the ::1 attempt must fail over to 127.0.0.1.
func TestDialContextFallsBackAmongValidatedAddresses(t *testing.T) {
t.Setenv("INTEGRATIONS_ALLOW_PRIVATE", "1")
ln, e := net.Listen("tcp4", "127.0.0.1:0")
if e != nil {
t.Skipf("no IPv4 loopback listener possible: %v", e)
}
defer ln.Close()
go func() {
for {
c, e := ln.Accept()
if e != nil {
return
}
c.Close()
}
}()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
conn, e := DialContext(ctx, "tcp", fmt.Sprintf("localhost:%d", ln.Addr().(*net.TCPAddr).Port))
if e != nil {
t.Fatalf("fallback dial to localhost failed: %v", e)
}
conn.Close()
}