TLS-Gate v3.3.0: optionales neues TOTP-QR bei jedem Passwort-Login, Login-Doktor

Von: Branko → OZMAI
Stand: 3. Oktober 2026
Typ: EXTERNAL_SOURCE (Inbox-Regel §3 — keine automatische Geltung, kein Brain-Status)
Charakter: STAND + PRÜFFALL-HINWEIS. Setzt 2026-10-02_TLS-GATE-V3-2-1-DUBLETTEN-NACHTRAG_BRANKO.md fort; ersetzt keine Aussage der Vorgänger.
Quelle: Repo TLS-Gate-Mock-Pipeline (git.crumbforest.org), Tag v3.3.0 = Commit c5d8695 (Vorgänger v3.2.1 = 98a4f38).
Belege: tests/test_mfa.sh (28), tests/test_auth.sh (76), VM-Suiten run 52, p3 48, p4 54, p5 31, p6 22.

Legende: ✅ real/gebaut · 🧪 gebaut, getestet, nicht live · 🛠 spezifiziert · ⬜ OPEN · ❓ UNKNOWN

Keine Zugangsdaten, keine Kunden-Domains, keine Reseller-IDs.


1. Anlass

Ein vollständiger Durchlauf in der VM gelang (zwei Gruppen angelegt, SOAP-Zugang geladen, Deploy-ZIP). Der Fehlversuch davor war ein fehlender Port in hosts/URL, kein Fehler im Code. Daraus zwei Wünsche: (a) bei jedem Passwort-Login soll ein neues TOTP-Secret samt QR in der DB entstehen, (b) ein Werkzeug, das solche Anmeldeprobleme benennt statt sie raten zu lassen.

2. Was gebaut ist

  • 🧪 TLSGATE_MFA_QR_EVERY_LOGIN=1 (src/Auth/Auth.php): nach dem Passwort wird ein neues Secret erzeugt und versiegelt abgelegt, totp_enabled=0 bis zur Bestätigung. Erst der Code des neuen Secrets meldet an; das alte ist sofort ungültig. Standard: aus.
  • 🧪 Nebenwirkung, gewollt: totp_last_step wird zurückgesetzt, ein eben benutzter Code ist nach Logout/Login nicht mehr durch die Replay-Sperre blockiert.
  • 🧪 docker_vm: instance.sh <name> [mock] [qrlogin] setzt die Variable im Pool. Bewusst nicht fest im Template, weil die Abnahmen sich mit user code am bestehenden Secret anmelden. Ohne qrlogin entfällt die Zeile beim nächsten Lauf.
  • 🧪 bin/login.doktor.sh [URL] [Instanz] [E-Mail]: nur lesend, kein Passwort. Prüft Port, ob der Container-nginx antwortet, Host-Header, login.php, CSRF-Token, __Host--Cookie über http, Pool-Schalter, Konto (gesperrt, deaktiviert, mfa-offen) und die letzten auth.*-Audit-Einträge (bad_password, bad_code, blocked_ip).

3. Einordnung als Prüffall (Branko, nicht OZMAI-Geltung)

Mit dem Schalter erzeugt ein Passwort allein eine neue TOTP-Bindung und zeigt sie an. Wer das Passwort kennt, sieht das QR; TOTP ist dann kein zweiter Faktor mehr, sondern eine Bestätigung des ersten. Das berührt den Kernsatz des Identitäts-Prüffalls („Eine erfolgreiche Prüfung einer Bindung darf nicht stillschweigend eine stärkere Bindung erzeugen“): hier erzeugt eine erfolgreiche Passwortprüfung eine neue Bindung, und die alte wird dabei verworfen. Deshalb: nur Mockup/Demo, im Changelog, README und HANDBUCH so benannt, Standard aus. Ob das als Fall für WORKING_HYPOTHESES/IDENTITAETSBINDUNG_HMAC_NETBOX_TLS_CUSTODY_PRUEFFALL_v0.1.md taugt, entscheidet OZMAI/Alex.

4. Belegt, und was nicht

  • 🧪 test_mfa.sh +4: Passwort-Login zeigt trotz aktivem TOTP ein QR, Secret in der DB neu und totp_enabled=0, Code des neuen Secrets meldet an, danach totp_enabled=1.
  • 🧪 Im Container von Hand: zwei Logins hintereinander, je ein neues Secret, beide 302, danach Status mfa.
  • 🧪 Gesamtlauf am 3.10.: VM-Suiten grün (Zahlen oben), Pool danach wieder ohne Schalter.
  • ❓ Nicht automatisiert abgesichert: die Option qrlogin in instance.sh; es gibt keinen eigenen Test unter docker_vm/tests/. Der Login-Doktor hat ebenfalls keinen Test; er wurde gegen den laufenden Container und gegen falschen Port/Host von Hand geprüft.
  • ❓ Folgefehler im Doktor bei nicht erreichbarem Port: mehrere Befunde kaskadieren (Zähler zeigt dann mehr Probleme als Ursachen).

5. Offene Punkte

  • ⬜ Test für instance.sh … qrlogin in docker_vm/tests/.
  • ⬜ Falls gewünscht statt Schalter: Re-Auth (TOTP erneut) für sensible Aktionen oder kürzere Session-Laufzeit. Die ursprüngliche Frage („2FA nach Session-Laufzeit/Abmeldung zurücksetzen“) war nach Klärung genau der Schalter; die Alternativen sind nicht gebaut.
  • ⬜ .codebase-memory/artifact.json ist lokal geändert und bewusst nicht im Release-Commit.