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
This commit was merged in pull request #336.
This commit is contained in:
clawbot committed 2026-11-11 10:56:43 +01:00
1 parent 6a59011dee
commit 83525b5e73
30 files changed
+1677 -585

No files matched your search

+9 -5
View File
@@ -9,6 +9,7 @@
# - that a probe for /.env bans another client, which its next request bans
# for good;
# - that only waf's container changes the state directory's owner;
# - that waf's container makes the cache directory for the sww user;
# - that the app still answers through rproxy with waf stopped, and
# that once waf has started again, bans apply again;
# - that `sv stop` stops rproxy in order, and `docker stop` stops each
@@ -153,9 +154,9 @@ refused_from() {
[ "$(status_from "$1" "$2")" = 403 ]
}
# owner_of_state_dir <container>: print who owns /var/lib/sww there.
owner_of_state_dir() {
docker exec "$1" stat --format '%U' /var/lib/sww
# owner_of <container> <dir>: print who owns dir there.
owner_of() {
docker exec "$1" stat --format '%U' "$2"
}
main() {
@@ -173,11 +174,14 @@ main() {
start_app
echo "example-app: the health checks pass"
[ "$(owner_of_state_dir "$WAF")" = sww ] ||
[ "$(owner_of "$WAF" /var/lib/sww)" = sww ] ||
fail "waf's container did not give the state directory to sww"
[ "$(owner_of_state_dir "$APP")" = root ] ||
[ "$(owner_of "$APP" /var/lib/sww)" = root ] ||
fail "the app's container changed the state directory's owner"
echo "example-app: only waf's container changes the state directory's owner"
[ "$(owner_of "$WAF" /var/cache/sww)" = sww ] ||
fail "waf's container did not make the cache directory for sww"
echo "example-app: waf's container makes the cache directory for sww"
page="$(curl --fail --silent --show-error --max-time 10 "http://$address/")" ||
fail "no answer on port 8080"
+8 -2
View File
@@ -6,8 +6,9 @@
# waf listens on port 8090 unless SWW_LISTEN_ADDR says otherwise, and
# rproxy asks it there unless SWRP_WAF_BACKEND says otherwise. Unless
# SWW_STATE_DIR is set, the state files go in bin/state, beside the binary,
# and unless SWW_RULES_DIR is set, the rule files are those of share/rules.d,
# which the image ships.
# and unless SWW_CACHE_DIR is set, the cache files go in bin/cache. Unless
# SWW_RULES_DIR is set, the rule files are those of share/rules.d, which the
# image ships.
set -eu
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
@@ -31,6 +32,11 @@ main() {
export SWW_STATE_DIR
mkdir -p "$SWW_STATE_DIR"
fi
if [ -z "${SWW_CACHE_DIR+set}" ]; then
SWW_CACHE_DIR="$ROOT/bin/cache"
export SWW_CACHE_DIR
mkdir -p "$SWW_CACHE_DIR"
fi
if [ -z "${SWW_RULES_DIR+set}" ]; then
SWW_RULES_DIR="$ROOT/share/rules.d"
export SWW_RULES_DIR