Files
smallwebwaf/docs/bans.md
T
sneak dfb44c5546
check / check (push) Waiting to run
README rewritten from scratch so a newcomer can follow it (closes #154, closes #155)
The old README opened with project history and one list of a hundred
settings. The new one leads with what smallwebwaf is, what it protects
against, how to build and deploy it, how it sits in front of the app,
what happens to a request, the settings most deployments touch, how to
check it works and how to develop it. The reference material, every
setting, bans, rule files, the Core Rule Set, the admin endpoints, the
request log, alerts, metrics, state files, lookups, reputation sources,
the image and gitea, moves to files under docs/, each linked from the
README. Every statement was checked against the code on next.

Model: fable-5-1
2026-10-22 21:02:38 +00:00

3.3 KiB

Bans

How bans are made, what they cover and how long they last is under "Bans" in SPEC.md; the settings are under "How long bans last and what they cover" in 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).

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:

{
    "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:

# 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 for what each answers. An admin whose own address is banned lifts that ban by editing bans.json.