Anomaly thresholds: alerts for unusual traffic, nothing refused (closes #101)
check / check (push) Waiting to run

Work in progress.

Model: opus-5-5
This commit is contained in:
2026-10-07 12:49:18 +00:00
parent 2421cdc273
commit 87ec799e99
14 changed files with 1705 additions and 133 deletions
+18 -1
View File
@@ -12,6 +12,7 @@ import (
"time"
"sneak.berlin/go/smallwebwaf/internal/alerts"
"sneak.berlin/go/smallwebwaf/internal/anomaly"
"sneak.berlin/go/smallwebwaf/internal/bans"
"sneak.berlin/go/smallwebwaf/internal/config"
"sneak.berlin/go/smallwebwaf/internal/lookup"
@@ -68,7 +69,8 @@ type Params struct {
// against.
Rules *rules.Files
// Alerts receive the alert for each ban the proxy makes or makes
// permanent, and for GeoJS failing.
// permanent, for each count over an anomaly threshold, and for GeoJS
// failing.
Alerts *alerts.Queue
}
@@ -81,6 +83,7 @@ type Server struct {
Ledger *bans.Ledger
Limiter *ratelimit.Limiter
GeoJS *lookup.GeoJS
Anomalies *anomaly.Counters
LookupFile *lookup.File
Metrics *metrics.Metrics
}
@@ -117,6 +120,17 @@ func New(params Params) *Server {
AttackBanDuration: params.Config.AttackBanDuration,
MaxBans: params.Config.MaxBans,
}),
anomalies: anomaly.New(anomaly.Params{
Client: params.Config.AnomalyClient,
Net: params.Config.AnomalyNet,
ASN: params.Config.AnomalyASN,
Total: params.Config.AnomalyTotal,
Watch: params.Config.AnomalyWatch,
NetV4Prefix: params.Config.AnomalyNetV4Prefix,
NetV6Prefix: params.Config.AnomalyNetV6Prefix,
NamedNetblocks: params.Config.WatchNets,
Alerts: params.Alerts,
}),
lookupFile: params.LookupFile,
rules: params.Rules,
alerts: params.Alerts,
@@ -154,6 +168,7 @@ func New(params Params) *Server {
Ledger: h.ledger,
Limiter: h.limiter,
GeoJS: h.geojs,
Anomalies: h.anomalies,
LookupFile: h.lookupFile,
Metrics: m,
}
@@ -172,6 +187,7 @@ type handler struct {
limiter *ratelimit.Limiter
ledger *bans.Ledger
geojs *lookup.GeoJS
anomalies *anomaly.Counters
lookupFile *lookup.File
rules *rules.Files
alerts *alerts.Queue
@@ -211,6 +227,7 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Once the request has ended, before its log line is written.
defer rq.addToHistory()
defer rq.countAnomalies()
refused := rq.check(r.Context())
rq.checked = time.Now()