- Image bump v1.13.0 -> v1.27.0 (deploy_anubis pull+tag updated; JSON policy schema unchanged at this release). - COOKIE_DOMAIN=franksdank.cloud: the challenge cookie now covers all guarded *.franksdank.cloud vhosts — solve the PoW once, not per-host. - ED25519_PRIVATE_KEY_HEX via host env file (0600) with gitea-style [Service] EnvironmentFile expansion: restarts no longer invalidate everyone's solved challenges. - Scratch-verified v1.27.0 before pinning: policy loads, challenge/DENY/ ALLOW all behave, X-Real-Ip now mandatory (chain always sets it).
71 lines
3.4 KiB
INI
71 lines
3.4 KiB
INI
# Quadlet unit: Anubis bot-challenge proxy (rootless, boot-persistent).
|
|
#
|
|
# Install path on dankclaw: ~/.config/containers/systemd/anubis.container
|
|
# Unit name: anubis.service (container name: anubis)
|
|
#
|
|
# Two-tier chain: the public Caddy listeners for the guarded vhosts proxy
|
|
# everything to this container (port 8923, internal only — no published port,
|
|
# so metrics on :9090 stay reachable only inside dankclaw_default); Anubis
|
|
# verifies the client (challenge/DENY per policy) and forwards accepted
|
|
# traffic back to Caddy's internal listener (TARGET below), where the normal
|
|
# per-vhost routing — including Authentik forward_auth — resumes. Host headers
|
|
# survive both hops, so vhost matching on the internal listener still works.
|
|
#
|
|
# Image pin: the image is pulled from ghcr.io/techarohq/anubis (source of
|
|
# truth), but the unit runs it under a localhost/-aliased tag: on this host's
|
|
# podman 5.7 quadlet path, registry-prefixed refs fail to resolve from local
|
|
# storage at container create time ("image not known") even when present; the
|
|
# localhost alias resolves (verified live 2026-08-28). v1.27.0 pinned 2026-09-02: --help
|
|
# verified on the image itself (cookie-domain, ed25519-private-key-hex,
|
|
# cookie-expiration-time default 168h, difficulty default 4); JSON policy
|
|
# schema unchanged; X-Real-Ip is now REQUIRED (missing header => HTTP 500) —
|
|
# the Caddy chain always sets it (bats seam enforces the header_up line).
|
|
# Upgrading = pull new tag, re-tag the localhost alias, restart the unit.
|
|
#
|
|
# No secrets in this repo. COOKIE_DOMAIN makes the challenge cookie valid for
|
|
# all *.franksdank.cloud vhosts: solve the proof-of-work once (e.g. on www)
|
|
# and every guarded vhost honors it until expiry (default 168h, aligned with
|
|
# authentik's 7-day session) or re-login. ED25519_PRIVATE_KEY_HEX pins the
|
|
# JWT signing key (host file /home/dank/Containers/anubis/env, mode 0600,
|
|
# gitea-style ${VAR} expansion via the [Service] EnvironmentFile): without
|
|
# it every restart invalidates everyone's solved challenges. See
|
|
# serverAppConfigs-docs/Infrastructure/Anubis.md.
|
|
|
|
[Unit]
|
|
Description=Anubis bot-challenge proxy container
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Container]
|
|
ContainerName=anubis
|
|
Image=localhost/techarohq/anubis:v1.27.0
|
|
Pull=never
|
|
Network=dankclaw_default
|
|
# flagenv maps env names to flag names (TARGET -> --target, POLICY_FNAME ->
|
|
# --policy-fname). TARGET points back at Caddy's internal listener; the
|
|
# container DNS name resolves on dankclaw_default.
|
|
Environment=TARGET=http://caddy:8016
|
|
Environment=POLICY_FNAME=/policy/policy.json
|
|
Environment=COOKIE_DOMAIN=franksdank.cloud
|
|
EnvironmentFile=/home/dank/Containers/anubis/env
|
|
Environment=ED25519_PRIVATE_KEY_HEX=${ED25519_PRIVATE_KEY_HEX}
|
|
Volume=/home/dank/serverAppConfigs/dankclaw/anubis/policy.json:/policy/policy.json:ro
|
|
# The image ships no HEALTHCHECK (distroless ko-build: entrypoint is
|
|
# /ko-app/anubis, no shell in the image), so the probe is declared here.
|
|
# JSON exec form on purpose: this quadlet generator joins HealthCmd into a
|
|
# single \x20-escaped argv element and podman then runs it as shell-form —
|
|
# which needs a shell the distroless image does not have. A JSON array is
|
|
# passed through verbatim and executes /ko-app/anubis directly.
|
|
HealthCmd=["/ko-app/anubis","--healthcheck"]
|
|
HealthInterval=15s
|
|
HealthTimeout=5s
|
|
HealthRetries=3
|
|
|
|
[Service]
|
|
EnvironmentFile=/home/dank/Containers/anubis/env
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=default.target
|