From 0012d66fc36a4fb13bec6659c3d728e87eeb8853 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Fri, 26 Jun 2026 11:48:53 +0200 Subject: [PATCH] docs: CHANGELOG + REPORT for crafty 4.10.7 bump, port range, guidance; flag in-place-upgrade TOTP lockout --- CHANGELOG.md | 22 +++++++++++++ REPORT.md | 87 ++++++++++++++++++++++++++-------------------------- 2 files changed, 65 insertions(+), 44 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cff7249..4a16d7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## 2026-06-26 — crafty-controller: image bump 4.4.8→4.10.7 + publish Java port range + connection guidance +- **Image bump** `crafty-4:4.4.8` → `4.10.7` (latest stable; 4.10.8/4.11.0 don't exist in the registry). + 6 minor versions of fixes incl. security CVEs. **Java 25 verified present** in 4.10.7 + (`/usr/lib/jvm/java-25-openjdk-amd64`, default `java -version` = openjdk 25.0.3; 8/11/17/21 also + available) — so the latest-Minecraft (`26.x`, needs Java 25) blocker is resolved. Healthcheck + Traefik + https-backend labels unchanged (Crafty still serves HTTPS on 8443). +- **Published the Java game-port range** `25565-25575:25565-25575` (TCP, 11 ports = up to 11 Java + servers; first server 25565, rest 25566–25575). No `network_mode: host` (would break Traefik routing). + Bedrock UDP 19132 intentionally out of scope. +- **App-page guidance** (`.felhom.yml` first_steps + prerequisites): how to set the server port within + 25565–25575, how to connect on the LAN (manual IP:port — "scan for LAN" won't auto-list), and that + internet access needs operator port-forwarding. (Static text — can't show the live LAN IP.) +- **Live-verified on guest 9201:** 4.10.7 healthy; public URL 302; fresh deploy → admin login works (200); + port range reachable from a LAN host at the guest's bridged IP `192.168.0.121:25565`/`:25575` (negative + control: `:25600` closed). +- **⚠ Upgrade caveat (in-place only):** an in-place 4.4.8→4.10.7 upgrade of an existing seeded install + **locked out the admin** — 4.10.7 treats any `totp_data` row as active 2FA (`len(totp_user)>0`), and the + old install carried an unconfigured TOTP secret, so password-only login returns 401 despite the correct + password (argon2 hash still verifies). **Fresh 4.10.7 deploys are clean** (0 TOTP rows, login works) — + the only existing install (the demo) was fresh-redeployed. Any future in-place upgrade of a pre-4.10 + Crafty needs its unconfigured TOTP rows cleared (or the user logs in with a recovery code). + ## 2026-06-26 — crafty-controller: seed a felhom-generated admin password (replaces Crafty's ugly random one) - **crafty-controller**: instead of reading Crafty's auto-generated (long, symbol-laden) random admin password, we now **seed** a clean felhom-generated one — same pattern as gokapi, so initial passwords are diff --git a/REPORT.md b/REPORT.md index 63190b8..a0d1a26 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,51 +1,50 @@ -# REPORT — crafty-controller: seed a felhom-generated admin password (gokapi pattern) +# REPORT — crafty-controller: image bump 4.4.8→4.10.7 + Java game-port range + connection guidance -**Date:** 2026-06-26 · **Repo:** `app-catalog-felhom.eu` (catalog-only) · **Commit:** `5a403d1` -**Guest:** 9201 (`demo-felhom`) on `felhom-pve` · **Controller:** v0.84.0 (unchanged — reuses its `initial_credentials` reader) +**Date:** 2026-06-26 · **Repo:** `app-catalog-felhom.eu` (catalog-only) · **Commit:** `2d5b835` (template) +**Guest:** 9201 (`demo-felhom`) on `felhom-pve` · **Controller:** unchanged -## Goal -Replace Crafty's auto-generated, ugly random admin password with a clean **felhom-generated** one, -using the same seeding pattern as gokapi (consistency), while keeping it visible on the app page. - -## Root mechanism (discovered in Crafty source) -`main_models.default_settings` reads `app/config/default.json` on fresh install; the image ships -`config_original/default.json = {"username":"admin","password":"crafty"}` — 6 chars, below Crafty's -8-char minimum, so Crafty rejected it and generated a random password into `default-creds.txt`. We can't -"lengthen" that internal fallback — we **seed** a valid `default.json` instead. - -## Change (catalog-only) -- **`docker-compose.yml`**: new `CRAFTY_PASSWORD` env + an **entrypoint** wrapper that overwrites - `config_original/default.json` with `{"username":"admin","password":"$CRAFTY_PASSWORD"}` before exec'ing - the image launcher (`/crafty/docker_launcher.sh -d -i`). On fresh install the launcher copies our - template into the config volume → Crafty creates `admin` with our password. -- **`.felhom.yml`**: new `CRAFTY_PASSWORD` deploy field (`type: password`, `generate: password:24`, - `locked_after_deploy` — mirrors gokapi's `GOKAPI_PASSWORD`, alphanumeric so JSON/shell-safe). Repointed - `initial_credentials.file` `default-creds.txt` → `default.json` so the controller's "Kezdeti belépési - adatok" card shows the **seeded** password. -- No controller change: the deploy flow already injects/decrypts password deploy-fields into the compose - env (`stackEnv`), and v0.84.0's `initial_credentials` reader already parses `default.json`. - -## Live validation (guest 9201 — fresh install via the real pipeline) -Removed crafty + wiped its volumes, then deployed via `POST /api/stacks/crafty-controller/deploy` with -`{DOMAIN, SUBDOMAIN, CRAFTY_PASSWORD}` (clean 24-char alphanumeric). +## Changes (3, catalog-only) +- **A — image bump**: `crafty-4:4.4.8` → **`4.10.7`** (confirmed latest stable in the GitLab registry; + 4.10.8/4.11.0 do not exist). Security CVEs + Java. +- **B — publish game ports**: added `ports: ["25565-25575:25565-25575"]` (TCP, 11 Java servers). No + `network_mode: host`; Traefik labels + python3 healthcheck unchanged. +- **C — app-page guidance** (`.felhom.yml`): port-range usage + LAN connection (manual IP:port) + + internet/port-forward note, in `first_steps`/`prerequisites` (the only rendered AppInfo fields). +## Verification (live, guest 9201) | Check | Result | |---|---| -| Fresh install, **no "Default password too short"** | ✅ Crafty used our seeded password | -| `default.json` in volume | `{"username":"admin","password":""}` | -| **Crafty API login** `admin`/seeded | **HTTP 200 + token** (gold standard) | -| Stray `default-creds.txt` random pw | **401 rejected** — non-functional artifact (see note) | -| `app.yaml` | `CRAFTY_PASSWORD: ENC:…` (encrypted at rest) + in `locked_fields` | -| App-page card | shows the seeded password (from `default.json`) | -| Public URL `minecraft.demo-felhom.eu` | **302** | +| Image + health | `crafty-4:4.10.7`, `Up (healthy)` (python3 TLS healthcheck passes) | +| Public URL | `minecraft.demo-felhom.eu` → **302** (prior 502 fix holds) | +| **Java 25 present?** | **YES** — `/usr/lib/jvm/java-25-openjdk-amd64`, default `java -version` = openjdk 25.0.3 (also 8/11/17/21). Latest-MC (26.x) blocker resolved. | +| Migration | clean from 4.4.8 — "Crafty has fully started"; no traceback (but see TOTP caveat) | +| Ports published | `0.0.0.0:25565-25575->25565-25575/tcp` (only host-bound range; others are image EXPOSEs) | +| **Guest network mode** | **bridged** (net0 → vmbr0), own LAN IP **192.168.0.121** (DHCP) — direct LAN reach, no host NAT forward | +| **LAN reachability** | from build server 192.168.0.180: `192.168.0.121:25565` **OPEN**, `:25575` **OPEN**; `:25600` (outside range) **closed** (negative control) | +| Fresh deploy login | admin / seeded pw → **200 + token** | +| App-page card + guidance | shows the seeded admin password; "25565" guidance rendered | -## Known quirk (documented, low-risk) -Crafty still writes `default-creds.txt` with a *different* random password during init even though it -used our `default.json`. That password is **non-functional** (login → 401) and the file is **not** shown -anywhere in the felhom UI (the card reads `default.json`; FileBrowser is scoped to userdata, not -`/crafty/app/config`). Left as-is — a post-boot cleanup would be a racy entrypoint hack for an invisible -file. The canonical, working password is the seeded one shown on the app page. +Reachability used synthetic listeners on the range ends (the prior fresh-redeploy removed the old test +server). A real Minecraft-client join is the optional gold standard (not performed; Crafty's first server +binds `0.0.0.0:25565` by default). -## Consistency -crafty now matches gokapi: a felhom-generated, locked, `password`-type deploy field set at deploy time — -plus the app-page card (v0.84.0 reader) so the initial login is also visible there. +## ⚠ Key finding — in-place upgrade locks out the admin (TOTP) +An **in-place** 4.4.8→4.10.7 upgrade of the existing seeded install **locked out admin login** (401 +`INCORRECT_CREDENTIALS`) **despite the correct password** (the stored argon2 hash verifies True). Root +cause: 4.10.7's login treats `len(user.totp_user) > 0` as "2FA enabled", and the old install carried an +**unconfigured** `totp_data` row (a TOTP secret the customer never set up) — so password-only login is +rejected. A **fresh 4.10.7 deploy has 0 TOTP rows and logs in fine** (verified). The demo (the only +existing install) was fresh-redeployed, so no live customer is affected; the catalog bump is safe for new +deploys. + +## Observations (documented, NOT acted on) +1. **In-place upgrade remediation**: upgrading any pre-4.10 Crafty needs its unconfigured `totp_data` + (+`totp_recovery`) rows cleared, or the user logs in with a recovery code, else lockout. A safe + migration helper (clear TOTP rows that were never user-activated) would be a Crafty-side or + entrypoint concern — own task; currently moot (no other installs). +2. **Java 25 present** → no custom image needed to run latest MC; the earlier "may need a custom + temurin-25 image" worry is resolved by 4.10.7 itself. +3. **Dynamic connection panel**: render the live LAN IP + published range + per-server port on the app + page (vs static guidance) — a controller feature, own task. +4. **Bedrock (UDP 19132)** — out of scope; own task if Bedrock enters product scope. +5. **Internet exposure** (operator port-forward vs Felhom-operated relay vs Tailscale) — open design call.