Lower limits for listed AS numbers and countries (closes #21)
check / check (push) Waiting to run
check / check (push) Waiting to run
SWWAF_ASN_LIMIT_PERCENT and SWWAF_COUNTRY_LIMIT_PERCENT give the clients of the AS numbers and countries they list that percentage of every rate and byte limit, rounded down; SWWAF_ASN_BYTES_PERCENT and SWWAF_COUNTRY_BYTES_PERCENT take its place for the byte limits of those they list; SWWAF_UNKNOWN_LIMIT_PERCENT (100) covers clients without a country. The lowest applies. While one lowers a limit, a request waits for its client's lookup, and SWWAF_LOOKUP_SOURCE=off stops the start. Log lines give limit_percent and bytes_percent with their settings; ban notes, and so alerts, give the broken limit's. Judgement call: a client without a country is unknown, whatever its AS number. Judgement call: bytes_percent and its setting are log fields SPEC does not name. Rule suppressed: funlen on FromEnvironment, one line per setting. Model: opus-5-5
This commit was merged in pull request #103.
This commit is contained in:
@@ -56,9 +56,12 @@ type request struct {
|
||||
lookedUp bool
|
||||
lookupAnswer lookup.Answer
|
||||
// counted is true for a request the rate limits counted, whose bytes
|
||||
// the byte limits count once it has ended.
|
||||
counted bool
|
||||
start time.Time
|
||||
// the byte limits count once it has ended. limitPercent and
|
||||
// bytesPercent are then its client's limit percentages for the rate
|
||||
// limits and for the byte limits.
|
||||
counted bool
|
||||
limitPercent, bytesPercent percentage
|
||||
start time.Time
|
||||
// checked is when the checks were done, and upstreamStart when the
|
||||
// request was handed to the app.
|
||||
checked time.Time
|
||||
@@ -212,9 +215,10 @@ func (rq *request) check(ctx context.Context) *refusal {
|
||||
// them refuses is not counted for the rate limits. Then come the rate
|
||||
// limits, unless the client is in SWWAF_RATE_LIMIT_EXEMPT_NETS or the
|
||||
// request's path is exempt under SWWAF_RATE_LIMIT_EXEMPT_PATHS, so that
|
||||
// every other request is counted, and last the rule files. A request
|
||||
// exempt from the rate limits is exempt from the byte limits too. ctx is
|
||||
// the request's own context.
|
||||
// every other request is counted, each of them by the client's limit
|
||||
// percentages, and last the rule files. A request exempt from the rate
|
||||
// limits is exempt from the byte limits too. ctx is the request's own
|
||||
// context.
|
||||
func (rq *request) checkClient(ctx context.Context) string {
|
||||
cfg := rq.h.config
|
||||
if isInside(rq.client, cfg.AllowNets) {
|
||||
@@ -239,6 +243,12 @@ func (rq *request) checkClient(ctx context.Context) string {
|
||||
|
||||
rq.counted = !isInside(rq.client, cfg.RateLimitExemptNets) &&
|
||||
!pathExempt(rq.in.URL, cfg.RateLimitExemptPaths)
|
||||
if rq.counted {
|
||||
rq.limitPercent, rq.bytesPercent = limitPercentages(cfg, rq.line.ASN, rq.line.Country)
|
||||
rq.line.LimitPercent, rq.line.LimitPercentSetting = rq.limitPercent.logged()
|
||||
rq.line.BytesPercent, rq.line.BytesPercentSetting = rq.bytesPercent.logged()
|
||||
}
|
||||
|
||||
if rq.counted && rq.limitBroken(now) {
|
||||
return requestlog.ActionRateLimited
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user