Commit Graph
15 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5.5 46fe011796 fix(web-app-fusiondirectory): lift the PHP memory_limit in the FPM pool
#1259 moved the interim CVE-2026-109618 mitigation (memory_limit = -1)
out of the shared hardening.ini into memory-unlimited.ini and mounted it
only in the roles whose images it had inventoried. Its branch predates
#1263, which gave FusionDirectory the php_hardening mount, so after both
merged FusionDirectory ran with the image default of 128M again.

A conf.d mount would not have fixed it: the nfrastack image writes
php_admin_value[memory_limit] into its FPM pool
(/etc/php7/pools.d/www/www-settings.conf) from PHP_MEMORY_LIMIT, and a
pool php_admin_value outranks every conf.d ini. Measured on main: CLI
128M, FPM 128M. So even before #1259 the hardening ini only ever lifted
the CLI limit.

nfrastack/fusiondirectory:1.5 runs PHP 7.4.33 on Alpine 3.15, end of
life and never patched, so the role carries the mitigation until it
moves to a PHP 8 image.

- Set PHP_MEMORY_LIMIT=-1 in templates/env.j2. The image seds it into
  php.ini and the pool, so CLI and FPM both report -1.
- The root TODO lists FusionDirectory with the image and the reason it
  uses the variable instead of the mount; the role TODO names which
  setting carries which CVE mitigation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 08:57:44 +01:00
kevinveenbirkenbachandClaude Opus 4.8 15e7647d2f refactor(env): central TZ+LANG base included by every role env.j2
New roles/sys-svc-container/templates/env.j2 sets TZ={{ HOST_TIMEZONE }} and LANG=C.UTF-8. Every role env.j2 includes it at the top; it renders via stack_host_template, the same engine that resolves the includes in compose.yml.j2, so it works in both compose and swarm. TZ/LANG are removed from the individual role env.j2 so each value stays single-source.

New lint tests/lint/ansible/test_env_base_include.py verifies every role env.j2 includes the base and never re-sets a base-owned key (keys derived from the base file).

mattermost and gitea meta/volumes.yml drop the /etc/timezone host-path bind: swarm hard-rejects a task whose bind source is missing on the node (Debian-trixie nodes have no /etc/timezone). TZ now comes from the base env. /etc/localtime bind also dropped; the container timezone follows TZ.

Non-directive comments were removed from the touched env.j2 (banners, restatements, reference URLs, narration) so the changed files pass the comment-lint; only tool directives remain.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 22:13:57 +02:00
kevinveenbirkenbachandClaude Opus 4.7 c26c514529 fix(web-app-fusiondirectory/env): match upstream LDAP01_* naming
The nfrastack/fusiondirectory image (1.5-3.0.0) initializes LDAP
profiles in `/container/functions/40-fusiondirectory` via
`create_profile(i)` with `i=$(printf "%02d" $i)`, so profile 1 is
expected as `LDAP01_*`. The env.j2 template was rendering `LDAP1_*`
(single digit), which the init script never consumed:

  $ docker logs fusiondirectory
  ** [ERROR] ** [fusiondirectory] No 'Server Name' Entered\! - Set '$LDAP01_NAME'
  ** ERROR - Some initialization scripts haven't completed:
            40-fusiondirectory

The container then ran without an LDAP binding, so the application
itself returned `FATAL: Error when connecting to LDAP server
"ldap://openldap:"` (with a dangling colon because `LDAP01_PORT`
was also missing).

In variant 0 the failure stayed invisible because oauth2-proxy
fronts the fd vhost and intercepts every unauthenticated request
with a redirect to Keycloak — the reachability probe got `200 OK`
from the proxy even though the upstream was dead. Variant 1
disables oauth2, the probe hits fd directly, and the matrix-deploy
aborts with `502 Bad Gateway`.

Two changes:

- rename `LDAP1_*` to `LDAP01_*` for every LDAP env-var the role
  exposes, matching the image's zero-padded convention.
