Every cache of answers from an outside service has its own file in `SWW_CACHE_DIR` (default `/var/cache/sww`): `lookups.json` (GeoJS), `lists.json` (lists fetched by URL, CrowdSec's decisions included), `dnsbl.json`, `abuseipdb-scores.json` and `routewatch.json` (at most 100,000 answers, each kept an hour). `reputation.json` is gone; the AbuseIPDB checks spent today stay in `SWW_STATE_DIR` as `abuseipdb-checks-spent.json`, since losing them would spend the daily budget twice. A cache file never stops the start: one that does not parse is set aside as `<name>.bad` with a `file_error` alert. An unwritable `SWW_CACHE_DIR` stops the start. The `run` script creates the cache directory and gives it to `sww`. The cache directory needs no volume and can be left out of backups. Model: opus-5-5
5.4 KiB
State and cache files
The JSON files waf keeps, and what each holds. "Persistent state" in
SPEC.md says how they are written, read and edited. Each has a
top-level version of 1.
- The state files are in
SWW_STATE_DIR,/var/lib/swwby default. They hold what cannot be fetched again, so back them up:bans.json;clients.json;abuseipdb-checks-spent.json;alerts.json.
- The cache files are in
SWW_CACHE_DIR,/var/cache/swwby default. They hold answers from outside services, which are asked again when a file is lost, so the directory can be left out of backups:lookups.json;lists.json;dnsbl.json;abuseipdb-scores.json;routewatch.json.
bans.json
Active and past bans: every ban an admin made, and up to SWW_MAX_BANS of those
waf made. Per entry:
netblock,startandexpires(nullfor a permanent ban);cause:attack,limit,adminorcrowdsec;reason: a short reason;lifted: when an admin lifted it, if one did;notes: the notes below.
An entry an admin adds needs netblock, start and expires; reason,
notes and cause may be left out, and the cause is then admin:
{
"version": 1,
"bans": [
{
"netblock": "203.0.113.0/24",
"start": "2026-10-06T12:00:00Z",
"expires": null,
"reason": "probes for logins"
}
]
}
"Bans" in SPEC.md says how an edit lifts, keeps or forgets a
ban. The notes:
asn,as_nameandcountry: the client's, added when the lookup answers (empty when lookups are off);- for a broken limit,
kind(requests,bytesorrefusals),limit,windowandcount: what the limit was on, the limit, its window and the count reached; limit_percentandlimit_percent_setting: the client's percentage of that limit and the setting that gave it, when a setting lowered it;- for a clear sign of attack,
rule_idandtarget, ortrap_path; reputation: the sources the client was on, each with itssourceand, for AbuseIPDB, itsscore;request: the request that caused the ban, each text cut to 256 bytes:time,methodandhost;path, with its query string;statusanduser_agent;
requestsandrefused: 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;
- body bytes of its requests, and of the responses it was sent;
- responses by status class;
- offences by kind:
limit,attack,blocked_by_block_ruleandblocked_by_core_rule_set. A file may also holdtoken_refused, which is kept, and which nothing adds to.
abuseipdb-checks-spent.json
The AbuseIPDB checks spent today, so that a restart does not spend the daily budget again:
day: the day, in UTC;spent: the checks spent on it.
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.
lookups.json
A cache file. GeoJS answers, one per line:
client;asn,as_nameandcountry;answered: when GeoJS answered;used: when the answer was last used.
lists.json
A cache file. The last good copy of each list fetched from a URL, with when it was last tried:
url;tried: when it was last fetched or tried;fetchedandlines: when the last good copy was fetched, and its lines, comment lines included.
dnsbl.json
A cache file. Each DNS blocklist verdict still in use, one per line:
zoneandclient;listed: whether the zone lists the client;fetched: when the zone answered.
abuseipdb-scores.json
A cache file. AbuseIPDB's scores still in use, one per line:
client;score: from 0 to 100;fetched: when AbuseIPDB answered.
routewatch.json
A cache file. routewatch's answers from the last hour, one per line:
client;netblock: the netblock the client's address is announced in, empty for an address without a live route;asn: the number of the AS that originates the netblock, 0 for none;answered: when routewatch answered.
Sizes
clients.json: about 1 KiB per client, about 20 MiB at the defaultSWW_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 defaultSWW_MAX_BANS. Written every 15 minutes, a full file comes to about 600 MiB of writes a day, and a hundred new bans a day add about 600 MiB more.lookups.json: about 150 bytes per answer, under 1.5 GiB of writes a day when full.routewatch.json: about 120 bytes per answer, at most about 12 MiB.abuseipdb-checks-spent.json: a few bytes.lists.json,dnsbl.json,abuseipdb-scores.jsonandalerts.json: usually a few MiB or less.