Neuer Fix
All checks were successful
release-tag / release-image (push) Successful in 2m10s

This commit is contained in:
2026-04-30 08:39:24 +02:00
parent 1587991eda
commit 91bf9ed3fc

92
main.go
View File

@@ -4963,42 +4963,51 @@ func buildSQLMatchCondition(r DynamicRule) (string, []any) {
} }
func (s *server) runDetectionsOnce() { func (s *server) runDetectionsOnce() {
ctx, cancel := context.WithTimeout(context.Background(), s.cfg.DetectionInterval) type ruleSpec struct {
defer cancel() name string
timeout time.Duration
if err := s.detector.updateAgentMetrics(ctx); err != nil { fn func(context.Context) error
s.logger.Printf("update agent metrics: %v", err)
} }
rules := []struct { rules := []ruleSpec{
name string {"agent_offline", 15 * time.Second, s.detector.runAgentOfflineRule},
fn func(context.Context) error {"failed_logon_spike", 45 * time.Second, s.detector.runFailedLogonSpikeRule},
}{ {"reboot_spike", 30 * time.Second, s.detector.runRebootSpikeRule},
{"agent_offline", s.detector.runAgentOfflineRule}, {"new_event_id", 60 * time.Second, s.detector.runNewEventIDRule},
{"failed_logon_spike", s.detector.runFailedLogonSpikeRule}, {"password_spray", 60 * time.Second, s.detector.runPasswordSprayRule},
{"reboot_spike", s.detector.runRebootSpikeRule}, {"success_after_failures", 90 * time.Second, s.detector.runSuccessAfterFailuresRule},
{"new_event_id", s.detector.runNewEventIDRule}, {"new_source_ip_for_user", 90 * time.Second, s.detector.runNewSourceIPForUserRule},
{"password_spray", s.detector.runPasswordSprayRule}, {"dynamic_rules", 60 * time.Second, s.detector.runDynamicRules},
{"success_after_failures", s.detector.runSuccessAfterFailuresRule},
{"new_source_ip_for_user", s.detector.runNewSourceIPForUserRule},
{"dynamic_rules", s.detector.runDynamicRules},
{"ueba_admin_new_host", s.detector.runAdminNewHostRule}, {"ueba_admin_new_host", 90 * time.Second, s.detector.runAdminNewHostRule},
{"ueba_offhours_login", s.detector.runOffHoursLoginRule}, {"ueba_offhours_login", 60 * time.Second, s.detector.runOffHoursLoginRule},
{"ueba_first_privileged_use", s.detector.runFirstTimePrivilegedRule}, {"ueba_first_privileged_use", 60 * time.Second, s.detector.runFirstTimePrivilegedRule},
{"ueba_new_user_context", s.detector.runUEBANewUserContextRule},
{"ueba_update", s.detector.runUEBABaselineUpdate}, // Diese Regel ist bei dir aktuell der Problemfall.
{"ueba_new_user_context", 180 * time.Second, s.detector.runUEBANewUserContextRule},
{"ueba_update", 120 * time.Second, s.detector.runUEBABaselineUpdate},
} }
for _, rule := range rules { for _, rule := range rules {
start := time.Now() start := time.Now()
if err := rule.fn(ctx); err != nil {
s.logger.Printf("rule %s error: %v", rule.name, err) ctx, cancel := context.WithTimeout(context.Background(), rule.timeout)
err := rule.fn(ctx)
cancel()
dur := time.Since(start)
if err != nil {
s.logger.Printf("rule %s error after %s: %v", rule.name, dur, err)
s.detector.ruleErrorsTotal.WithLabelValues(rule.name).Inc() s.detector.ruleErrorsTotal.WithLabelValues(rule.name).Inc()
continue continue
} }
s.logger.Printf("rule %s completed in %s", rule.name, dur)
s.detector.ruleLastRunGauge.WithLabelValues(rule.name).Set(float64(time.Now().Unix())) s.detector.ruleLastRunGauge.WithLabelValues(rule.name).Set(float64(time.Now().Unix()))
s.detector.ruleRuntimeHist.WithLabelValues(rule.name).Observe(time.Since(start).Seconds()) s.detector.ruleRuntimeHist.WithLabelValues(rule.name).Observe(dur.Seconds())
} }
} }
@@ -5061,6 +5070,8 @@ func (d *detector) runUEBANewUserContextRule(ctx context.Context) error {
return nil return nil
} }
start := time.Now()
windowEnd := time.Now().UTC() windowEnd := time.Now().UTC()
windowStart := windowEnd.Add(-d.cfg.UEBANewContextWindow) windowStart := windowEnd.Add(-d.cfg.UEBANewContextWindow)
@@ -5079,23 +5090,21 @@ WHERE e.channel_name = 'Security'
AND e.target_user <> '' AND e.target_user <> ''
AND e.target_user <> '-' AND e.target_user <> '-'
AND e.target_user NOT LIKE '%$' AND e.target_user NOT LIKE '%$'
AND LOWER(e.target_user) NOT IN (
'system',
'localsystem',
'local service',
'network service',
'anonymous logon'
)
GROUP BY e.hostname, e.target_user, e.src_ip, e.workstation GROUP BY e.hostname, e.target_user, e.src_ip, e.workstation
` `
rows, err := d.db.QueryContext(ctx, q, windowStart, windowEnd) rows, err := d.db.QueryContext(ctx, q, windowStart, windowEnd)
if err != nil { if err != nil {
return err return fmt.Errorf("query ueba_new_user_context after %s: %w", time.Since(start), err)
} }
defer rows.Close() defer rows.Close()
rowCount := 0
newCount := 0
for rows.Next() { for rows.Next() {
rowCount++
var host, user, srcIP, workstation string var host, user, srcIP, workstation string
var firstSeen time.Time var firstSeen time.Time
var count int var count int
@@ -5118,6 +5127,8 @@ GROUP BY e.hostname, e.target_user, e.src_ip, e.workstation
continue continue
} }
newCount++
score := 2.0 score := 2.0
severity := "medium" severity := "medium"
@@ -5162,9 +5173,20 @@ GROUP BY e.hostname, e.target_user, e.src_ip, e.workstation
} }
} }
return rows.Err() if err := rows.Err(); err != nil {
} return err
}
d.logger.Printf(
"ueba_new_user_context processed rows=%d new_contexts=%d window=%s duration=%s",
rowCount,
newCount,
d.cfg.UEBANewContextWindow,
time.Since(start),
)
return nil
}
func riskWeight(severity string) float64 { func riskWeight(severity string) float64 {
switch severity { switch severity {
case "critical": case "critical":