TLS-Gate v3.2.0: Deploy-ZIP, ssl_outbox, und der Fake-Modus ist weg

Von: Branko → OZMAI
Stand: 2. Oktober 2026
Typ: EXTERNAL_SOURCE (Inbox-Regel §3 — keine automatische Geltung, kein Brain-Status)
Charakter: STANDSMELDUNG mit Fehlerbefund. Gebaut und im Container getestet (🧪); kein Lauf gegen einen echten Registrar oder eine echte CA.
Quelle: Repo TLS-Gate-Mock-Pipeline (git.crumbforest.org), Tag v3.2.0 = Commit 23d613c; Handout-Korrektur 93ac702 (main).
Belege: tests/test_outbox.sh (27), docker_vm/tests/{run,p3,p4,p5,p6}.sh (52 + 45 + 54 + 31 + 22), tests/test_dates.sh (16).
Anschluss an: 2026-10-01_TLS-GATE-NODE-ALS-ANSIBLE-ROLLE-HANDOUT_BRANKO.md (Stand 702afe3; Teile davon sind durch diese Notiz überholt, siehe §3).

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

Keine Zugangsdaten, keine Kunden-Domains, keine Reseller-IDs. Registrar und Zertifikate im Test sind Fake.


1. Befund: ein neuer aktiver SOAP-Zugang ließ sich in der VM nicht anlegen 🧪

  • Beobachtung (Branko, 2.10.): Die VM lief mit dem Fake sauber, nur das Anlegen eines neuen aktiven Zugangs scheiterte.
  • Ursache, im Code gefunden: instance.sh <name> fake schrieb env[TLSGATE_SOAP_HOSTS] = soap.fake.test in den php-fpm-Pool.
    CredentialStore::check() lehnt jede WSDL ab, deren Host nicht in dieser Liste steht. Der Testmodus verhinderte damit genau den Schritt, den er vorbereiten sollte.
    Zusätzlich stand in der .profile der Instanz fest ein Fake-Zugang für das Bash-Dashboard.
  • Behoben: Der Modus fake ist entfernt (instance.sh kennt nur noch mock), ebenso die festen Zugangsdaten. Der Fake-Registrar bleibt als gewöhnliches Ziel im Container; sein Zugang wird wie jeder andere angelegt.
    TLSGATE_SOAP_HOSTS bleibt eine bewusste, manuelle Betriebsoption.
  • Gegenprobe im Test (p3.sh): Der Pool enthält kein TLSGATE_SOAP_HOSTS; instance.sh <name> fake wird abgelehnt; ein Zugang mit fremdem WSDL-Host lässt sich anlegen.
  • Zweiter Fund derselben Sitzung: Die Handbuch-Anleitung für den ssh-Schlüssel ließ install -d /root/.provision/ssh aus. Nach down -v scheiterte docker cp mit „Could not find the file“. Nachgestellt, Schritt ergänzt.

2. Neu: Deploy-ZIP und ssl_outbox 🧪

  • Knopf in der Detailansicht einer Bestellung. public/outbox.php fragt sslInfo mit dem Zugang der eigenen Gruppe und liefert <domain>.zip mit
    <domain>/<domain>.cert und <domain>/<domain>.chain.pem — dieselben Dateien und Namen wie dashboard.sh deploy (native_bash_cli).
  • Kein Private Key. TLS-Gate besitzt keinen (DESIGN_TENANTS §0.2). Zusätzlich bricht der Bau ab, wenn ein Feld „PRIVATE KEY“ enthält (Gegenprobe im Test: Key im Cert- und im Chain-Feld).
  • Ablage: dieselben Bytes unter <state>/ssl_outbox/<gruppen-id>/<domain>.zip (Ordner 0700, Datei 0640, Besitzer Instanz), umlenkbar mit TLSGATE_OUTBOX_DIR.
    Gedacht zum Einsammeln durch die Orchestrierung; die Weiterverteilung selbst ist nicht gebaut (⬜).
  • Zugriff: ab Rolle user, CSRF, Audit ssl.deployZip (requested/ok/fail; bei ok mit SHA-256 des ZIPs).
  • Dateiname aus Registrar-Daten wird nicht vertraut: .., /, Leerzeichen, Steuerzeichen werden abgelehnt, *. wird zu _..
  • ZIP ohne PHP-Erweiterung (im Container fehlt php-zip), Methode „stored“; fremd gelesen mit python zipfile und unzip -t.

3. Was sich für die Ansible-Übergabe ändert ⬜

  • Rollenparameter mode: fake|real wird zu mode: mock|real (mock = TLSGATE_MOCK=1, nur Test). Korrigiert in docs/HANDOUT_ANSIBLE.md (93ac702); die Inbox-Fassung vom 1.10. nennt noch den alten Stand.
  • Referenz-Suiten: 52 + 45 + 54 + 31 + 22 statt 52 + 43 + 54 + 31.
  • Neu zu erzeugen, falls die Rolle den Deploy-Weg mittragen soll: state/ssl_outbox/ entsteht lazy durch die App (Besitzer Instanz); ein gemeinsamer Pfad wäre TLSGATE_OUTBOX_DIR im Pool. ❓ Welchen Pfad die Orchestrierung einsammelt, ist nicht entschieden.

4. Belegt, und was nicht

  • 🧪 Frisch nach down -v (Volumes weg, Image neu, Instanzen neu): alle Suiten grün — run 52, p3 45, p4 54, p5 31, p6 22.
    p6 prüft den HTTP-Pfad gegen die Instanz: Anmeldung, CSRF (403), GET (405), fehlende Nummer (400), Fehlerfälle ohne 5xx und ohne ZIP, Outbox-Rechte, Audit.
  • 🧪 Der Zugang überlebt down, nicht down -v; danach instance.sh und cred add erneut (im Handbuch §3a/3c).
  • ❓ Nicht belegt: ein Zertifikat einer echten CA (nur Fake-PEM), cred test gegen einen echten Registrar, Verhalten bei sehr großen Ketten.
  • ⬜ Offen aus dem Stand vom 1.10. unverändert: Ansible-Rolle, DB-Passwort im Pool im Klartext (LoadCredential), Doktor prüft nur den Pool des WEB_USER, group add mit vorhandenem Slug (PDOException statt Meldung).
    Neu dazugekommen und ebenfalls offen: cred add mit vorhandenem Label zeigt die rohe SQL-Meldung (1062 Duplicate entry) statt eines Satzes.

5. Prüfmaßstab (Hinweis an OZMAI)

Die Fehlerursache war kein Fehler im Zugangsspeicher, sondern eine Test-Konfiguration, die eine Sicherheitsschranke (Host-Liste) für den Normalfall gesetzt hat.
Was die Suiten bis dahin als „grün“ zeigten, war richtig für den Fake-Pfad und sagte nichts über den Pfad „fremde WSDL“. Beleg dafür ist erst die neue Prüfung, die genau diesen Pfad einzeln zieht.