Proxy: - server_tokens off, X-Powered-By stripped from upstream responses, HSTS max-age raised to one year. - No global X-Content-Type-Options: under nosniff, ORB (step 3.4) blocks no-cors cross-origin responses typed text/html, e.g. tracking beacons answered with an empty 204. PHP (CVE-2026-109618, CVE-2026-109619): - New role sys-svc-compose-php installs a shared ini (expose_php Off, session.upload_progress.enabled 0, fatal_error_backtraces 0 for PHP 8.5, interim memory_limit -1) and a PHP-FPM [www] drop-in (pm.max_requests = PHP_FPM_MAX_REQUESTS) once per stack host, before 04_files renders any compose file. - The host file names carry a sha1 prefix of the controller-side source, so a content change alters every PHP app's compose.yml and recreates it, also on remote deploys where compose_volumes cannot read the stack host file and hashes the path instead. - 20 PHP roles mount the ini as a compose/swarm config into their image's scan dir; moodle, nextcloud and shopware also mount the FPM drop-in. Magento keeps its own pool: its php-fpm.conf has no include= and is rendered without notify. - Joomla's php-upload.ini now loads as zzz-joomla-uploads.ini so its own memory_limit wins: the media API compares Content-Length with toBytes(memory_limit) and rejects every upload at -1. TODOs record the memory_limit revert condition and accepted trade-offs, Akaunting on PHP 8.1, FusionDirectory on PHP 7.4 and the public Keycloak admin console. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
8.7 KiB
Todos
- Implement multi language
- Implement rbac administration interface
- Enable IP6 for docker.
- backup docker to local für ca optimieren
- Drop
memory_limit = -1from hardening.ini once every PHP image ships PHP 8.2.35, 8.3.36, 8.4.27, 8.5.12 or later. It is the interim mitigation for CVE-2026-109618 and overrides the per-roleservice_memory_mbshare, so a single request can exhaust the container instead of hitting a PHP limit.web-app-joomlakeeps its ownmemory_limitbecause its media API compares uploads against it, andweb-app-magentokeeps the 756M itsnginx.conf.sample(PHP_VALUE) andpub/.user.iniset; both keeppost_max_sizebelow a quarter of that limit. While the override is in place,web-app-nextcloud(upload_limit5G at 3g) accepts POST bodies above a quarter of its container memory,web-app-friendicacaps account imports at 64 MiB instead of half the memory limit, EspoCRM's System Requirements page flagsmemory_limitas failed, and Pixelfed (InstanceService), phpMyAdmin (import and export) and Snipe-IT (imports and LDAP sync) set a finite limit again viaini_setafter the request has started. - Fork rpardini/docker-registry-proxy and teach the bundled nginx to handle GCP Artifact Registry redirect URLs (
/artifacts-downloads/namespaces/<ns>/repositories/<repo>/downloads/<token>). Currentlygcr.ioblob pulls are bypassed viaNO_PROXY=…,gcr.io,storage.googleapis.com,googleusercontent.comin compose/registry-cache/proxy.conf, which is a workaround that disables caching for those registries. Long-term: rebase upstream'sproxy.conf/sub_filterrules to recognise the new redirect shape, ship the fix in our fork, pointcompose/registry-cache/Dockerfile(or its image tag) at the fork, and drop theNO_PROXYbypass.
Testing
- re-run with different credentials/configuration
- run over all distros for each app
- msg: can not use content with a dir as dest for NGINX multi distro
- split service database to postgres and mariadb
Onion e2e (feature/svc-net-tor) — remaining failures
Status after deploy-matrix run 29657147883 (commit 407b8a8a1). Every fixable
failure class from that run is committed (hlth-csp onion-sibling skip,
onion-aware Playwright request timeouts + lint guard, joomla server-side OIDC
reachability). The items below are the ones that are NOT fixed yet. Runs
31756400129 and 31756560361 have since moved several of them; entries corrected
against those runs say so inline.
-
https on the onion IdP — investigated and REJECTED, do not re-derive. OIDC Discovery / RFC 8414 want an https issuer, and an onion-exclusive Keycloak has none, so strict client libraries refuse it. Serving TLS on the onion is blocked on four independent things, in this order: (1)
roles/svc-net-tor/templates/torrc.j2publishes onlyHiddenServicePort 80, and no role declares 443 inports.public/ports.local, solookup('tor_ports')can never emit it — flipping TLS on first makes Keycloak unreachable over Tor entirely, becausenginx_ssl_header.j2is one if/else and port 80 disappears; (2)roles/sys-front-tls-selfsigned/tasks/00_core.ymlwrites an unguarded CN, which overflows X.509's 64-byte cap on a 62-char v3 onion —group_vars/all/02_tls.ymlalready guards exactly this for the root CA and nowhere else; (3)nginx_ssl_header.j2emits HSTS in the same branch, and browsers offer no click-through on an HSTS host with an untrusted chain, so a self-signed interim locks real users out while staying invisible to Playwright'signoreHTTPSErrors; (4) it fixes zero libcurl consumers, because RFC 7686 refusal happens at name resolution and is scheme-independent. Unblocking needs a CA that issues for v3.onion(HARICA, CA/B Forum ballot 144) — procurement, not code. Until then the per-consumer fixes stand: SOCKS proxy for libcurl clients. peertube is no longer among them - it is a clearnet-only role. -
dual-family providers — the one real remaining design gap. On a CI onion node, tor-enabled providers (e.g. mastodon) are onion-exclusive: their domain list contains only the
.onioncanonical, no clearnet sibling. The family-alignment resolver (utils/tls_common.py:align_domain_to_consumer, wired intoplugins/lookup/tls.py) correctly bails in that case, so a clearnet-pinned consumer still receives an onion URL it can neither resolve nor reach. First hard evidence:web-app-fediwallvariant 2 (tor=false) rendersmicroblog.<onion>intowall-config.json.servers; the clearnet browser (no SOCKS) times out waiting for mastodon wall items (test-walls-surface-posts.js:24, deterministic across retries). The same class is expected to keepweb-app-bigbluebutton,web-app-nextcloud,web-app-opentalkandweb-app-jitsired (clearnet-pinned apps whose peer refs — OIDC/cdn/matomo/logout — resolve onion-primary). Fix direction: providers must publish BOTH families (clearnet sibling alongside the onion canonical) so the resolver has something to align to; includes re-applying the deferredKC_HOSTNAMEonion-gate for Keycloak that was dropped from the earlier bundle because it is only needed once dual-family exists. -
joomla local-login fallback spec —
test-oidc-fallback.js:52(the?fallback=localemergency hatch: local Joomla admin form login must reach the control panel). Root cause UNCONFIRMED. It is independent of the fixed OIDC-login spec: the fallback path short-circuits before the plugin's server-side discovery, so the committedextra_hostsfix does not cover it. Thesecure => truesticky-cookie hypothesis was rejected (.onionis a potentially-trustworthy origin and the e2e Firefox setsdom.securecontext.allowlist_onions, so Secure cookies are accepted over plain-http onion). Next step when it fails again post-fix: isolate the post-submit URL — Keycloak redirect (cookie lost) vs. form reject vs. slow control-panel render. -
matomo container health flake (checkmk batch) — in the checkmk job the 4th deploy play failed at
Wait for Matomo container to be healthywithcontainer inspect: map has no entry for key "State"for the whole retry window (container started, then vanished — likely crash + prune). Plays 1–3 in the SAME job deployed matomo healthy, so classified transient (resource/prune pressure after ~3h). No code fix derivable. If it recurs, investigate as a real matomo crash/OOM (container logs, mem_limit). -
server-side OIDC reachability candidates — joomla failed because its app container performs server-side OIDC discovery against
http://auth.<onion>without anextra_hostsmapping. Roles with the same mechanic and nocontainer_extra_hostslookup yet (fix is the same one-line lookup, apply on CI evidence): wordpress (daggerhart plugin) and mediawiki (PluggableAuth) are structurally identical PHP in-app plugins (high likelihood); discourse is now confirmed and pinned (run 33445831564, job Nextcloud#7); jenkins, jira, confluence, odoo, openwebui, pretix, zammad, semaphore, jellyfin, listmonk, xwiki, mastodon consume the issuer server-side too (unverified network path). oauth2-proxy-based apps are NOT affected (proven green: prometheus admin SSO). Two names have left this list on evidence: mobilizon got the lookup in0e39f3fadafter its code-to-token call raised OAuth2.Error Connection refused twenty-four times, and gitlab was NEVER a member - run 31756560361 shows it resolving and connecting (peeraddr=172.30.0.10:443); its failure was the openid_connect gem rebuilding the discovery URL over https regardless of the issuer scheme, fixed in2389b6e38. -
baseline exclusions —
web-app-fiderandweb-app-bookwyrm(also keycloak-job, n8n) were red before the tor branch and stay out of scope for it; bookwyrm fails its oauth2 trusted-header session spec, fider its baseline. Fix separately from the onion work. espocrm has left this list: its onion variant failed in the shared admin persona (fixed inb97cf8888) and its clearnet variant returns HTTP 500 on GET /api/v1/App/user, cause still open. -
test-development environment jobs — all 5 distro jobs (arch, debian, ubuntu, fedora, centos) hit the 4h30m cap under congestion while still progressing (playwright image pull). Environmental, no code fix - distinct from the distro sweep's own budget, which did have one:
508669809books a budget SIGKILL as skipped, whichad9222630had only done for SIGTERM; note that onion e2e inherently lengthens the routine (×5 onion timeouts, circuit waits), so under congestion these jobs are the first to hit the cap.