Nachtrag Branko â TLS-NativePHP_v1: Server-Version, Review-Dummy, Test auf frischer Ubuntu-22.04
Von: Branko / Ansible-Katze â OZMAI
Stand: 14. Oktober 2026
Bezug: 2026-10-13_ANTWORT-OZMAI_TLS-GATE-V3-16-NETBOX-LIVE.md (§3 âein roter Test kann der PrĂŒfer seinâ), Handout HANDOUT_NODE_OHNE_DOCKER.md
Charakter: Befund und Beleg. Keine Aussage ĂŒber die RZ-VM.
1. Was jetzt existiert
Das PHP-Frontend (native_php, v3.16.0) ist als eigenes Repo TLS-NativePHP_v1 herausgelöst und nur noch fĂŒr die Node gebaut:
Ubuntu 22.04, Apache + php-fpm, PHP 8.4, MySQL 8. SQLite, der Mock-Modus (TLSGATE_MOCK) und die Installation im Projektbaum sind
entfernt. Commits 9b7d88f, b734884, b72f32e, 2d9b215, a3b1721, 618216e, 0d7bfc2, 52eefb6, 1860fb8, 369e3d6,
gepusht auf git.crumbforest.org.
Neu: deploy/node/build.sh (Node bauen), review-dummy.sh (Wegwerf-Daten), review-check.sh (Gegenprobe), bin/seed_cli.php
(Beispielbestand in der DB statt Mock-Datei: eigener abgeschalteter Zugang sample, löschbar, im Audit), bin/tg (die CLIs
mit der Umgebung der Instanz aufrufen; ohne TLS_GATE_STATE_DIR endet die CLI jetzt mit Exit 2 und klarer Meldung).
2. Belegt
| Aussage | Beleg |
|---|---|
| 15 Suiten, 0 rot gegen MySQL 8.0.46 (Docker, lokal) | tests/run_all.sh |
build.sh lÀuft auf frischer Ubuntu-22.04 durch, zweimal (zweiter Lauf Àndert nichts); MySQL dort 8.0.x aus dem Ubuntu-Repo, Version nicht festgehalten |
Container mit systemd |
| Doktor nach dem Bau: keine Fehler, 3 Warnungen | bin/TLS-node-doktor.bash |
| Login mit Passwort + TOTP durch Apache â FPM â MySQL | review-check.sh, 49 grĂŒn, 0 rot |
Zwei Gruppen (bwa, ozm), je sechs Benutzer (admin, group_admin, 2Ăuser, readonly, Erst-Login) sehen den Bestand der eigenen Gruppe und keine Order der anderen |
review-check.sh |
Beide MFA-Wege: code (enrolltes Secret) und qr (neues Secret nach jedem Passwort) |
je Gruppe einer, Stand zum Zeitpunkt von review-check.sh; bwa wurde danach ĂŒber die OberflĂ€che geĂ€ndert (§4a) |
Browser-Zugriff https://localhost:8443: Anmeldung admin@bwa.review.test, danach katalog.php, credentials.php, netbox.php, auditlog.php âsieht gut ausâ |
ATTESTED_BY_BRANKO (Seiten per Browser, Inhalte nicht von mir gelesen) |
Drei abgelehnte Codes desselben Kontos (bad_code, 18:42:02, 18:42:27, 18:43:15 UTC) stehen im Audit mit Zeit, Konto und Grund; ZĂ€hler failed_count = 3, Sperre bei 5; Entsperren per CLI |
gesehen in audit_log und users (Container) |
3. Befunde aus MySQL 8.0.46 (vorher nur gegen MariaDB gelaufen)
- Fehler 1419 bei
migratemit getrenntem DDL-Benutzer: Binlog ist an, Trigger brauchenSET_USER_ID(oderlog_bin_trust_function_creators=1). Reproduziert und beides geprĂŒft. - Zweiter
migrate-Lauf und--statusbrachen ab:information_schema.CHECK_CONSTRAINTShat in MySQL 8 keine SpalteTABLE_NAME. - Falscher Abbruch auf frischer DB: MySQL liefert die CHECK-Literale mit Backslash (
\'revoked\'), der Vergleich traf nicht. - Migration
0003hatte dieselben beiden Fehler. Sie war auf MySQL 8 nie gelaufen. Der Upgrade-Pfad 2â7 ist jetzt getestet (aus dem letzten Stand ohne Versionsangabe: Schema == frisch, Daten erhalten). groupsist reserviert (bekannt,35451b0); in vier Test-Suiten (auth,credentials,credentials_ui,katalog) und in
den alten Schema-Fixtures stand es noch unquotiert. Eine dieser Abfragen (test_auth, Dubletten-PrĂŒfung) hĂ€tte bei Fehler
eine leere Antwort mit einer leeren Antwort verglichen und wĂ€re grĂŒn geblieben; gefunden durch Lesen, nicht durch einen roten Test.
4. Ihre Formeln an diesem Lauf
RED_TEST â PRODUCT_DEFECT
Die drei zunĂ€chst roten Suiten (auth, mfa, credentials_ui) waren veraltete Tests: Der MFA-Default fĂŒr neue Gruppen ist
inzwischen qr, die Tests erwarteten code. Das Produkt war nicht kaputt.
DOKTOR_FAIL â PRODUCT_DEFECT
Der Doktor meldete â0 von 16 Triggernâ. In der DB waren alle 16. Der PrĂŒfer lĂ€uft als App-Benutzer und sieht ohne TRIGGER-Recht keine
Trigger in information_schema. Das ist jetzt eine Warnung ânicht sichtbarâ, kein Fehler. Gleiche Fehlerklasse wie der Locale-Fall.
Dazu zwei kleine Verifier-Fehler im Doktor: eine Variable G ĂŒberschrieb die Farbvariable (die Ausgabe zeigte Rechte statt ok),
und stat folgte Symlinks nicht.
LOGIN_OK â IDENTITAET_FESTGESTELLT
Die Testbenutzer sind erzeugt, die Passwörter zufÀllig und im Klartext in einer Datei. Der Test belegt den Mechanismus
(Passwort + zweiter Faktor, Gruppentrennung der Seite), nicht, dass dahinter eine Person steht.
NOT_SEEN â NOT_ACCESSIBLE
âSieht nichts aus Gruppe Xâ ist geprĂŒft fĂŒr die Seite bestand.php per Textmuster der Order-Nummern. Direkte Objektverweise
(IDs in anderen Seiten und Formularen) sind nicht geprĂŒft.
4a. Fall gadmin@bwa.review.test: âAnmeldung fehlgeschlagen oder Konto vorĂŒbergehend gesperrtâ
Die Meldung der OberflÀche unterscheidet falsches Passwort und Sperre bewusst nicht. Das Audit tut es:
| Zeit (UTC) | Eintrag | Quelle |
|---|---|---|
| 18:46:39 | admin.group_mfa ok fĂŒr Gruppe bwa (MFA-Modus geĂ€ndert; neuer Wert nicht festgehalten, Container abgebaut) |
Web |
| 19:30:23 | auth.login fail bad_password |
Web |
| 19:32:46 | admin.user_reset_mfa ok (Admin ĂŒber die OberflĂ€che) |
Web |
| 19:34:00 | auth.login fail bad_password |
Web |
| 19:38:53 â 19:41:04 | cli.user_enroll ok, 2Ă cli.user_code ok |
CLI (root) |
| 19:41:39 | auth.login fail bad_password |
Web |
| 19:51:03 | admin.user_passwd ok (Admin ĂŒber die OberflĂ€che) |
Web |
| 19:52:06 â 19:52:25 | auth.password ok (next: enroll), auth.mfa_enroll ok, auth.login ok |
Web |
| 19:53:19 | auth.logout ok |
Web |
- Belegt: Das Passwort aus der Testdatei passte zum Hash in der DB. Der Server war also nicht der Grund, das eingegebene Passwort
war ein anderes. Konto weder gesperrt (locked_untilleer) noch inaktiv. ZĂ€hler 2 zum Zeitpunkt der PrĂŒfung (ca. 19:37 UTC), danach ein
dritter Fehlversuch (19:41:39); Sperre erst bei 5. - Nicht festgestellt: welches Passwort eingegeben wurde. Das Passwort hat 29 Zeichen und endet auf
-Aa9!; Abtippfehler sind
wahrscheinlich, aber nicht belegt. - Beobachtet, aber vermengt: Nach dem Passwortwechsel durch den Admin (19:51:03) verlangte die App wieder die Einrichtung
(next: enroll), obwohl das Konto vorher per CLI enrollt war. Dazwischen liegt die Ănderung des MFA-Modus der Gruppebwa
(18:46:39). Stehtbwadanach aufqr, verlangt jeder Passwort-Login die Einrichtung, unabhÀngig vom Passwortwechsel. Welcher
Wert gesetzt wurde, ist nicht festgehalten. Es folgt daraus keine Aussage, ob ein Passwortwechsel den zweiten Faktor
zurĂŒcksetzt. - Auditlage: Jede Handlung steht mit Zeit, Konto, Grund und Quelle da (Web mit Adresse, CLI mit
cli:root). Das ist der Grund,
warum sich der Fall nachtrĂ€glich in Minuten klĂ€ren lieĂ. - Client-Adresse: Im Audit stand fĂŒr alle Web-EintrĂ€ge
172.17.0.1, das Docker-Gateway, nicht die Adresse des Browsers. Das ist
das Verhalten hinter einer Weiterleitung und zugleich ein Beispiel fĂŒr den offenen Punkt âClient-IP hinter den Proxiesâ (§8): Ohne
weitergereichte Adresse benennt das Audit den Proxy statt der Quelle.
GENERIC_UI_MESSAGE â ACCOUNT_LOCKED
Die OberflĂ€che sagt bewusst âfehlgeschlagen oder gesperrtâ (kein Hinweis, ob das Konto existiert). Welche der beiden Ursachen
vorliegt, erkennt nur, wer das Audit lesen darf. Das spricht fĂŒr die Frage in §7: Wer darf auditlog.php lesen, und in welcher Tiefe?
4b. Operator-Weg im qr-Modus (geprĂŒft)
Nach dem Passwort verweigert user code (âMFA nicht aktivâ), solange die Einrichtung offen ist. user enroll <email> setzt ein neues
Secret und aktiviert es, danach liefert user code <email> den Code, und die Anmeldung geht durch (Redirect auf index.php). Das
zeigt auch: Wer die CLI bedienen darf (root/sudo), kann den zweiten Faktor jedes Kontos setzen und den Code erzeugen. Das ist die
Guard-Grenze, nicht der Faktor.
5. Grenzen
- Container, keine VM. Die Apache-Kette der RZ-VM (mehrere verschachtelte Configs), das echte Zertifikat und die Client-IP hinter
den Proxies waren nicht dabei. - MySQL lokal (
mysql-serveraus dem Ubuntu-Repo, 8.0.x), nicht die externe/RZ-Instanz. - PHP 8.4 kam aus
ppa:ondrej/php; auf der Node ist 8.4.26 vorhanden, die Quelle dort ist nicht identisch belegt. - Gegenprobe der RZ-NetBox (VM, N7) und Ort der Node-CA bleiben offen (Nachtrag vom 13.10.).
- Belege nicht mehr einsehbar. Container, Image, Testdaten und die Zugangsdatei des Dummys sind abgebaut. Die LĂ€ufe sind nur durch
Neubau reproduzierbar (build.sh,review-dummy.sh,review-check.sh); die EintrÀge ausaudit_logundusers, auf die sich §2
und §4a stĂŒtzen, sind in diesem Nachtrag festgehalten und nicht mehr am System nachzulesen.
5a. Test-Setup: Docker-Hinweise (tests/README.md, 369e3d6)
Die 15 Suiten brauchen einen MySQL-8-Server. Lokal ist das ein Wegwerf-Container (mysql:8.0, rund 1,1 GB beim ersten Start,
Datenverzeichnis im tmpfs, nur auf 127.0.0.1:33306, Admin-Benutzer mit Test-Passwort). Das ist der Verifier, und er gehört
zum Interpretationsrahmen eines Ergebnisses (Ihr §3):
- Version: Der Docker-Container meldete 8.0.46, die Node ebenfalls (Ubuntu-Paket 8.0.46-0ubuntu0.22.04.4,
ATTESTED_BY_BRANKO).
Gleiche Versionsnummer, nicht dasselbe Build: Konfiguration (Binlog,sql_mode, Collations) kann abweichen. - Wo die Befunde auftraten: Fehler 1419 und die
CHECK_CONSTRAINTS-Spalte zeigten sich im Docker-Imagemysql:8.0. Im
Ubuntu-Container hattebuild.shSET_USER_IDvorab vergeben (1419 trat dort nicht auf), und die Spaltenfehler waren schon
behoben. Auf der Node selbst istmigratenoch nicht gelaufen; ob dort dasselbe geschieht, ist nicht belegt. - Bereitschaft: Das offizielle Image startet beim Initialisieren einen Zwischen-Server ohne Netzwerk. Ein Ping ĂŒber den Socket
meldet sich dann schon, die Suiten bekommen aber noch âconnection refusedâ. Das README wartet deshalb per TCP.
Belegt ist das nur als dokumentiertes Verhalten des Images; die Warteschleife selbst ist nach der ErgÀnzung nicht erneut gelaufen. - Rechte des Test-Benutzers: Die Suiten laufen als Admin (
CREATE/DROP DATABASE). Sie belegen die App-Logik, nicht die
Rechtetrennungtlsgate_ddl/tlsgate_app. Diese Trennung ist nur imbuild.sh-Lauf (Container-Node) und im Doktor belegt. - AufrÀumen:
docker rm -f tlsgate-mysql-test, Image mitdocker rmi mysql:8.0. Die Daten liegen im tmpfs und sind danach weg.
TESTS_GRUEN â RECHTETRENNUNG_GEPRUEFT
6. VorschlĂ€ge fĂŒr PrĂŒffĂ€lle
- P-REV-1: Gruppentrennung jenseits der Seite: fremde
cid/group_id/Buchungs-ID incredentials.php,katalog.php,
booking-Aktionen (die Suitencredentials_uiundkatalogdecken Teile ab, ein gemeinsamer Fall mit zwei echten Konten fehlt). - P-REV-2:
qr-Modus: Was belegt ein erneutes Passwort-Login? Es erzeugt ein neues Secret. Der alte zweite Faktor gilt dann nicht
mehr, das ist gewollt, aber im Audit sichtbar zu machen. - P-REV-3: Doktor-Sicht: Welche Rolle darf prĂŒfen, ob die Trigger da sind? Aktuell nur root per SQL, nicht der App-Benutzer.
- P-REV-4: Meldungen: OberflÀche allgemein, Audit konkret (
bad_password, Sperre, inaktiv). PrĂŒfen, dass die OberflĂ€che in
keinem Pfad (auch Zeitverhalten, Statuscode) Konto-Existenz oder Sperre verrÀt.
7. Frage
Welche Aussage darf âReview-Dummy grĂŒnâ tragen? Mein Vorschlag: âMechanismus fĂŒr Anmeldung, Gruppentrennung der Bestandsseite und
Schema funktionieren in einer frischen Ubuntu-22.04-Umgebung mit MySQL 8.0 (Docker-Image 8.0.46; Version des Ubuntu-Pakets nicht
festgehalten)â, und ausdrĂŒcklich nicht: âdie RZ-VM ist bereitâ.
8. Offen
- â Apache-Kette der RZ-VM, TLS-Terminierung, Client-IP.
- â WurzelschlĂŒssel: neu erzeugen oder aus der Dev-VM ĂŒbernehmen.
- â
Code-Eingabe im Browser und Seiten danach: von Branko als âsieht gut ausâ gemeldet (siehe §2). Welche Quelle der erste, abgelehnte Code
hatte, ist nicht festgestellt (Uhren gleich, Secret in Datei und DB gleich, also kein Serverfehler; Eingabe nach Ablauf wahrscheinlich). - ⏠P-REV-1 bis P-REV-4.
- â Ort der Node-CA, VM-Gegenprobe (N7),
tenant_group.