Rename the program to sww and its deciding daemon to discriminator
check / check (push) Successful in 5m33s

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 SWW_COMMAND setting, the OS user, and the state
and rules directories.

No logic changes. make check passes.

Model: deepseek-v4-pro
This commit is contained in:
sneak committed 2026-11-07 04:19:17 +00:00
1 parent 7fed6b6d36
commit d8f417b00b
97 files changed
+1945 -1912

No files matched your search

+39 -38
View File
@@ -4,8 +4,8 @@ Every setting, its default and the values it takes, in the groups of "Settings"
in [`SPEC.md`](../SPEC.md). That section gives the conventions, the settings
that take `off`, the `_FILE` form, and what each group does and why.
The settings that start with `SWWAF_` are `servewaf`'s. Those that start with
`SWRP_` are `rproxy`'s, and are under "`rproxy`" below. `SMALLWEBWAF_COMMAND`
The settings that start with `SWWAF_` are `discriminator`'s. Those that start
with `SWRP_` are `rproxy`'s, and are under "`rproxy`" below. `SWW_COMMAND`
chooses between the two (see "The image's command" below).
## Forms of values
@@ -28,12 +28,12 @@ chooses between the two (see "The image's command" below).
## Core
- `SWWAF_LISTEN_ADDR` (default `:8080`): where `servewaf` listens: `:` and a
port, such as `:9000`. Leave the host out (see "Ports" in
- `SWWAF_LISTEN_ADDR` (default `:8080`): where `discriminator` listens: `:` and
a port, such as `:9000`. Leave the host out (see "Ports" in
[`SPEC.md`](../SPEC.md)).
- `SWWAF_INSTANCE_NAME` (default: the container's host name): the `instance`
name in each line `servewaf` logs, and in each alert and metric, such as
`fsn1/servewaf`. Valid UTF-8. No control character while
name in each line `discriminator` logs, and in each alert and metric, such as
`fsn1/discriminator`. Valid UTF-8. No control character while
`SWWAF_ALERT_NTFY_URL` is set. 1 to 48 printable ASCII characters without a
space while `SWWAF_LOG_REMOTE_URL` is set and `SWWAF_LOG_REMOTE_APP_NAME` is
not.
@@ -42,20 +42,20 @@ chooses between the two (see "The image's command" below).
client's group, from 32 to 128.
- `SWWAF_MAX_TRACKED_CLIENTS` (default `20000`): the most clients kept, a whole
number above zero.
- `SWWAF_MAX_BANS` (default `5000`): how many of its own bans `servewaf` keeps,
a whole number above zero.
- `SWWAF_MAX_BANS` (default `5000`): how many of its own bans `discriminator`
keeps, a whole number above zero.
## Tokens
- `SWWAF_ADMIN_TOKEN` (default unset): the token for the ban endpoints and
`/_smallwebwaf/clients/<ip>`. At least 32 characters.
- `SWWAF_METRICS_TOKEN` (default unset): the token for `/_smallwebwaf/metrics`.
At least 32 characters.
`/_sww/clients/<ip>`. At least 32 characters.
- `SWWAF_METRICS_TOKEN` (default unset): the token for `/_sww/metrics`. At least
32 characters.
## State files
- `SWWAF_STATE_DIR` (default `/var/lib/smallwebwaf`): the directory of the state
files, an absolute path that exists and can be written.
- `SWWAF_STATE_DIR` (default `/var/lib/sww`): the directory of the state files,
an absolute path that exists and can be written.
- `SWWAF_STATE_WRITE_DELAY` (default `10s`): how long `bans.json` waits to be
written after a ban is made, lifted or made permanent. A duration.
- `SWWAF_STATE_COUNTER_INTERVAL` (default `15m`): how often every state file is
@@ -63,7 +63,7 @@ chooses between the two (see "The image's command" below).
## Logging
- `SWWAF_LOG_LEVEL` (default `info`): the least severe of `servewaf`'s own
- `SWWAF_LOG_LEVEL` (default `info`): the least severe of `discriminator`'s own
messages that are written: `debug`, `info`, `warn` or `error`.
- `SWWAF_LOG_REQUEST_HEADERS` (default
`accept,accept-language,accept-encoding,content-type,origin,range`): the
@@ -170,8 +170,8 @@ chooses between the two (see "The image's command" below).
## Attack detection
- `SWWAF_RULES_DIR` (default `/etc/smallwebwaf/rules.d`): the directory of the
rule files.
- `SWWAF_RULES_DIR` (default `/etc/sww/rules.d`): the directory of the rule
files.
- `SWWAF_RULES_ENABLED` (default `true`): `false` reads no rule file.
- `SWWAF_TRAP_PATHS` (default empty): paths only scanners ask for, such as
`/wp-login.php,/xmlrpc.php`. Each starts with `/` and holds no `?`.
@@ -310,9 +310,9 @@ Then mount its directory into the container read-only, and name the file:
```sh
docker run \
-v /srv/app/tokens:/etc/smallwebwaf/tokens:ro \
-e SMALLWEBWAF_COMMAND=servewaf \
-e SWWAF_METRICS_TOKEN_FILE=/etc/smallwebwaf/tokens/metrics \
-v /srv/app/tokens:/etc/sww/tokens:ro \
-e SWW_COMMAND=discriminator \
-e SWWAF_METRICS_TOKEN_FILE=/etc/sww/tokens/metrics \
...
```
@@ -325,41 +325,42 @@ A few limits are fixed rather than settings:
- at most 1,000 DNS blocklist queries are under way at once;
- at most 20,000 anomaly counters are kept;
- each alert destination's queue holds at most 1,000 alerts;
- `servewaf` holds at most 10,000 answered requests awaiting their reports;
- `servewaf` refuses a request with more than 50 cookies or more than 100 header
fields (see "Answering in time" under "`servewaf`" in
- `discriminator` holds at most 10,000 answered requests awaiting their reports;
- `discriminator` refuses a request with more than 50 cookies or more than 100
header fields (see "Answering in time" under "`discriminator`" in
[`SPEC.md`](../SPEC.md));
- `rproxy` takes a request line and headers of at most 32 KiB, and closes a
kept-open connection idle for 120 seconds;
- `rproxy` reads at most 1 MiB of the body of `servewaf`'s answer, and answers
`502` to a longer one.
- `rproxy` reads at most 1 MiB of the body of `discriminator`'s answer, and
answers `502` to a longer one.
## `servewaf`'s answer and `rproxy`'s wait
## `discriminator`'s answer and `rproxy`'s wait
`SWWAF_LOOKUP_TIMEOUT` is the longest a question waits on an outside source.
Keep it well under `rproxy`'s `SWRP_TIMEOUT_MS`, as the default is. No question
waits for `SWWAF_REPUTATION_TIMEOUT`, since the DNS blocklists and AbuseIPDB are
asked in the background (see "Answering in time" under "`servewaf`" in
asked in the background (see "Answering in time" under "`discriminator`" in
[`SPEC.md`](../SPEC.md)).
## `rproxy`
`smallwebwaf rproxy` reads the settings below and no others. They are read once
at start, and an invalid value stops the start. None can be given as a file,
since `rproxy` never touches disk. "`rproxy`" in [`SPEC.md`](../SPEC.md) says
what they do.
`sww rproxy` reads the settings below and no others. They are read once at
start, and an invalid value stops the start. None can be given as a file, since
`rproxy` never touches disk. "`rproxy`" in [`SPEC.md`](../SPEC.md) says what
they do.
A time here is a whole number of milliseconds above zero, such as `2000`.
- `SWRP_WAF_BACKEND` (required, no default): `servewaf`'s URL. An `http` or
- `SWRP_WAF_BACKEND` (required, no default): `discriminator`'s URL. An `http` or
`https` URL with a host and an optional port, and nothing more. `rproxy`
speaks HTTP/1.1 to it.
- `SWRP_TIMEOUT_MS` (default `2000`): how long `rproxy` waits for `servewaf`'s
answer, to a question and to a report. A time; never `off`.
- `SWRP_TIMEOUT_MS` (default `2000`): how long `rproxy` waits for
`discriminator`'s answer, to a question and to a report. A time; never `off`.
- `SWRP_DEFAULT_DISPOSITION` (default `allow`): what is done with a request when
`servewaf` cannot be connected to, does not answer at all, or does not answer
within `SWRP_TIMEOUT_MS`. `allow` passes it to the app, and `deny` answers
`503`. It does not apply to an answer `servewaf` gives, such as an error.
`discriminator` cannot be connected to, does not answer at all, or does not
answer within `SWRP_TIMEOUT_MS`. `allow` passes it to the app, and `deny`
answers `503`. It does not apply to an answer `discriminator` gives, such as
an error.
- `SWRP_MAX_REQUEST_SIZE` (default `100M`): the largest request body. A size or
`off`.
- `SWRP_MAX_RESPONSE_SIZE` (default `1G`): the largest response body. A size or
@@ -383,8 +384,8 @@ A time here is a whole number of milliseconds above zero, such as `2000`.
## The image's command
`SMALLWEBWAF_COMMAND` (default `rproxy`) chooses what the image runs and what
its health check checks: `rproxy` or `servewaf` (see "Deployment" in
`SWW_COMMAND` (default `rproxy`) chooses what the image runs and what its health
check checks: `rproxy` or `discriminator` (see "Deployment" in
[`SPEC.md`](../SPEC.md)). It cannot be given as a file.
## Where earlier settings went