Name request log actions so they say what they mean (closes #229)
check / check (push) Successful in 3m46s
check / check (push) Successful in 3m46s
Rename too_large, rate_limited, rule_blocked and denied, and split banned into temporarily_banned and permanently_banned by whether the ban runs out. A request that makes a ban permanent gets permanently_banned. A ban the request itself makes gets the value for that ban, and in observe mode would_action names the ban enforce mode would have made. The offence kind rule_blocked follows, as a metric label and a key in clients.json. Model: opus-5-5
This commit is contained in:
1 parent
d7c62f2854
commit
ca9e97998f
45 files changed
+429
-298
No files matched your search
@@ -50,13 +50,23 @@ func (activeBan) check(_ context.Context, rq *request, now time.Time) *verdict {
|
||||
}
|
||||
|
||||
return &verdict{
|
||||
action: requestlog.ActionBanned,
|
||||
action: banAction(ban.Permanent()),
|
||||
figures: map[string]any{
|
||||
figureNetblock: ban.Netblock.String(), "ban_expires": rq.line.BanExpires,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// banAction is the action of a request refused under a ban or for making one:
|
||||
// permanent says the ban never runs out.
|
||||
func banAction(permanent bool) string {
|
||||
if permanent {
|
||||
return requestlog.ActionPermanentlyBanned
|
||||
}
|
||||
|
||||
return requestlog.ActionTemporarilyBanned
|
||||
}
|
||||
|
||||
// limitFigures are the figures of a heuristic that broke hit, a limit: its
|
||||
// window, the count and the limit.
|
||||
func limitFigures(hit ratelimit.Hit) map[string]any {
|
||||
@@ -90,8 +100,8 @@ func (rq *request) countedBytes() int64 {
|
||||
// rate limit or a byte limit; the error burst is not lowered. The ban sets
|
||||
// the client's counters back to zero. In observe mode it makes no ban and
|
||||
// sets nothing back, and raises the alert for the ban it would have made,
|
||||
// if that alert would be sent.
|
||||
func (rq *request) banForLimit(now time.Time, hit ratelimit.Hit, status int) {
|
||||
// if that alert would be sent. It returns the action for that ban.
|
||||
func (rq *request) banForLimit(now time.Time, hit ratelimit.Hit, status int) string {
|
||||
switch hit.Kind {
|
||||
case ratelimit.KindBytes:
|
||||
rq.line.LimitHit = hit.Window + "_bytes" // as counts names the byte totals
|
||||
@@ -106,7 +116,7 @@ func (rq *request) banForLimit(now time.Time, hit ratelimit.Hit, status int) {
|
||||
|
||||
netblock := rq.h.netblock(rq.client)
|
||||
if rq.h.config.Observe && !rq.wouldAlertBan(netblock, now, bans.CauseLimit) {
|
||||
return
|
||||
return banAction(rq.h.ledger.WouldBePermanent(netblock, now, bans.CauseLimit))
|
||||
}
|
||||
|
||||
notes := bans.Notes{
|
||||
@@ -135,7 +145,7 @@ func (rq *request) banForLimit(now time.Time, hit ratelimit.Hit, status int) {
|
||||
rq.alertBan(ban)
|
||||
}
|
||||
|
||||
return
|
||||
return banAction(ban.Permanent())
|
||||
}
|
||||
|
||||
ban, made := rq.h.ledger.BanForLimit(netblock, now, notes)
|
||||
@@ -145,17 +155,19 @@ func (rq *request) banForLimit(now time.Time, hit ratelimit.Hit, status int) {
|
||||
if made {
|
||||
rq.alertBan(ban)
|
||||
}
|
||||
|
||||
return banAction(ban.Permanent())
|
||||
}
|
||||
|
||||
// banForAttack bans the client's netblock at now for a clear sign of
|
||||
// attack, which notes name: the ban rule that matched, or the trap path
|
||||
// asked for. It fills in the rest of the notes. In observe mode it makes
|
||||
// no ban, and raises the alert for the ban it would have made, if that
|
||||
// alert would be sent.
|
||||
func (rq *request) banForAttack(now time.Time, notes bans.Notes) {
|
||||
// alert would be sent. It returns the action for that ban.
|
||||
func (rq *request) banForAttack(now time.Time, notes bans.Notes) string {
|
||||
netblock := rq.h.netblock(rq.client)
|
||||
if rq.h.config.Observe && !rq.wouldAlertBan(netblock, now, bans.CauseAttack) {
|
||||
return
|
||||
return banAction(rq.h.ledger.WouldBePermanent(netblock, now, bans.CauseAttack))
|
||||
}
|
||||
|
||||
notes.ASN = rq.line.ASN
|
||||
@@ -171,7 +183,7 @@ func (rq *request) banForAttack(now time.Time, notes bans.Notes) {
|
||||
rq.alertBan(ban)
|
||||
}
|
||||
|
||||
return
|
||||
return banAction(ban.Permanent())
|
||||
}
|
||||
|
||||
ban, made := rq.h.ledger.BanForAttack(netblock, now, notes)
|
||||
@@ -180,16 +192,18 @@ func (rq *request) banForAttack(now time.Time, notes bans.Notes) {
|
||||
if made {
|
||||
rq.alertBan(ban)
|
||||
}
|
||||
|
||||
return banAction(ban.Permanent())
|
||||
}
|
||||
|
||||
// banForCrowdSec bans the client's netblock at now until decision,
|
||||
// CrowdSec's decision on the client, ends. In observe mode it makes no
|
||||
// ban, and raises the alert for the ban it would have made, if that alert
|
||||
// would be sent.
|
||||
func (rq *request) banForCrowdSec(now time.Time, decision reputation.Decision) {
|
||||
// would be sent. It returns the action for that ban.
|
||||
func (rq *request) banForCrowdSec(now time.Time, decision reputation.Decision) string {
|
||||
netblock := rq.h.netblock(rq.client)
|
||||
if rq.h.config.Observe && !rq.wouldAlertBan(netblock, now, bans.CauseCrowdSec) {
|
||||
return
|
||||
return banAction(rq.h.ledger.WouldBePermanent(netblock, now, bans.CauseCrowdSec))
|
||||
}
|
||||
|
||||
notes := bans.Notes{
|
||||
@@ -208,7 +222,7 @@ func (rq *request) banForCrowdSec(now time.Time, decision reputation.Decision) {
|
||||
rq.alertBan(ban)
|
||||
}
|
||||
|
||||
return
|
||||
return banAction(ban.Permanent())
|
||||
}
|
||||
|
||||
ban, made := rq.h.ledger.BanForCrowdSec(netblock, now, decision.Expires,
|
||||
@@ -218,6 +232,8 @@ func (rq *request) banForCrowdSec(now time.Time, decision reputation.Decision) {
|
||||
if made {
|
||||
rq.alertBan(ban)
|
||||
}
|
||||
|
||||
return banAction(ban.Permanent())
|
||||
}
|
||||
|
||||
// wouldAlertBan reports whether the alert for a ban on netblock for cause
|
||||
|
||||
Reference in new issue
Block a user