feat: T1016 dns_config probe + server-side drift detection + Crucible DNS DRIFT badge

This commit is contained in:
AetherForge
2026-05-30 23:26:50 -07:00
parent 6704933568
commit d005d5d07c
48 changed files with 4621 additions and 22 deletions

View File

@@ -41,9 +41,9 @@ func checkDashboardWSToken(r *http.Request) bool {
}
user, pass := parts[0], parts[1]
usersMu.RLock()
expectedPass, exists := authUsers[user]
stored, exists := authUsers[user]
usersMu.RUnlock()
return exists && secureStringEqual(pass, expectedPass)
return exists && checkPassword(stored, pass)
}
var upgrader = websocket.Upgrader{
@@ -106,6 +106,8 @@ type WSHub struct {
agentConfigs map[string]AgentForgeConfig
agentCapabilities map[string]models.AgentCapabilities
agentLogs map[string]string
// T1016 DNS drift detection — stores last seen resolver list per agent
agentDNS map[string][]string
serverPolicy ServerPolicy
pingIntervalSec int
fleetSecret string // baked into forged agents; verified on WS connect
@@ -120,6 +122,7 @@ func NewWSHub(database *db.Database) *WSHub {
agentConfigs: make(map[string]AgentForgeConfig),
agentCapabilities: make(map[string]models.AgentCapabilities),
agentLogs: make(map[string]string),
agentDNS: make(map[string][]string),
pingIntervalSec: 30,
}
}
@@ -519,6 +522,9 @@ func (h *WSHub) HandleAgentWS(w http.ResponseWriter, r *http.Request) {
CPUUsagePct float64 `json:"cpu_usage_pct"`
MemoryUsagePct float64 `json:"memory_usage_pct"`
UptimeSeconds int `json:"uptime_seconds"`
// DNS config (T1016)
DNSServers []string `json:"dns_servers,omitempty"`
DNSSearchDomains []string `json:"dns_search_domains,omitempty"`
// Resource pressure
CPUFreqMHz *int `json:"cpu_freq_mhz,omitempty"`
CPUMaxMHz *int `json:"cpu_max_mhz,omitempty"`
@@ -587,6 +593,23 @@ func (h *WSHub) HandleAgentWS(w http.ResponseWriter, r *http.Request) {
if stats.GPUTempC != nil { broadcast["gpu_temp_c"] = *stats.GPUTempC }
if stats.GPUUsagePct != nil { broadcast["gpu_usage_pct"] = *stats.GPUUsagePct }
// T1016 DNS drift detection
if len(stats.DNSServers) > 0 {
broadcast["dns_servers"] = stats.DNSServers
if stats.DNSSearchDomains != nil {
broadcast["dns_search_domains"] = stats.DNSSearchDomains
}
h.mu.Lock()
prev, hasPrev := h.agentDNS[agentID]
drifted := hasPrev && !dnsEqual(prev, stats.DNSServers)
h.agentDNS[agentID] = stats.DNSServers
h.mu.Unlock()
if drifted {
broadcast["dns_drifted"] = true
log.Printf("[T1016] DNS drift detected on agent %s: %v → %v", agentID, prev, stats.DNSServers)
}
}
if stats.SSHAvailable != nil {
broadcast["ssh_available"] = *stats.SSHAvailable
}
@@ -850,6 +873,25 @@ func mustMarshal(v interface{}) json.RawMessage {
return data
}
// dnsEqual returns true when two DNS server lists contain the same addresses
// regardless of order. Used for T1016 drift detection.
func dnsEqual(a, b []string) bool {
if len(a) != len(b) {
return false
}
m := make(map[string]int, len(a))
for _, v := range a {
m[v]++
}
for _, v := range b {
m[v]--
if m[v] < 0 {
return false
}
}
return true
}
// BroadcastToAgents sends a message to all connected agents
func (h *WSHub) BroadcastToAgents(msg Message) {
h.mu.RLock()