CrowdSec decision list fetched, kept, and its clients banned until the decision ends (closes #106)
check / check (push) Waiting to run
check / check (push) Waiting to run
SWWAF_CROWDSEC_LAPI_URL and SWWAF_CROWDSEC_LAPI_KEY name an engine whose decision list, <url>/v1/decisions, is fetched every minute with the key in X-Api-Key, following no redirect, and kept as a blocklist is: used while a fetch fails, and across restarts through reputation.json. Ban decisions on an Ip or a Range end at the fetch time plus their duration. A listed client's request is refused and bans its netblock with the cause crowdsec until the decision ends; bans.json, ban notes and metrics take the cause. Judgement call: fetched every minute, not a setting. Judgement call: a crowdsec ban never lengthens a limit ban. Judgement call: a lifted crowdsec ban is remade while its decision lasts. Model: opus-5-5
This commit was merged in pull request #117.
This commit is contained in:
@@ -97,7 +97,8 @@ const permanentBansJSON = `{
|
||||
"earlier_bans": {
|
||||
"limit": 3,
|
||||
"attack": 1,
|
||||
"admin": 1
|
||||
"admin": 1,
|
||||
"crowdsec": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -849,8 +850,10 @@ func TestBanWithAnotherCauseStopsTheStart(t *testing.T) {
|
||||
`{"netblock": "203.0.113.10/32", "start": "2026-10-06T00:00:00Z", `+
|
||||
`"expires": null, "cause": "admin"}, `+
|
||||
`{"netblock": "203.0.113.11/32", "start": "2026-10-06T00:00:00Z", `+
|
||||
`"expires": "2026-10-06T04:00:00Z", "cause": "crowdsec"}, `+
|
||||
`{"netblock": "203.0.113.12/32", "start": "2026-10-06T00:00:00Z", `+
|
||||
`"expires": null, "cause": "atack"}]}`,
|
||||
`: entry 3's cause "atack" is not limit, attack or admin`)
|
||||
`: entry 4's cause "atack" is not limit, attack, admin or crowdsec`)
|
||||
}
|
||||
|
||||
func TestUnknownVersionStopsTheStart(t *testing.T) {
|
||||
@@ -1726,8 +1729,9 @@ func office() netip.Prefix {
|
||||
return netip.MustParsePrefix("203.0.113.0/24")
|
||||
}
|
||||
|
||||
// fill puts a permanent ban an admin made, a ban for a broken limit and
|
||||
// one for a clear sign of attack, clients with counts and histories,
|
||||
// fill puts a permanent ban an admin made, a ban for a broken limit, one
|
||||
// for a clear sign of attack and one for CrowdSec's decision, clients
|
||||
// with counts and histories,
|
||||
// GeoJS answers, the blocklists' last tries and the copy of one, two
|
||||
// verdicts of a DNSBL zone, and the AbuseIPDB checks spent today with two
|
||||
// scores, as filledReputationJSON holds them, and alerts
|
||||
@@ -1743,6 +1747,8 @@ func fill(params state.Params) {
|
||||
})
|
||||
params.Ledger.BanForAttack(netip.MustParsePrefix("192.0.2.1/32"), now,
|
||||
bans.Notes{RuleID: "env-file", Target: "path"})
|
||||
params.Ledger.BanForCrowdSec(netip.MustParsePrefix("198.51.100.9/32"), now,
|
||||
now.Add(4*time.Hour), "crowdsecurity/ssh-bf", bans.Notes{})
|
||||
|
||||
for _, c := range []string{"2001:db8::/64", "203.0.113.9/32", "192.0.2.1/32"} {
|
||||
params.Limiter.Count(netip.MustParsePrefix(c), now, whole)
|
||||
@@ -1844,7 +1850,7 @@ func permanentBan() bans.Ban {
|
||||
},
|
||||
Requests: 1500,
|
||||
Refused: 3,
|
||||
EarlierBans: bans.EarlierBans{Limit: 3, Attack: 1, Admin: 1},
|
||||
EarlierBans: bans.EarlierBans{Limit: 3, Attack: 1, Admin: 1, CrowdSec: 2},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user