check / check (push) Failing after 3m27s
Every setting of discriminator 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. Discriminator'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_. Every place a name appeared changed: the code, the viper keys, tests, documents, examples, the README's settings table and the image files. Model: deepseek-v4-pro
61 lines
2.7 KiB
Markdown
61 lines
2.7 KiB
Markdown
# 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`](../SPEC.md) says how their tokens work.
|
|
|
|
- `GET /_sww/healthz`: `200` and `ok`, to anyone.
|
|
- `GET /_sww/metrics`: the metrics, for `SWW_WAF_METRICS_TOKEN` (see
|
|
[`metrics.md`](metrics.md)).
|
|
- `GET /_sww/bans`: every ban held, under `bans`, each as `bans.json` lists it.
|
|
Needs `SWW_WAF_ADMIN_TOKEN`, as do the three below.
|
|
- `POST /_sww/bans`: bans a netblock. The body is a JSON object of `netblock`,
|
|
`duration` and, if you like, `reason`. `netblock` is a netblock such as
|
|
`203.0.113.0/24`, or a client's address, which bans its IPv4 netblock
|
|
(`SWW_WAF_BAN_SCOPE_V4_PREFIX`) or its IPv6 group. `duration` is a duration
|
|
such as `1h` or `7d`, or `permanent`. A bad body is answered `400`, 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 answers `404` when none is active.
|
|
- `GET /_sww/clients/<ip>`: what `discriminator` knows of the client. Under
|
|
`client`, its counters and history as `clients.json` holds them, or `null`
|
|
when `clients.json` does not hold it. Under `bans`, every ban covering the
|
|
address, with its notes.
|
|
- `POST /_sww/report`: takes `rproxy`'s report, without a token. It answers
|
|
`204`, or `400` to a body that is no report (see "The report" in
|
|
[`SPEC.md`](../SPEC.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`](../SPEC.md)).
|
|
|
|
## Examples
|
|
|
|
With `SWW_WAF_ADMIN_TOKEN` set, the token in `$TOKEN`, and `discriminator`
|
|
reached as `discriminator:8080` on its network:
|
|
|
|
```sh
|
|
# 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
|
|
```
|