check / check (push) Waiting to run
With SWWAF_ABUSEIPDB_KEY set, a client whose history counts an offence (a broken limit, a ban rule's match or a block rule's refusal, counted by kind) is checked in the background, at most SWWAF_ABUSEIPDB_DAILY_BUDGET checks a day, the count kept in reputation.json. A client, an IPv4 address or an IPv6 /64, is checked by the address it sent from, and its score serves all its addresses. A score at or over SWWAF_ABUSEIPDB_MIN_SCORE is a hit for SWWAF_REPUTATION_ACTION, logged as abuseipdb and alerted with its score. A failure or the used-up budget gives no score and raises source_failure. The key goes only in the Key header. Judgement call: the budget's day is UTC; AbuseIPDB documents no reset time. Judgement call: each check sent spends budget; a minute's pause after a failure. Model: opus-5-5
44 lines
1.2 KiB
Go
44 lines
1.2 KiB
Go
package proxy
|
|
|
|
import (
|
|
"time"
|
|
|
|
"sneak.berlin/go/smallwebwaf/internal/requestlog"
|
|
"sneak.berlin/go/smallwebwaf/internal/rules"
|
|
)
|
|
|
|
// checkRules checks the request against the rules of the rule files at
|
|
// now, notes the ids of those it matches in the log line, and returns the
|
|
// action of the rule that refuses it, ActionRuleBlocked for a block rule
|
|
// and ActionBanned for a ban rule, or "" when none does. A ban rule bans
|
|
// the client's netblock for a clear sign of attack, or in observe mode
|
|
// raises the alert for the ban it would have made. Either rule's match
|
|
// is noted as an offence, for the client's history.
|
|
func (rq *request) checkRules(now time.Time) string {
|
|
matched := rq.h.rules.Match(rq.in)
|
|
|
|
for _, rule := range matched {
|
|
rq.line.RuleIDs = append(rq.line.RuleIDs, rule.ID)
|
|
rq.h.metrics.RuleMatched(rule.ID, rule.Action)
|
|
}
|
|
|
|
if len(matched) == 0 {
|
|
return ""
|
|
}
|
|
|
|
// Only the last rule matched can refuse the request.
|
|
switch last := matched[len(matched)-1]; last.Action {
|
|
case rules.ActionBlock:
|
|
rq.ruleBlocked = true
|
|
|
|
return requestlog.ActionRuleBlocked
|
|
case rules.ActionBan:
|
|
rq.attack = true
|
|
rq.banForAttack(now, last)
|
|
|
|
return requestlog.ActionBanned
|
|
default:
|
|
return ""
|
|
}
|
|
}
|