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 # 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) ## 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 - **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 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` **Date:** 2026-06-26 · **Repo:** `app-catalog-felhom.eu` (catalog-only) · **Commit:** `2d5b835` (template)
**Guest:** 9201 (`demo-felhom`) on `felhom-pve` · **Controller:** v0.84.0 (unchanged — reuses its `initial_credentials` reader) **Guest:** 9201 (`demo-felhom`) on `felhom-pve` · **Controller:** unchanged
## Goal ## Changes (3, catalog-only)
Replace Crafty's auto-generated, ugly random admin password with a clean **felhom-generated** one, - **A — image bump**: `crafty-4:4.4.8`**`4.10.7`** (confirmed latest stable in the GitLab registry;
using the same seeding pattern as gokapi (consistency), while keeping it visible on the app page. 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
## Root mechanism (discovered in Crafty source) `network_mode: host`; Traefik labels + python3 healthcheck unchanged.
`main_models.default_settings` reads `app/config/default.json` on fresh install; the image ships - **C — app-page guidance** (`.felhom.yml`): port-range usage + LAN connection (manual IP:port) +
`config_original/default.json = {"username":"admin","password":"crafty"}` — 6 chars, below Crafty's internet/port-forward note, in `first_steps`/`prerequisites` (the only rendered AppInfo fields).
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).
## Verification (live, guest 9201)
| Check | Result | | Check | Result |
|---|---| |---|---|
| Fresh install, **no "Default password too short"** | ✅ Crafty used our seeded password | | Image + health | `crafty-4:4.10.7`, `Up (healthy)` (python3 TLS healthcheck passes) |
| `default.json` in volume | `{"username":"admin","password":"<seeded>"}` | | Public URL | `minecraft.demo-felhom.eu`**302** (prior 502 fix holds) |
| **Crafty API login** `admin`/seeded | **HTTP 200 + token** (gold standard) | | **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. |
| Stray `default-creds.txt` random pw | **401 rejected** — non-functional artifact (see note) | | Migration | clean from 4.4.8 — "Crafty has fully started"; no traceback (but see TOTP caveat) |
| `app.yaml` | `CRAFTY_PASSWORD: ENC:…` (encrypted at rest) + in `locked_fields` | | Ports published | `0.0.0.0:25565-25575->25565-25575/tcp` (only host-bound range; others are image EXPOSEs) |
| App-page card | shows the seeded password (from `default.json`) | | **Guest network mode** | **bridged** (net0 → vmbr0), own LAN IP **192.168.0.121** (DHCP) — direct LAN reach, no host NAT forward |
| Public URL `minecraft.demo-felhom.eu` | **302** | | **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) Reachability used synthetic listeners on the range ends (the prior fresh-redeploy removed the old test
Crafty still writes `default-creds.txt` with a *different* random password during init even though it server). A real Minecraft-client join is the optional gold standard (not performed; Crafty's first server
used our `default.json`. That password is **non-functional** (login → 401) and the file is **not** shown binds `0.0.0.0:25565` by default).
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.
## Consistency ## ⚠ Key finding — in-place upgrade locks out the admin (TOTP)
crafty now matches gokapi: a felhom-generated, locked, `password`-type deploy field set at deploy time — An **in-place** 4.4.8→4.10.7 upgrade of the existing seeded install **locked out admin login** (401
plus the app-page card (v0.84.0 reader) so the initial login is also visible there. `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.