Files
serverAppConfigs/tests/searxng_limiter.bats
T

79 lines
3.1 KiB
Bash

#!/usr/bin/env bats
# Seam: SearXNG limiter / trusted-group configuration.
# The trusted group lives in shared/searxng/limiter.toml (NOT in settings.yml).
# It must be valid TOML, trust the homelab LAN, and be copied into place by
# deploy.sh so the deployed /etc/searxng/limiter.toml matches the repo.
load helpers
@test "shared/searxng/limiter.toml exists" {
[ -f "$REPO_ROOT/shared/searxng/limiter.toml" ]
}
@test "limiter.toml is valid TOML" {
python3 - "$REPO_ROOT/shared/searxng/limiter.toml" <<'PYEOF'
import sys, tomllib
with open(sys.argv[1], "rb") as fh:
tomllib.load(fh)
PYEOF
}
@test "limiter.toml trusts the homelab LAN in pass_ip" {
python3 - "$REPO_ROOT/shared/searxng/limiter.toml" <<'PYEOF'
import sys, tomllib
with open(sys.argv[1], "rb") as fh:
data = tomllib.load(fh)
ip_lists = data.get("botdetection", {}).get("ip_lists", {})
pass_ip = ip_lists.get("pass_ip", [])
assert "192.168.0.0/24" in pass_ip, f"LAN missing from pass_ip; got {pass_ip}"
PYEOF
}
@test "limiter.toml trusts the LAN as a proxy for X-Forwarded-For" {
python3 - "$REPO_ROOT/shared/searxng/limiter.toml" <<'PYEOF'
import sys, tomllib
with open(sys.argv[1], "rb") as fh:
data = tomllib.load(fh)
bd = data.get("botdetection", {})
proxies = bd.get("trusted_proxies", [])
assert "192.168.0.0/24" in proxies, f"LAN missing from trusted_proxies; got {proxies}"
PYEOF
}
@test "limiter.toml pass_ip covers local + podman sources (loopback + slirp/bridge)" {
# Rootless podman strips the client IP on published-port hits: the container
# sees a slirp/bridge source (10.88.x, 10.89.x), never the real client. And
# the JSON rate limit (API_MAX=4/hour, hardcoded) 429s any non-passed IP.
# So local subagents must present a pass_ip source. Loopback + the host's
# private podman ranges are trusted; they are reachable only from the host.
python3 - "$REPO_ROOT/shared/searxng/limiter.toml" <<'PYEOF'
import sys, tomllib
with open(sys.argv[1], "rb") as fh:
data = tomllib.load(fh)
pass_ip = data.get("botdetection", {}).get("ip_lists", {}).get("pass_ip", [])
need = ["127.0.0.1/32", "::1", "192.168.0.0/24", "10.88.0.0/16", "10.89.0.0/16"]
missing = [n for n in need if n not in pass_ip]
assert not missing, f"pass_ip missing {missing}; got {pass_ip}"
PYEOF
}
@test "SearXNG outgoing policy allows modest VPN latency without retry amplification" {
python3 - "$REPO_ROOT/shared/searxng/settings.yml" <<'PYEOF'
import sys, yaml
with open(sys.argv[1]) as fh:
data = yaml.safe_load(fh)
outgoing = data.get("outgoing", {})
assert outgoing.get("request_timeout") == 4.0, outgoing
assert outgoing.get("max_request_timeout") == 12.0, outgoing
assert outgoing.get("retries") == 1, outgoing
assert outgoing["request_timeout"] < outgoing["max_request_timeout"], outgoing
PYEOF
}
@test "deploy.sh copies limiter.toml into /opt/searxng/config" {
grep -q "shared/searxng/limiter.toml" "$REPO_ROOT/scripts/deploy.sh" \
|| { echo "deploy.sh does not copy shared/searxng/limiter.toml"; return 1; }
grep -q "/opt/searxng/config/limiter.toml" "$REPO_ROOT/scripts/deploy.sh" \
|| { echo "deploy.sh does not place limiter.toml at /opt/searxng/config"; return 1; }
}