Rule files, and bans for a clear sign of attack (closes #24)
check / check (push) Successful in 3m13s
check / check (push) Successful in 3m13s
Every *.rules file in SWWAF_RULES_DIR is read at start and on each change, and each request is checked against the rules after the rate limits: log notes a match, block refuses with 403, ban refuses and bans the netblock for SWWAF_ATTACK_BAN_DURATION, made permanent by its next request or clear sign of attack. path, query and uri are matched as the request line sent them. bans.json gains each ban's cause, and ban notes count earlier bans by cause. The image ships 00-default.rules. Judgement call: a header sent twice is matched with its values joined by ", ". Judgement call: SWWAF_MAX_BAN_DURATION does not cap a ban for an attack. Not in this unit: offences for rule matches, with the error burst. Model: opus-5-5
This commit is contained in:
@@ -82,8 +82,9 @@ func TestLoadedBansCarryOn(t *testing.T) {
|
||||
}
|
||||
|
||||
again := after.BanForLimit(netblock, ban.Expires, bans.Notes{})
|
||||
if again.Expires.Sub(again.Start) != 3*time.Hour || again.Notes.EarlierBans != 1 {
|
||||
t.Errorf("the next ban lasts %s with %d earlier bans, want 3h and 1",
|
||||
if again.Expires.Sub(again.Start) != 3*time.Hour ||
|
||||
again.Notes.EarlierBans != (bans.EarlierBans{Limit: 1}) {
|
||||
t.Errorf("the next ban lasts %s with earlier bans %+v, want 3h and 1 for a limit",
|
||||
again.Expires.Sub(again.Start), again.Notes.EarlierBans)
|
||||
}
|
||||
}
|
||||
@@ -178,7 +179,8 @@ func TestNextBanWorkedOutFromTheBanThatEndedLast(t *testing.T) {
|
||||
Netblock: netblock,
|
||||
Start: midnight(),
|
||||
Expires: midnight().Add(9 * time.Hour),
|
||||
Notes: bans.Notes{EarlierBans: 2},
|
||||
Cause: bans.CauseLimit,
|
||||
Notes: bans.Notes{EarlierBans: bans.EarlierBans{Limit: 2}},
|
||||
}
|
||||
admins := bans.Ban{
|
||||
Netblock: netblock,
|
||||
@@ -191,10 +193,13 @@ func TestNextBanWorkedOutFromTheBanThatEndedLast(t *testing.T) {
|
||||
|
||||
// Once both have ended, a limit broken within the repeat window bans
|
||||
// for three times the 9 hours, and the notes count the two bans
|
||||
// before the 9-hour one, it, and the admin's.
|
||||
// before the 9-hour one and it, for a limit, and the admin's, without
|
||||
// a cause.
|
||||
ban := ledger.BanForLimit(netblock, nineHours.Expires.Add(time.Hour), bans.Notes{})
|
||||
if ban.Expires.Sub(ban.Start) != 27*time.Hour || ban.Notes.EarlierBans != 4 {
|
||||
t.Errorf("the next ban lasts %s with %d earlier bans, want 27h and 4",
|
||||
if ban.Expires.Sub(ban.Start) != 27*time.Hour ||
|
||||
ban.Notes.EarlierBans != (bans.EarlierBans{Limit: 3, WithoutCause: 1}) {
|
||||
t.Errorf("the next ban lasts %s with earlier bans %+v, "+
|
||||
"want 27h, 3 for a limit and 1 without a cause",
|
||||
ban.Expires.Sub(ban.Start), ban.Notes.EarlierBans)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user