- add the missing `LDAP01_PORT` from `svc-db-openldap`'s
  `services.openldap.ports.local.ldap` so the rendered URI carries
  a port (`ldap://openldap:389` instead of `ldap://openldap:`).

Verified in-container: after patching the live `.env` with the new
names + port and `docker compose up -d --force-recreate
fusiondirectory`, the container reports `healthy` and
`wget https://fd.infinito.example/` returns `200 OK` with
`<title>FusionDirectory - Sign in</title>`. Before the fix the
same probe was `502` (variant 1) or a Keycloak login page hiding
the broken upstream (variant 0).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 13:13:54 +02:00
kevinveenbirkenbachandClaude Opus 4.7 bad8a5e5c5 fix(web-app-fusiondirectory): dotenv_quote on password fields in env.j2
The administrator password literally starts with `'` (verified via cat
on the rendered .env/env: `FUSIONDIRECTORY_ADMIN_PASS='$tr0ng€xampl3PW\!`),
which Docker Compose's .env parser interprets as an opening single
quote and fails with `unterminated quoted value`. Wrapping both
credential fields with the existing `| dotenv_quote` filter
(plugins/filter/dotenv.py — double-quote + escape `$`/`\\`/`"`) makes
the value compose-safe. Matches the pattern used in
web-app-{mastodon,listmonk}/templates/env.j2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:15:04 +02:00
kevinveenbirkenbachandClaude Opus 4.7 2e3e6412eb fix(web-app-fusiondirectory): rename LDAP_* env vars to LDAP1_*, extract into env.j2
40-fusiondirectory init script (sanity_var checks at lines 354-358 of
/etc/cont-init.d/40-fusiondirectory in the image) requires the numbered
LDAP1_* names because the script supports multiple LDAP servers via a
`for (( i = 1; i <= NUM; i++ ))` loop. The previous LDAP_* names caused
`sanity_var LDAP1_ADMIN_PASS "Admin Password"` to abort init, leaving
the container in an unhealthy state.

Also moves the `environment:` block out of compose.yml.j2 into the
canonical `templates/env.j2`; the env_file is auto-wired via
sys-svc-container/templates/base.yml.j2 once `has_env()` is true.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-17 01:15:03 +02:00
kevinveenbirkenbachandClaude Opus 4.7 91c57e0471 feat(req-013): alpha-to-beta promotion for 13 in-scope roles
Promote akaunting, baserow, bluesky, bookwyrm, bridgy-fed, flowise,
fusiondirectory, jenkins, joomla, minio, postmarks, libretranslate, xmpp
from `lifecycle: alpha` to `lifecycle: beta` per requirement 013.
socialhome stays alpha (operator-excluded).

SSO/LDAP integration per role:
- minio + jenkins + joomla + fusiondirectory: native first-party paths
  (MINIO_IDENTITY_OPENID/_LDAP, oic-auth + ldap + role-strategy JCasC,
  plg_system_keycloak, LDAP-as-storage). All V0+V1 verified.
- akaunting, baserow, bookwyrm, flowise, postmarks, libretranslate:
  oauth2-proxy perimeter gate as universal glue path. Native in-app
  OIDC integrations deferred to follow-up issues #219 (Baserow),
  #220 (BookWyrm), #221 (Akaunting).
