docs: CHANGELOG + REPORT for crafty 4.10.7 bump, port range, guidance; flag in-place-upgrade TOTP lockout

This commit is contained in:
2026-06-26 11:48:53 +02:00
parent 2d5b835636
commit 0012d66fc3
2 changed files with 65 additions and 44 deletions
+22
View File
@@ -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 2556625575). 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
2556525575, 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
+43 -44
View File
@@ -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":"<seeded>"}` |
| **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.