servewaf: each decision heuristic is its own module (closes #195)
check / check (push) Successful in 3m17s
check / check (push) Successful in 3m17s
Each check servewaf runs on a request is a type in its own file behind one interface, heuristic, and is registered in one of four ordered lists in heuristics.go. Order and behaviour are unchanged. Every refusal now logs heuristic, the name of the heuristic that made it, and heuristic_figures, the figures it acted on. A ban by refusal_limit or byte_limits after the answer logs after_answer_heuristic and after_answer_heuristic_figures instead, so a line can name both. All four are in docs/request-log.md, and SPEC.md names each heuristic at its step. Model: opus-5-5
This commit is contained in:
1 parent
21cac70b50
commit
230db01127
36 files changed
+1110
-398
No files matched your search
@@ -123,7 +123,9 @@ runs steps 3 to 13, and does the counting of step 15. The first step that
|
||||
produces a final answer ends the checks. Step 15 runs for each request
|
||||
`servewaf` answers with `allow`, `deny` or `close`. `rproxy`'s size and time
|
||||
limits apply to the whole exchange. Each step names the section that holds its
|
||||
rules.
|
||||
rules. Each check is a heuristic. Its name, in parentheses below, is the value
|
||||
of the request log's `heuristic` field. `refusal_limit` and `byte_limits` give
|
||||
theirs in `after_answer_heuristic` instead.
|
||||
|
||||
1. `GET /_smallwebwaf/healthz` is answered at once by `rproxy`, before any
|
||||
check, so a health checker never needs an exemption and is never refused.
|
||||
@@ -141,9 +143,9 @@ rules.
|
||||
around its address, a /64 by default, since one abuser usually controls a
|
||||
whole /64. A client is therefore one IPv4 address or one IPv6 group.
|
||||
3. The static lists. A client in `SWWAF_ALLOW_NETS` skips steps 4 to 12, the
|
||||
byte limits and the error burst. A client in `SWWAF_DENY_NETS` is refused; a
|
||||
client in both lists is let through.
|
||||
4. Bans. A client under a ban is refused (see "Bans").
|
||||
byte limits and the error burst. A client in `SWWAF_DENY_NETS` is refused
|
||||
(`deny_nets`); a client in both lists is let through.
|
||||
4. Bans. A client under a ban is refused (`active_ban`; see "Bans").
|
||||
5. The lookup, unless `SWWAF_LOOKUP_SOURCE` is `off` (see "Lookup of AS number
|
||||
and country"). The request goes on at once. It waits for the first GeoJS
|
||||
answer, up to `SWWAF_LOOKUP_TIMEOUT`, only when one of these needs it:
|
||||
@@ -153,22 +155,26 @@ rules.
|
||||
|
||||
A request that ends before the answer comes is logged without it.
|
||||
|
||||
6. The country lists (see "Country lists").
|
||||
7. The reputation sources (see "Reputation"). A client on a fetched blocklist
|
||||
gets `SWWAF_BLOCKLIST_ACTION`. A client on the CrowdSec decision list is
|
||||
banned. A client listed by a DNS blocklist, or scored at least
|
||||
`SWWAF_ABUSEIPDB_MIN_SCORE` by AbuseIPDB, gets `SWWAF_REPUTATION_ACTION`.
|
||||
6. The country lists (`countries`; see "Country lists").
|
||||
7. The reputation sources (see "Reputation"), in this order:
|
||||
- A client on a fetched blocklist gets `SWWAF_BLOCKLIST_ACTION`
|
||||
(`blocklists`).
|
||||
- A client on the CrowdSec decision list is banned (`crowdsec`).
|
||||
- A client listed by a DNS blocklist gets `SWWAF_REPUTATION_ACTION`
|
||||
(`dnsbl`).
|
||||
- A client scored at least `SWWAF_ABUSEIPDB_MIN_SCORE` by AbuseIPDB gets
|
||||
`SWWAF_REPUTATION_ACTION` (`abuseipdb`).
|
||||
8. The client's limit percentage (see "Biased thresholds").
|
||||
9. Rate limiting (see "Request rate limits, per client"). A request over a limit
|
||||
times the percentage is refused and bans the client.
|
||||
10. The trap paths (see "Attack detection"). A request for one is refused and
|
||||
bans the client.
|
||||
11. The rule files (see "Rule files"). Matching stops at the first rule that
|
||||
refuses.
|
||||
12. The header limits (see "Answering in time"), and then the Core Rule Set (see
|
||||
"Attack detection"). A Core Rule Set match is refused with `403` while
|
||||
`SWWAF_WAF_MODE` is `block`, and only logged and alerted while it is
|
||||
`detect`.
|
||||
9. Rate limiting (`rate_limits`; see "Request rate limits, per client"). A
|
||||
request over a limit times the percentage is refused and bans the client.
|
||||
10. The trap paths (`trap_paths`; see "Attack detection"). A request for one is
|
||||
refused and bans the client.
|
||||
11. The rule files (`rule_files`; see "Rule files"). Matching stops at the first
|
||||
rule that refuses.
|
||||
12. The header limits (`header_limits`; see "Answering in time"), and then the
|
||||
Core Rule Set (`core_rule_set`; see "Attack detection"). A Core Rule Set
|
||||
match is refused with `403` while `SWWAF_WAF_MODE` is `block`, and only
|
||||
logged and alerted while it is `detect`.
|
||||
13. A path under `/_smallwebwaf/` is answered `404`, so that the app never sees
|
||||
that prefix.
|
||||
14. `rproxy` passes the request to `SWRP_UPSTREAM_URL`, streaming (see "Passing
|
||||
@@ -182,14 +188,14 @@ rules.
|
||||
are added to the byte counters, as `SWWAF_BYTES_COUNT` says. For a
|
||||
WebSocket, what it carried each way counts once it closes. A client whose
|
||||
total passes a byte limit times the percentage has broken that limit and
|
||||
is banned. The response in progress is not cut off.
|
||||
is banned (`byte_limits`). The response in progress is not cut off.
|
||||
- For a request it allowed, the client's history and the anomaly counters
|
||||
are updated, and the alert thresholds are evaluated.
|
||||
|
||||
For a request it refused, `servewaf` adds nothing to the byte limits. It
|
||||
updates the history and the anomaly counters at its decision. It counts the
|
||||
refusals the error burst counts at the decision too (see "Attack
|
||||
detection").
|
||||
refusals the error burst counts at the decision too (`refusal_limit`; see
|
||||
"Attack detection").
|
||||
|
||||
In `SWWAF_MODE=observe`, every refusal above is logged as what would have
|
||||
happened, nothing is refused, and `servewaf` makes no ban of its own. A path
|
||||
|
||||
Reference in new issue
Block a user