Files
felhom-controller/REPORT.md
T
admin eb3bf4a391 @
docs: REPORT covers v0.129.0 (F-B/F-A/F-C fixes, red-proofs, both guests live 0.129.0)

Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd
@
2026-07-14 09:55:53 +02:00

5.2 KiB
Raw Blame History

REPORT — CAMPAIGN-4 fixes: rate-limiter key (F-B) + volume-blind estimate (F-A) + no-op claim status (F-C)

Date: 2026-07-14 · Version: controller v0.129.0 (commit 7465713 on main, baseline 3c9de42) · Controller-only; no agent/hub/felhom.eu change.

Baselines (verified live at start)

  • felhom-controller main @ 3c9de42 (docs commit on top of d752f15), v0.128.1 → v0.129.0.
  • Demo guest 9201 was 0.128.1; drill guest 9201 was 0.128.0 (CAMPAIGN-4 DEV-2) — both brought to 0.129.0.

Files changed

  • controller/internal/web/claim.gorequestIPclientIP (net.SplitHostPort host, XFF first-hop, raw fallback); call sites updated.
  • controller/internal/web/auth.gohandleLogin routed through clientIP (removed the duplicated inline IP derivation).
  • controller/internal/web/escrow_handlers.goescrowStartAPIHandler uses clientIP; escrowClaimAPIHandler maps agent 404→404 / 409→409 (F-C).
  • controller/internal/appexport/estimate.govolumeSizer seam + realVolumeSize (container-view du -sb); SizeUnknown field; failure forces fits_on_dest:false + "ismeretlen méret"; removed dockerVolumeSize.
  • controller/internal/appexport/export.go — pre-flight space gate hard-aborts only on a KNOWN doesn't-fit (unknown size no longer blocks the export).
  • Tests: controller/internal/web/ratelimit_ip_test.go (new), controller/internal/appexport/estimate_volsize_test.go (new), controller/internal/web/escrow_wizard_test.go (+3 subtests).
  • CHANGELOG.md (v0.129.0), controller/README.md (anti-brute-force source-key note), this REPORT.md.

Per-commit

  • 7465713 — v0.129.0 (all three fixes + tests + docs). One commit per the trunk-based rule.

Tests + red-proofs (all run → fail-on-revert → restore recorded)

F-B (ratelimit_ip_test.go, 6):

  • TestLoginRateLimit_DirectDistinctPorts_Limited — 6 fails over distinct ports, no XFF → limited on 6. PASS.
  • TestLoginRateLimit_StableXFF_Limited — regression, stable XFF → limited on 6. PASS.
  • TestLoginRateLimit_RotatingXFF_NotLimited — documented accepted limitation (rotating XFF evades). PASS.
  • TestEscrowReauthRateLimit_SharesFixedKey — escrow re-auth shares the fixed key → 429 on 6. PASS.
  • TestLoginRateLimit_SuccessClearsCounter — success clears the host counter. PASS.
  • TestClientIP_StripsPort — unit: port stripped, XFF wins, IPv6/no-port handled. PASS.
  • Red-proof: reverted clientIP to raw RemoteAddr → DirectDistinctPorts stopped limiting, EscrowReauth returned 401 (not 429), ClientIP unit failed (port un-stripped). Restored → green.

F-A (estimate_volsize_test.go, 3):

  • TestEstimate_VolumeSize_RealNotZero — injected 2 GiB → DataSizeBytes=2 GiB, GB-scale human (not 0/"3.6 KB"). PASS.
  • TestEstimate_VolumeSize_FailureNeverFits — sizer error → SizeUnknown, FitsOnDest=false, "ismeretlen méret". PASS.
  • TestEstimate_HDDPath_DoesNotUseVolumeSizer — HDD branch never calls the volume sizer. PASS.
  • Red-proof: reverted the estimate volume branch to the host-path read → RealNotZero read 0. Restored → green.

F-C (TestEscrowClaim_ProxySemantics +3):

  • no_active_ceremony_404_not_502 — agent 404 → clean 404 "Nincs aktív helyreállítási folyamat…". PASS.
  • conflict_409 — agent 409 → 409. PASS.
  • unreachable_stays_502 — status 0 → 502 (unchanged). PASS.
  • success / gone (existing) still green.
  • Red-proof: removed the 404 mapping → the no-ceremony claim returned 502. Restored → green.

Test counts / gate

Full module green gate: go build ./... && go vet ./... && go test ./...ALL GREEN (all packages ok). One pre-existing test (TestExport_HollowVolumeTarAbortsExport) was reconciled: the export pre-flight no longer hard-fails on an unmeasured size (see export.go change). New tests: 9 top-level + 3 subtests, all red-proofed.

Deployed versions

  • Image gitea.dooplex.hu/admin/felhom-controller:0.129.0 (digest sha256:957e0818…), pushed from 180.
  • Demo guest 9201: 0.129.0, healthy. Drill guest 9201: 0.129.0, healthy (was 0.128.0 — DEV-2 closed).

Live verification

  • F-B (nice-to-have, run): 6 direct wrong-password logins on the drill guest (loopback via docker exec curl, distinct ephemeral ports, no XFF) on live 0.129.0 → attempts 15 "Hibás jelszó", attempt 6 "Túl sok sikertelen próbálkozás". Pre-fix (CAMPAIGN-4) this never limited. (Transiently locks 127.0.0.1 for 1 min — expected.)
  • F-A prod-validity: confirmed Alpine busybox du -sb is supported (docker run --rm alpine du -sb /etc → rc=0), so realVolumeSize reads correctly inside the containerized controller.

Observations

  • The .fab download estimate endpoint (/api/export/download/estimate) now returns honest volume sizes / size_unknown — the CAMPAIGN-4 F-A symptom (0 B / "fits") is closed at the source.
  • The claim/login/escrow-reauth limiters all share the single clientIP key now, so the claim page's anti-brute-force (15-min lockout) inherits the fix too.
  • Scope held: no captcha/lockout/persistence added, loginMaxAttempts/window untouched, XFF trust untouched (commented), export path + HDD estimate branch + 410/unreachable claim cases unchanged.