diff --git a/main.go b/main.go index c0603ea..79a3e72 100644 --- a/main.go +++ b/main.go @@ -1687,6 +1687,7 @@ func main() { s.templates = tmpl + go s.runSOCLoop() go s.runDetectionLoop() mux := http.NewServeMux() @@ -1744,6 +1745,35 @@ func main() { } } +func (s *server) runSOCLoop() { + ticker := time.NewTicker(1 * time.Minute) + defer ticker.Stop() + + s.runSOCOnce() + + for range ticker.C { + s.runSOCOnce() + } +} + +func (s *server) runSOCOnce() { + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer cancel() + + start := time.Now() + + if err := s.detector.runHostRiskScoreUpdate(ctx); err != nil { + s.logger.Printf("soc host risk update error after %s: %v", time.Since(start), err) + s.detector.ruleErrorsTotal.WithLabelValues("host_risk_score").Inc() + return + } + + s.detector.ruleLastRunGauge.WithLabelValues("host_risk_score").Set(float64(time.Now().Unix())) + s.detector.ruleRuntimeHist.WithLabelValues("host_risk_score").Observe(time.Since(start).Seconds()) + + s.logger.Printf("soc host risk update completed in %s", time.Since(start)) +} + func normalizeTime(t time.Time) time.Time { if t.IsZero() { return t @@ -1809,7 +1839,7 @@ func (s *server) handleUIPrivilegedUsers(w http.ResponseWriter, r *http.Request) return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() users, err := s.listPrivilegedUsers(ctx) @@ -1845,7 +1875,7 @@ func (s *server) handleUIPrivilegedUserSave(w http.ResponseWriter, r *http.Reque return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() _, err := s.db.ExecContext(ctx, ` @@ -1884,7 +1914,7 @@ func (s *server) handleUIPrivilegedUserToggle(w http.ResponseWriter, r *http.Req return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() _, err := s.db.ExecContext(ctx, ` @@ -2189,7 +2219,7 @@ func (s *server) handleUISOC(w http.ResponseWriter, r *http.Request) { return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() topHosts, err := s.listSOCTopHosts(ctx, 20) @@ -2271,7 +2301,7 @@ func (s *server) handleUIDetectionUpdate(w http.ResponseWriter, r *http.Request) isFalsePositive := status == "false_positive" isLegitimate := status == "legitimate" - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() _, err = s.db.ExecContext(ctx, ` @@ -2582,7 +2612,7 @@ func (s *server) handleUIBaseline(w http.ResponseWriter, r *http.Request) { } } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() items, err := s.listBaselineAnomalies( @@ -2668,7 +2698,7 @@ func (s *server) handleUIRules(w http.ResponseWriter, r *http.Request) { return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() rules, err := s.listDynamicRules(ctx) @@ -2704,7 +2734,7 @@ func (s *server) handleUIRuleToggle(w http.ResponseWriter, r *http.Request) { enabled := strings.TrimSpace(r.FormValue("enabled")) == "1" - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() _, err = s.db.ExecContext(ctx, ` @@ -2763,7 +2793,7 @@ func (s *server) handleUIRuleSave(w http.ResponseWriter, r *http.Request) { rule.SuppressForSeconds = 0 } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() _, err := s.db.ExecContext(ctx, ` @@ -2860,7 +2890,7 @@ func (s *server) handleUIAgents(w http.ResponseWriter, r *http.Request) { return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() agents, err := s.listAgents(ctx) @@ -2898,7 +2928,7 @@ func (s *server) handleUIAgentToggle(w http.ResponseWriter, r *http.Request) { enabled := strings.TrimSpace(r.FormValue("enabled")) == "1" - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() res, err := s.db.ExecContext(ctx, ` @@ -2927,7 +2957,7 @@ func (s *server) handleUIIndex(w http.ResponseWriter, r *http.Request) { return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() stats, err := s.getDashboardStats(ctx) @@ -2983,7 +3013,7 @@ func (s *server) handleUIDetections(w http.ResponseWriter, r *http.Request) { } } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() items, err := s.listDetections(ctx, filters["host"], filters["rule"], filters["severity"], filters["status"], limit) @@ -3096,7 +3126,7 @@ func (s *server) handleUIEventDetail(w http.ResponseWriter, r *http.Request) { return } - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() ev, err := s.getEventByID(ctx, id) @@ -3551,7 +3581,7 @@ func (s *server) handleDetections(w http.ResponseWriter, r *http.Request) { rule := strings.TrimSpace(r.URL.Query().Get("rule")) severity := strings.TrimSpace(r.URL.Query().Get("severity")) status := strings.TrimSpace(r.URL.Query().Get("status")) - ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) + ctx, cancel := context.WithTimeout(r.Context(), 15*time.Second) defer cancel() items, err := s.listDetections(ctx, host, rule, severity, status, limit) @@ -4747,7 +4777,6 @@ func (s *server) runDetectionsOnce() { {"ueba_first_privileged_use", s.detector.runFirstTimePrivilegedRule}, {"ueba_new_user_context", s.detector.runUEBANewUserContextRule}, {"ueba_update", s.detector.runUEBABaselineUpdate}, - {"host_risk_score", s.detector.runHostRiskScoreUpdate}, } for _, rule := range rules {