Bugfix Problem Metrics
All checks were successful
release-tag / release-image (push) Successful in 5m59s
All checks were successful
release-tag / release-image (push) Successful in 5m59s
This commit is contained in:
94
main.go
94
main.go
@@ -1688,6 +1688,7 @@ func main() {
|
||||
s.templates = tmpl
|
||||
|
||||
go s.runSOCLoop()
|
||||
go s.runBaselineLoop()
|
||||
go s.runDetectionLoop()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
@@ -1756,6 +1757,53 @@ func (s *server) runSOCLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) runBaselineLoop() {
|
||||
ticker := time.NewTicker(s.cfg.DetectionInterval)
|
||||
defer ticker.Stop()
|
||||
|
||||
s.runBaselineOnce()
|
||||
|
||||
for range ticker.C {
|
||||
s.runBaselineOnce()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) runBaselineOnce() {
|
||||
if !s.cfg.BaselineEnabled {
|
||||
return
|
||||
}
|
||||
|
||||
rules := []struct {
|
||||
name string
|
||||
timeout time.Duration
|
||||
fn func(context.Context) error
|
||||
}{
|
||||
{"baseline_anomaly", 120 * time.Second, s.detector.runBaselineAnomalyRule},
|
||||
{"baseline_update", 120 * time.Second, s.detector.runBaselineUpdate},
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
start := time.Now()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), rule.timeout)
|
||||
err := rule.fn(ctx)
|
||||
cancel()
|
||||
|
||||
dur := time.Since(start)
|
||||
|
||||
if err != nil {
|
||||
s.logger.Printf("baseline rule %s error after %s: %v", rule.name, dur, err)
|
||||
s.detector.ruleErrorsTotal.WithLabelValues(rule.name).Inc()
|
||||
continue
|
||||
}
|
||||
|
||||
s.logger.Printf("baseline rule %s completed in %s", rule.name, dur)
|
||||
|
||||
s.detector.ruleLastRunGauge.WithLabelValues(rule.name).Set(float64(time.Now().Unix()))
|
||||
s.detector.ruleRuntimeHist.WithLabelValues(rule.name).Observe(dur.Seconds())
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) runSOCOnce() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
@@ -3941,17 +3989,18 @@ func (d *detector) runBaselineUpdate(ctx context.Context) error {
|
||||
windowEnd := time.Now().UTC()
|
||||
windowStart := windowEnd.Add(-d.cfg.BaselineWindow)
|
||||
|
||||
hour := windowEnd.Hour()
|
||||
dayOfWeek := int(windowEnd.Weekday()+6) % 7 // Go: Sonntag=0, MySQL WEEKDAY: Montag=0
|
||||
|
||||
rows, err := d.db.QueryContext(ctx, `
|
||||
SELECT
|
||||
hostname,
|
||||
channel_name,
|
||||
event_id,
|
||||
HOUR(ts) AS hour_of_day,
|
||||
WEEKDAY(ts) AS day_of_week,
|
||||
COUNT(*) AS cnt
|
||||
FROM event_logs
|
||||
WHERE ts >= ? AND ts < ?
|
||||
GROUP BY hostname, channel_name, event_id, HOUR(ts), WEEKDAY(ts)
|
||||
GROUP BY hostname, channel_name, event_id
|
||||
`, windowStart, windowEnd)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -3964,13 +4013,14 @@ GROUP BY hostname, channel_name, event_id, HOUR(ts), WEEKDAY(ts)
|
||||
&b.Hostname,
|
||||
&b.Channel,
|
||||
&b.EventID,
|
||||
&b.Hour,
|
||||
&b.DayOfWeek,
|
||||
&b.Count,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.Hour = hour
|
||||
b.DayOfWeek = dayOfWeek
|
||||
|
||||
excluded, err := d.isBaselineExcluded(ctx, b.Hostname, b.Channel, b.EventID)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -3995,6 +4045,12 @@ GROUP BY hostname, channel_name, event_id, HOUR(ts), WEEKDAY(ts)
|
||||
return rows.Err()
|
||||
}
|
||||
|
||||
func mysqlWeekday(t time.Time) int {
|
||||
// MySQL WEEKDAY(): Monday=0 ... Sunday=6
|
||||
// Go Weekday(): Sunday=0 ... Saturday=6
|
||||
return (int(t.UTC().Weekday()) + 6) % 7
|
||||
}
|
||||
|
||||
func (d *detector) hasConfirmedIncidentInWindow(ctx context.Context, hostname, channel string, eventID uint32, windowStart, windowEnd time.Time) (bool, error) {
|
||||
var count int
|
||||
|
||||
@@ -4129,35 +4185,34 @@ func (d *detector) runBaselineAnomalyRule(ctx context.Context) error {
|
||||
windowEnd := time.Now().UTC()
|
||||
windowStart := windowEnd.Add(-d.cfg.BaselineWindow)
|
||||
|
||||
hour := windowEnd.Hour()
|
||||
dayOfWeek := mysqlWeekday(windowEnd)
|
||||
|
||||
rows, err := d.db.QueryContext(ctx, `
|
||||
SELECT
|
||||
e.hostname,
|
||||
e.channel_name,
|
||||
e.event_id,
|
||||
HOUR(e.ts) AS hour_of_day,
|
||||
WEEKDAY(e.ts) AS day_of_week,
|
||||
COUNT(*) AS cnt,
|
||||
b.avg_count,
|
||||
b.stddev_count,
|
||||
b.sample_count
|
||||
COALESCE(b.avg_count, 0),
|
||||
COALESCE(b.stddev_count, 0),
|
||||
COALESCE(b.sample_count, 0)
|
||||
FROM event_logs e
|
||||
JOIN baseline_event_stats b
|
||||
LEFT JOIN baseline_event_stats b
|
||||
ON b.hostname = e.hostname
|
||||
AND b.channel_name = e.channel_name
|
||||
AND b.event_id = e.event_id
|
||||
AND b.hour_of_day = HOUR(e.ts)
|
||||
AND b.day_of_week = WEEKDAY(e.ts)
|
||||
AND b.hour_of_day = ?
|
||||
AND b.day_of_week = ?
|
||||
WHERE e.ts >= ? AND e.ts < ?
|
||||
GROUP BY
|
||||
e.hostname,
|
||||
e.channel_name,
|
||||
e.event_id,
|
||||
HOUR(e.ts),
|
||||
WEEKDAY(e.ts),
|
||||
b.avg_count,
|
||||
b.stddev_count,
|
||||
b.sample_count
|
||||
`, windowStart, windowEnd)
|
||||
`, hour, dayOfWeek, windowStart, windowEnd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -4167,8 +4222,6 @@ GROUP BY
|
||||
var host string
|
||||
var channel string
|
||||
var eventID uint32
|
||||
var hour int
|
||||
var dayOfWeek int
|
||||
var count int
|
||||
var avg float64
|
||||
var stddev float64
|
||||
@@ -4178,8 +4231,6 @@ GROUP BY
|
||||
&host,
|
||||
&channel,
|
||||
&eventID,
|
||||
&hour,
|
||||
&dayOfWeek,
|
||||
&count,
|
||||
&avg,
|
||||
&stddev,
|
||||
@@ -4769,9 +4820,6 @@ func (s *server) runDetectionsOnce() {
|
||||
{"new_source_ip_for_user", s.detector.runNewSourceIPForUserRule},
|
||||
{"dynamic_rules", s.detector.runDynamicRules},
|
||||
|
||||
{"baseline_anomaly", s.detector.runBaselineAnomalyRule},
|
||||
{"baseline_update", s.detector.runBaselineUpdate},
|
||||
|
||||
{"ueba_admin_new_host", s.detector.runAdminNewHostRule},
|
||||
{"ueba_offhours_login", s.detector.runOffHoursLoginRule},
|
||||
{"ueba_first_privileged_use", s.detector.runFirstTimePrivilegedRule},
|
||||
|
||||
Reference in New Issue
Block a user