Commit Graph
2 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5 1bb31fba41 fix(tor): resolve DEPLOYMENT_MODE before picking the SOCKS host
A lookup plugin receives group_vars through variables.get() untemplated, and
group_vars/all/18_swarm.yml:2 defines DEPLOYMENT_MODE as a Jinja expression.
The comparison against 'swarm' could therefore never match, so every swarm
deploy fell through to _COMPOSE_HOST and baked
socks5h://host.docker.internal:9050 into Nextcloud's proxy system value.

svc-net-tor publishes SOCKS with mode: host, so that listener exists on the
manager alone. With three Nextcloud replicas against one Tor node the failure
is node-determined, not intermittent: the 104 'cURL error 7 ... over proxy
host.docker.internal' lines in run 31340965955 split 56 on wrk-02, 48 on
wrk-01 and 0 on mgr-01, which is what made the OIDC callback 500 on 2 of 3
replicas and read as a 39% flake.

Templating first yields socks5h://tor:9050 in swarm, which every replica
reaches over the overlay it already joins through the onion_sso consumer rule.
Compose is unchanged: a single-node inventory renders the expression to
'compose', and a suppressed template error falls through to the same branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 12:01:44 +02:00
kevinveenbirkenbachandClaude Opus 5 20ddda8c1c fix(nextcloud): reach the onion OIDC issuer over Tor SOCKS again
libcurl refuses a .onion host by name (RFC 7686, error 6) before it
consults /etc/hosts, extra_hosts or DNS, so the platform's DNS+iptables
onion egress cannot serve a server-side backchannel at all. Measured:

    curl --noproxy '*'                          -> exit 6
    curl --resolve auth.<onion>:80:127.0.0.1 …  -> exit 6

--resolve fills curl's own cache strictly earlier than getaddrinfo and
is still refused, which makes sys-svc-container's onion_oidc_socks
template -- extra_hosts, despite its name -- a no-op for every libcurl
client. Only a configured proxy makes curl skip the check.

Since 9d91fbea8 emptied proxy.config.php.j2 there is no such proxy, while
svc-net-tor's exclusive/primary defaults replace Keycloak's clearnet
domain and KC_HOSTNAME pins the issuer to the onion. Nextcloud's
oidc_login discovery call therefore dies inside PHP, /apps/oidc_login/oidc
returns 500, and oidc_login_auto_redirect sends /login straight there.

Restoring the old socks5h://host.docker.internal:9050 alone would make it
worse: tor runs as a single manager-pinned replica publishing SOCKS with
mode: host, so only the replica on that node could connect and a
deterministic failure would become a 2-in-3 flake. In swarm, though, tor
is NOT host-networked -- that branch is compose-only -- and it already
binds SocksPort 0.0.0.0, so the shared overlay is a usable path from
every node.

Give svc-net-tor a shared_net overlay with alias 'tor' and dial it by
service name. Attachment is gated by a new consumer kind, onion_sso: the
consumer's services.sso.enabled AND the provider's services.tor.enabled.
Both are group-membership derived, so the conjunction is exactly "the
issuer is an onion" and stays false in clearnet deployments -- which
matters because the service registry is not filtered to deployed roles.
The existing kinds could not express it: keying on sso alone would also
hold without tor, and keying on tor would miss Nextcloud's variant 2,
which disables its own onion yet still needs the client path.

tor_socks_proxy keeps the swarm/compose split in one place so the six
roles sharing this defect need not restate it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 00:50:48 +02:00