Files
smallwebwaf/docs/bans.md
T
sneak d712bb1496
check / check (push) Waiting to run
SPEC: requirements and reasons only, reference material in docs/
docs/settings.md is now the one settings reference; the spec keeps the
conventions, the off list and each group's requirements and reasons, and
links to it for the per-setting entries. The endpoint list, the ban
notes, the state file contents, the rule file format and the alert
object likewise live in docs/ and are linked from the spec. The package
list from the README's Design section joins "Architecture". The nine
docs files are byte-identical to those on the README branch. Package
comments that named "Alert webhook schema", "Request log" and "Metrics
endpoint" for their field lists now name the docs files.

Model: fable-5-1
2026-10-22 21:08:26 +00:00

85 lines
3.3 KiB
Markdown

# Bans
How bans are made, what they cover and how long they last is under "Bans" in
[`SPEC.md`](../SPEC.md); the settings are under "How long bans last and what
they cover" in [`settings.md`](settings.md). This file says what a ban's notes
hold, and how to make, keep or lift a ban.
## The notes
Each ban carries notes for deciding whether to lift it, drawn from what
`smallwebwaf` already knows. Nothing is looked up to fill them:
- the AS number, AS name and country, 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;
- the request that caused the ban: time, method, host, path with its query
string, status and user agent, each text cut to 256 bytes;
- 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;
- how many earlier bans the netblock had, by cause.
## Managing bans by editing `bans.json`
`bans.json` in the state directory holds every ban, indented to be read. A
permanent ban's `expires` is `null`. `smallwebwaf` watches the file and takes in
an edit as soon as it is saved (see [`state-files.md`](state-files.md)).
To ban a netblock, add an entry with its `netblock`, `start` and `expires`.
`expires` is `null` for a ban that never ends. `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 keep a ban `smallwebwaf` made, so that it is never dropped, set its `cause`
to `admin`. To lift a ban, add `"lifted"` with the time you lift it, such as
`"lifted": "2026-10-06T13:00:00Z"`. The ban then refuses nothing and does not
make the netblock's next ban longer. It is kept with its notes. To forget a ban,
delete its entry. A ban whose cause is `attack` becomes permanent at the first
request it refuses. One whose cause is `admin` or `crowdsec` does not.
An edit that cannot be read does not stop the running `smallwebwaf`. It keeps
what it holds. At the file's next write it renames your file to `bans.json.bad`,
writes the file again from memory, and logs and alerts the error. Mend the
`.bad` file and move it back.
## Managing bans through the admin endpoints
With `SWWAF_ADMIN_TOKEN` set, and the token in `$TOKEN`:
```sh
# Every ban.
curl -H "Authorization: Bearer $TOKEN" https://app.example/_smallwebwaf/bans
# Ban 203.0.113.0/24 for seven days.
curl -H "Authorization: Bearer $TOKEN" \
--json '{"netblock": "203.0.113.0/24", "duration": "7d", "reason": "probes for logins"}' \
https://app.example/_smallwebwaf/bans
# Lift the bans on 203.0.113.9.
curl -H "Authorization: Bearer $TOKEN" -X DELETE \
https://app.example/_smallwebwaf/bans/203.0.113.9
# What smallwebwaf knows of 203.0.113.9.
curl -H "Authorization: Bearer $TOKEN" \
https://app.example/_smallwebwaf/clients/203.0.113.9
```
See [`admin-endpoints.md`](admin-endpoints.md) for what each answers. An admin
whose own address is banned lifts that ban by editing `bans.json`.