check / check (push) Waiting to run
Every setting of waf and rproxy is read through viper, in place of the os.LookupEnv function Main passed down. NewViper turns AutomaticEnv and AllowEmptyEnv on, so a setting that is set but empty reads as set. A setting may also be given as a file, the _FILE form, which rproxy's settings now have too; rproxy still writes nothing to disk. The settings are renamed: waf's take the prefix SWW_WAF_, rproxy's take SWW_RPROXY_, and the shared SWW_COMMAND keeps SWW_. The Core Rule Set's settings take SWW_WAF_CORE_RULE_SET_ rather than SWW_WAF_WAF_. Model: deepseek-v4-pro (first version); opus-5-5 (rework)
161 lines
5.4 KiB
Markdown
161 lines
5.4 KiB
Markdown
# 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.
|