check / check (push) Waiting to run
SWWAF_BLOCKLIST_URLS names lists of addresses and netblocks, fetched every SWWAF_BLOCKLIST_REFRESH (24h, never under 1h); an IPv4-mapped line stands for its IPv4 address or netblock. reputation.json keeps each list's last try, failed or not, which a restart waits on as a running instance does, and its last good copy, whole, used while a fetch fails. SWWAF_BLOCKLIST_ACTION denies, limits or only logs a listed client; the log line names the lists, each raises reputation_hit, and a failed fetch raises source_failure. SWWAF_ASN_LIMIT_PERCENT_URL is fetched the same way and counts as SWWAF_ASN_LIMIT_PERCENT does, the lower winning. Judgement call: a failed fetch is retried after the refresh, not sooner. Not done: ban notes do not name the lists yet. Model: opus-5-5
33 lines
1023 B
Go
33 lines
1023 B
Go
package proxy
|
|
|
|
import (
|
|
"sneak.berlin/go/smallwebwaf/internal/alerts"
|
|
)
|
|
|
|
// blocklistDenied notes in the log line the URLs of the blocklists that
|
|
// list the client, counts each of them in the metrics and raises a
|
|
// reputation_hit alert for it, and reports whether SWWAF_BLOCKLIST_ACTION,
|
|
// being deny, refuses the request. Being limit, it lowers the client's
|
|
// limits instead (see limitPercentages), and being log, it does nothing
|
|
// more.
|
|
func (rq *request) blocklistDenied() bool {
|
|
listedBy := rq.h.lists.ListedBy(rq.client)
|
|
rq.line.Reputation = listedBy
|
|
|
|
for _, listURL := range listedBy {
|
|
rq.h.metrics.ReputationHit(listURL)
|
|
rq.h.alerts.Raise(alerts.Alert{
|
|
Event: alerts.EventReputationHit,
|
|
Client: rq.client,
|
|
Netblock: clientGroup(rq.client),
|
|
ASN: rq.line.ASN,
|
|
ASName: rq.line.ASName,
|
|
Country: rq.line.Country,
|
|
Reason: "listed by a blocklist",
|
|
Detail: map[string]any{"source": listURL},
|
|
})
|
|
}
|
|
|
|
return len(listedBy) > 0 && rq.h.config.BlocklistAction == "deny"
|
|
}
|