- bluesky: variant A+ login-broker (oauth2-proxy → broker → social-app)
  with AES-256-GCM-encrypted PDS app-passwords cached in-process
  (Keycloak user-attribute storage caused LDAP federation conflicts
  that broke other realm-clients' OIDC logins).
- xmpp: native ejabberd LDAP backend for both variants
  (mod_oauth2_client is contrib-only and deferred).
- bridgy-fed: documented SSO/LDAP/RBAC exception (federated source-
  platform auth, no local user table).

Project-wide bugfixes:
- web-app-oauth2-proxy: propagate X-Forwarded-User /
  -Preferred-Username / -Email / -Groups via auth_request_set bridge
  (set_xauthrequest + pass_user_headers in cfg + nginx headers in
  following_directives.conf). Benefits all 8 oauth2-proxy consumers.
- scripts/tests/deploy/local/deploy/fresh-kept-app.sh: bake
  `RUNTIME=dev` into the matrix-init host vars so the Playwright
  E2E gate fires (was silently skipped on kept-deploys).

From-scratch role implementations: jenkins (JCasC + plugin pre-bake +
JVM cacerts CA-trust entrypoint), fusiondirectory (LDAP-as-storage
compose), xmpp (ejabberd LDAP backend ejabberd.yml).

Verification:
- Per-role baseline: each in-scope role passed standalone V0/V1
  Playwright suites green.
- Multi-app fresh-purged-apps over all 13 in-scope roles
  (FULL_CYCLE=true): Pass 1 sync + Pass 2 async both `failed=0`,
  every role's Playwright suite green.

Doc 013 acceptance section reflects the divergences (oauth2-proxy
glue path, in-memory bluesky cache, deferred contrib modules) with
explicit follow-up issue references.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 12:47:01 +02:00
kevinveenbirkenbach 3fa7887dc8 Added whitespaces for better readability 2026-02-06 16:21:10 +01:00
kevinveenbirkenbach 5100c2c1ce refactor(config): replace get_app_conf filter with config lookup
Replace usages of the get_app_conf filter with the config lookup plugin
across roles and templates. Adjust quoting where required to keep YAML
and Jinja syntax valid. No functional changes intended.

https://chatgpt.com/share/69860678-cef8-800f-8402-7fe6231fdc2d
2026-02-06 16:19:14 +01:00
kevinveenbirkenbach 8b1ae03e77 fix(env): prevent dotenv_quote double-quoting in env.j2 templates
- Replace `"{{ ... | dotenv_quote }}"` with `{{ ... | dotenv_quote }}` across roles
- Update integration test to enforce pure Jinja + dotenv_quote and forbid wrapped quotes

https://chatgpt.com/share/6974e6c6-51b8-800f-80a1-a76f885cf57e
2026-01-24 16:35:27 +01:00
kevinveenbirkenbach fdb2683ddb test(env): enforce dotenv_quote + double quotes for password vars in env.j2 templates
https://chatgpt.com/share/6974cbac-023c-800f-8198-fd85df2aa7bc
2026-01-24 15:32:33 +01:00
kevinveenbirkenbach aa7d0c642c feat(dotenv): add dotenv_quote filter and enforce quoted password vars in env.j2
https://chatgpt.com/share/6974cbac-023c-800f-8198-fd85df2aa7bc
2026-01-24 15:22:19 +01:00
kevinveenbirkenbach cb66fb2978 Refactor LDAP variable schema to use top-level constant LDAP and nested ALL-CAPS keys.
- Converted group_vars/all/13_ldap.yml from lower-case to ALL-CAPS nested keys.
- Updated all roles, tasks, templates, and filter_plugins to reference LDAP.* instead of ldap.*.
- Fixed Keycloak JSON templates to properly quote Jinja variables.
- Adjusted svc-db-openldap filter plugins and unit tests to handle new LDAP structure.
- Updated integration test to only check uniqueness of TOP-LEVEL ALL-CAPS constants, ignoring nested keys.

See: https://chatgpt.com/share/68b01017-efe0-800f-a508-7d7e2f1c8c8d
2025-08-28 10:15:48 +02:00
kevinveenbirkenbach 5c9ca20e04 Optimized keycloak variables 2025-08-17 11:40:15 +02:00
kevinveenbirkenbach 756597668c Semi bsr for applications[] to prevent heavy to debug bugs in j2 - part 1 2025-07-13 15:11:38 +02:00
kevinveenbirkenbach 563d5fd528 Huge role refactoring/cleanup. Other commits will propably follow. Because some bugs will exist. Still important for longrun and also for auto docs/help/slideshow generation 2025-07-08 23:43:13 +02:00