check / check (push) Successful in 3m13s
The program is now sww, built from cmd/sww, with two modes: sww rproxy and sww discriminator. servewaf becomes discriminator everywhere it names that daemon: the package (internal/discriminator), its types, functions, files, the discriminator_line log field, and its docs and tests. smallwebwaf is left only where sneak's directive allows it: the documents' product name, the git.eeqj.de/sneak/smallwebwaf URLs, and the Go module path sneak.berlin/go/smallwebwaf. Everywhere else a name containing it takes the sww form: the package (internal/sww), metric names (sww_*), the X-Sww-* headers, the /_sww/ admin endpoints, the OS user, and the state and rules directories. The SWWAF_ environment variables take the SWW_ form. No logic changes. make check passes. Model: deepseek-v4-pro
2.7 KiB
2.7 KiB
Admin endpoints
The endpoints under /_sww/, what each takes and what each answers.
sww discriminator answers them at its own address, on the private network.
"Admin endpoints" in SPEC.md says how their tokens work.
GET /_sww/healthz:200andok, to anyone.GET /_sww/metrics: the metrics, forSWW_METRICS_TOKEN(seemetrics.md).GET /_sww/bans: every ban held, underbans, each asbans.jsonlists it. NeedsSWW_ADMIN_TOKEN, as do the three below.POST /_sww/bans: bans a netblock. The body is a JSON object ofnetblock,durationand, if you like,reason.netblockis a netblock such as203.0.113.0/24, or a client's address, which bans its IPv4 netblock (SWW_BAN_SCOPE_V4_PREFIX) or its IPv6 group.durationis a duration such as1hor7d, orpermanent. A bad body is answered400, saying what is wrong:- one that is not such an object, or has another field;
- one longer than 4 KiB;
- one that names an IPv4-mapped netblock, or an address with a zone.
DELETE /_sww/bans/<client>: lifts every active ban covering the address<client>. It answers404when none is active.GET /_sww/clients/<ip>: whatdiscriminatorknows of the client. Underclient, its counters and history asclients.jsonholds them, ornullwhenclients.jsondoes not hold it. Underbans, every ban covering the address, with its notes.POST /_sww/report: takesrproxy's report, without a token. It answers204, or400to a body that is no report (see "The report" inSPEC.md).
No check runs on these requests. A missing or wrong token is answered 401. An
endpoint whose token is unset answers 404, as does any other path.
sww rproxy answers only the health check of these, at its own address. It asks
discriminator about any other request under /_sww/. One that passes the
checks is answered 404, so that the app never sees that prefix (see "rproxy"
in SPEC.md).
Examples
With SWW_ADMIN_TOKEN set, the token in $TOKEN, and discriminator reached
as discriminator:8080 on its network:
# Every ban.
curl -H "Authorization: Bearer $TOKEN" http://discriminator:8080/_sww/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"}' \
http://discriminator:8080/_sww/bans
# Lift the bans on 203.0.113.9.
curl -H "Authorization: Bearer $TOKEN" -X DELETE \
http://discriminator:8080/_sww/bans/203.0.113.9
# What discriminator knows of 203.0.113.9.
curl -H "Authorization: Bearer $TOKEN" \
http://discriminator:8080/_sww/clients/203.0.113.9