package servewaf // What the reputation heuristics share: blocklists, crowdsec, dnsbl and // abuseipdb. import ( "sneak.berlin/go/smallwebwaf/internal/alerts" "sneak.berlin/go/smallwebwaf/internal/bans" ) // deny is the SWWAF_BLOCKLIST_ACTION and the SWWAF_REPUTATION_ACTION that // refuses the requests of a client a source lists. const deny = "deny" // noteListed notes each of sources, the URLs of the blocklists or the // DNSBL zones, their keys masked, that list the client, as noteHit does, // with reason. func (rq *request) noteListed(sources []string, reason string) { for _, source := range sources { rq.noteHit(bans.ReputationHit{Source: source}, reason) } } // noteHit adds hit's source, which lists the client, to the log line's // reputation, and hit to the notes of a ban the request makes, counts the // source in the metrics, and raises a reputation_hit alert with reason, // whose detail gives hit's source and score. func (rq *request) noteHit(hit bans.ReputationHit, reason string) { detail := map[string]any{"source": hit.Source} if hit.Score != nil { detail["score"] = *hit.Score } rq.line.Reputation = append(rq.line.Reputation, hit.Source) rq.reputation = append(rq.reputation, hit) rq.h.metrics.ReputationHit(hit.Source) rq.h.alerts.Raise(alerts.Alert{ Event: alerts.EventReputationHit, Host: rq.site, Client: rq.client, Netblock: rq.h.clientGroup(rq.client), ASN: rq.line.ASN, ASName: rq.line.ASName, Country: rq.line.Country, Reason: reason, Detail: detail, }) }