AbuseIPDB scores for clients that committed an offence, within a daily budget (closes #105)
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
This commit was merged in pull request #111.
This commit is contained in:
2026-10-07 22:47:06 +02:00
parent 0b0f207423
commit ca787985f8
23 changed files with 2045 additions and 309 deletions
+14 -13
View File
@@ -28,18 +28,19 @@ func biasedThresholdsSet(cfg *config.Config) bool {
// limitPercentages returns the client's limit percentages, for the rate
// limits and for the byte limits, by its AS number and country as looked
// up, each "" when unknown, and the blocklists and DNSBL zones that list
// it. Each is the lowest of those the settings give it, the first of them
// in the order below when several are lowest: the percentage
// SWWAF_ASN_LIMIT_PERCENT gives its AS number, the one the file
// up, each "" when unknown, and the blocklists, DNSBL zones and AbuseIPDB
// that list it. Each is the lowest of those the settings give it, the
// first of them in the order below when several are lowest: the
// percentage SWWAF_ASN_LIMIT_PERCENT gives its AS number, the one the file
// SWWAF_ASN_LIMIT_PERCENT_URL names gives it, the one
// SWWAF_COUNTRY_LIMIT_PERCENT gives its country, for a client without a
// country, SWWAF_UNKNOWN_LIMIT_PERCENT, for a client a blocklist lists,
// the percentage of SWWAF_BLOCKLIST_ACTION while it is limit, and for a
// client a DNSBL zone's verdict lists, the percentage of
// SWWAF_REPUTATION_ACTION while it is limit. For the byte limits,
// SWWAF_ASN_BYTES_PERCENT and SWWAF_COUNTRY_BYTES_PERCENT take the place
// of the first three for an AS number or a country they list.
// client a DNSBL zone's verdict lists, or whose AbuseIPDB score is a hit,
// the percentage of SWWAF_REPUTATION_ACTION while it is limit. For the
// byte limits, SWWAF_ASN_BYTES_PERCENT and SWWAF_COUNTRY_BYTES_PERCENT
// take the place of the first three for an AS number or a country they
// list.
func (rq *request) limitPercentages() (percentage, percentage) {
cfg := rq.h.config
asn, country := rq.line.ASN, rq.line.Country
@@ -59,9 +60,9 @@ func (rq *request) limitPercentages() (percentage, percentage) {
blocklisted = percentage{cfg.BlocklistLimitPercent, "SWWAF_BLOCKLIST_ACTION"}
}
dnsblListed := percentage{percent: whole}
if rq.dnsblListed && cfg.ReputationAction == "limit" {
dnsblListed = percentage{cfg.ReputationLimitPercent, "SWWAF_REPUTATION_ACTION"}
reputationListed := percentage{percent: whole}
if (rq.dnsblListed || rq.abuseIPDBHit) && cfg.ReputationAction == "limit" {
reputationListed = percentage{cfg.ReputationLimitPercent, "SWWAF_REPUTATION_ACTION"}
}
asnRequests := lowest(given(cfg.ASNLimitPercent, asn, "SWWAF_ASN_LIMIT_PERCENT"),
@@ -78,8 +79,8 @@ func (rq *request) limitPercentages() (percentage, percentage) {
countryBytes = given(cfg.CountryBytesPercent, country, "SWWAF_COUNTRY_BYTES_PERCENT")
}
return lowest(asnRequests, countryRequests, unknown, blocklisted, dnsblListed),
lowest(asnBytes, countryBytes, unknown, blocklisted, dnsblListed)
return lowest(asnRequests, countryRequests, unknown, blocklisted, reputationListed),
lowest(asnBytes, countryBytes, unknown, blocklisted, reputationListed)
}
// given returns the percentage percents, the setting named setting, gives