check / check (push) Waiting to run
docs/core-rule-set.md, docs/lookup.md, docs/reputation.md and docs/bans.md restated the spec and are folded back into it and removed. The remaining docs files hold only lists: settings with their defaults and value forms, the request log's fields, the metrics, the endpoints, the state files and their contents, the rule file format and default file, the alert events and messages, the image's contents and pins, and the gitea notes. Every behaviour each of them held moves to the spec, said once. The settings groups have the same names in both files. Stale comments in internal/state and script/example-app point at the right places. Model: fable-5-1
101 lines
3.4 KiB
Markdown
101 lines
3.4 KiB
Markdown
# State files
|
|
|
|
The five JSON files in `SWWAF_STATE_DIR`, and what each holds. "Persistent
|
|
state" in [`SPEC.md`](../SPEC.md) says how they are written, read and edited.
|
|
Each has a top-level `version` of 1.
|
|
|
|
## `bans.json`
|
|
|
|
Active and past bans: every ban an admin made, and up to `SWWAF_MAX_BANS` of
|
|
those `smallwebwaf` made. Per entry:
|
|
|
|
- `netblock`, `start` and `expires` (`null` for a permanent ban);
|
|
- `cause`: `attack`, `limit`, `admin` or `crowdsec`;
|
|
- `reason`: a short reason;
|
|
- `lifted`: when an admin lifted it, if one did;
|
|
- `notes`: the notes below.
|
|
|
|
To ban a netblock, add an entry with its `netblock`, `start` and `expires`.
|
|
`reason`, `notes` and `cause` may be left out; the cause is then `admin`:
|
|
|
|
```json
|
|
{
|
|
"version": 1,
|
|
"bans": [
|
|
{
|
|
"netblock": "203.0.113.0/24",
|
|
"start": "2026-10-06T12:00:00Z",
|
|
"expires": null,
|
|
"reason": "probes for logins"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
To lift a ban, add `"lifted"` with the time you lift it, such as
|
|
`"lifted": "2026-10-06T13:00:00Z"`. To keep a ban `smallwebwaf` made, set its
|
|
`cause` to `admin`. To forget a ban, delete its entry.
|
|
|
|
The notes:
|
|
|
|
- `asn`, `as_name` and `country`: the client's, added when the lookup answers
|
|
(empty when lookups are off);
|
|
- what was broken: the rule id and target that matched, or the trap path, or the
|
|
limit, its window and the count reached;
|
|
- the client's percentage of the limit, with the setting that gave it;
|
|
- the reputation sources the client is on;
|
|
- `request`: the request that caused the ban: time, method, host, path with its
|
|
query string, status and user agent, each text cut to 256 bytes;
|
|
- `requests` and `refused`: the netblock's requests since it was first seen, and
|
|
how many this ban has refused so far, kept up to date while the ban lasts;
|
|
- `earlier_bans`: how many earlier bans the netblock had, by cause.
|
|
|
|
## `clients.json`
|
|
|
|
Per client, one per line: its minute, hour and day counters, and its history
|
|
since it was first seen:
|
|
|
|
- the first and last time seen;
|
|
- the AS number, AS name and country last looked up, and when;
|
|
- total requests, and how many were forwarded and how many refused;
|
|
- bytes in each direction;
|
|
- responses by status class;
|
|
- offences by kind: `limit`, `attack`, `rule_blocked`, `waf_blocked` and
|
|
`token_refused`.
|
|
|
|
## `lookups.json`
|
|
|
|
GeoJS answers, one per line:
|
|
|
|
- `client`;
|
|
- `asn`, `as_name` and `country`;
|
|
- `answered`: when GeoJS answered;
|
|
- `used`: when the answer was last used.
|
|
|
|
## `reputation.json`
|
|
|
|
- the last good copy of each list fetched from a URL, with when it was last
|
|
tried;
|
|
- each DNS blocklist verdict still in use;
|
|
- AbuseIPDB's scores, and the checks spent today.
|
|
|
|
## `alerts.json`
|
|
|
|
- the anomaly counters;
|
|
- the alert cooldowns: for each event and netblock, source, file or anomaly
|
|
scope, when it was last sent and the count of repeats held back since;
|
|
- the alerts sent and held back in the current hour;
|
|
- the alerts waiting for each destination.
|
|
|
|
## Sizes
|
|
|
|
- `clients.json`: about 1 KiB per client, about 20 MiB at the default
|
|
`SWWAF_MAX_TRACKED_CLIENTS`. Written every 15 minutes, that is under 2 GiB of
|
|
disk writes a day.
|
|
- `bans.json`: about 1.2 KiB per ban, at most about 2.5 KiB, so about 6 MiB at
|
|
the default `SWWAF_MAX_BANS`. With a full file, a hundred new bans a day come
|
|
to about 600 MiB of writes.
|
|
- `lookups.json`: about 150 bytes per answer, under 1.5 GiB of writes a day when
|
|
full.
|
|
- `reputation.json` and `alerts.json`: usually a few MiB or less.
|