Files
smallwebwaf/docs/state-files.md
sneak 23908b0e33
check / check (push) Waiting to run
SPEC: false statements fixed, repeats removed, dropped requirements restored
The bounds sentence, the blocklist URL sentence, the deny list sentence,
the limit action's scope and the observe mode sentence now say what the
code does. Each of the twenty-one requirements the fourth review found
twice is stated once, with a link from the other place. The request id
header, redirect_uri's case, change 4's reason and the live archive's
InRelease files are back. The biased thresholds are defined where they
are introduced. The docs files apply the fifth README review's findings
and stay identical to the README branch.

Model: fable-5-1
2026-10-22 22:35:29 +00:00

3.6 KiB

State files

The five JSON files in SWWAF_STATE_DIR, 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.

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.

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_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;
  • 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. 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.
  • reputation.json and alerts.json: usually a few MiB or less.