# State and cache files The JSON files `waf` keeps, 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. - The state files are in `SWW_WAF_STATE_DIR`, `/var/lib/sww` by 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_WAF_CACHE_DIR`, `/var/cache/sww` by 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_WAF_MAX_BANS` of those `waf` 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. An entry an admin adds needs `netblock`, `start` and `expires`; `reason`, `notes` and `cause` may be left out, and 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" } ] } ``` "Bans" in [`SPEC.md`](../SPEC.md) says how an edit lifts, keeps or forgets a ban. The notes: - `asn`, `as_name` and `country`: the client's, added when the lookup answers (empty when lookups are off); - for a broken limit, `kind` (`requests`, `bytes` or `refusals`), `limit`, `window` and `count`: what the limit was on, the limit, its window and the count reached; - `limit_percent` and `limit_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_id` and `target`, or `trap_path`; - `reputation`: the sources the client was on, each with its `source` and, for AbuseIPDB, its `score`; - `request`: the request that caused the ban, each text cut to 256 bytes: - `time`, `method` and `host`; - `path`, with its query string; - `status` and `user_agent`; - `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; - body bytes of its requests, and of the responses it was sent; - responses by status class; - offences by kind: `limit`, `attack`, `blocked_by_block_rule` and `blocked_by_core_rule_set`. A file may also hold `token_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_name` and `country`; - `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; - `fetched` and `lines`: 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: - `zone` and `client`; - `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 default `SWW_WAF_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 `SWW_WAF_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.json` and `alerts.json`: usually a few MiB or less.