Commit Graph
5 Commits
Author SHA1 Message Date
sneak c516e34145 Read every setting through viper and rename the settings (closes #211)
check / check (push) Waiting to run
Every setting of waf 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: waf'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_.

Model: deepseek-v4-pro (first version); opus-5-5 (rework)
2026-11-11 10:15:12 +00:00
clawbot b93bad5842 Answer-time tests check the answer, not wall-clock milliseconds (closes #316)
check / check (push) Waiting to run
Tests only. `TestWAFAnswersWithinTheTimeLimitWhileEveryOutsideSourceHangs` and `TestHangingRoutewatchNeverDelaysAndFailsTheQuery` run in a `synctest` bubble, whose clock load cannot move, instead of comparing wall-clock durations with fixed bounds. The first checks the answer comes after exactly `SWW_LOOKUP_TIMEOUT`, and that the DNS blocklist's query, held by a stand-in resolver, had not failed when it came. The second requires `no_answer_yet` after exactly zero time. The other wall-clock checks in the tests were already in bubbles or are bounds load cannot break.

- The held DNS query still times out on the real clock after two seconds; a stall that long between question and check fails the test.

Model: opus-5-5
2026-11-11 10:56:51 +01:00
clawbot 83525b5e73 Caches of outside APIs live in /var/cache/sww (closes #314)
check / check (push) Waiting to run
Every cache of answers from an outside service has its own file in `SWW_CACHE_DIR` (default `/var/cache/sww`): `lookups.json` (GeoJS), `lists.json` (lists fetched by URL, CrowdSec's decisions included), `dnsbl.json`, `abuseipdb-scores.json` and `routewatch.json` (at most 100,000 answers, each kept an hour). `reputation.json` is gone; the AbuseIPDB checks spent today stay in `SWW_STATE_DIR` as `abuseipdb-checks-spent.json`, since losing them would spend the daily budget twice.

A cache file never stops the start: one that does not parse is set aside as `<name>.bad` with a `file_error` alert. An unwritable `SWW_CACHE_DIR` stops the start. The `run` script creates the cache directory and gives it to `sww`. The cache directory needs no volume and can be left out of backups.

Model: opus-5-5
2026-11-11 10:56:43 +01:00
clawbot 9e7a7e60c7 Tests no longer connect to test servers they closed (closes #257)
check / check (push) Failing after 2m5s
Four tests closed a test server or stopped discriminator, and then
connected to its port. Another test process could take that port in
between and receive the connection.

- TestUnreachableRouteWatchLetsTheRequestThroughAndSaysWhy and
  TestUnreachableRoutewatchFailsTheQueryAndTheLogOmitsTheClient, formerly
  TestRefusedConnection..., point routewatch at 224.0.0.1, a multicast
  address to which TCP cannot connect.
- TestStalledRemoteLogEndpointHoldsUpNoRequest keeps its endpoint open
  and closes each connection it takes, instead of closing the endpoint.
- TestTheSiteAnswersWhileDiscriminatorIsStoppedAndStartedAgain gives
  rproxy an address the test holds throughout. The test forwards each
  connection there to the running discriminator, and closes it while
  discriminator is stopped.

No change to non-test code.

Model: opus-5-5
2026-11-10 00:58:01 +01:00
clawbot 6850cb0e9f Add asn= and prefix= tags from a routewatch instance (closes #204)
check / check (push) Successful in 5m0s
With `SWW_ROUTEWATCH_URL` set, a new heuristic, `routewatch_tags`, adds `asn=<number>` and `prefix=<netblock>` to a request from what a routewatch instance answers about the client. New package `internal/routewatch` asks in the background, never on a request's path, and keeps answers 1 hour in memory. The request log gains `routewatch_tags_missing`, saying why a request has none. `prefix=` works in `SWW_TAG_DENY` and `SWW_TAG_LIMIT_PERCENT`.

Trips a reader: a client's first request has no routewatch tags, so `prefix=` refuses from its next request after the answer comes.
Judgement call: with `SWW_LOOKUP_SOURCE=off` and `SWW_ROUTEWATCH_URL` set, an `asn=` tag no longer stops the start.

Model: opus-5-5
2026-11-09 05:47:34 +01:00