throw new RuntimeException('Für den Server ist keine SSH-Kennung erzeugt — ohne sie kann keine Terminalsitzung entstehen.'), 'not_installed' => throw new RuntimeException('Der Server ist für das Terminal noch nicht eingerichtet — es fehlt storage/app/deploy/server-terminal.json.'), default => null, }; // blocker() hat die Datei eben gelesen; dass sie zwischen den beiden // Zeilen verschwindet, wäre ein Wettlauf mit dem Einrichtungsskript. // Die Prüfung steht trotzdem da: die Alternative wäre ein Zugriff auf // null — also eine Fehlerseite in einem Terminalfenster. $setup = ServerTerminalSetup::read() ?? throw new RuntimeException('Die Einrichtung des Server-Terminals ist zwischen Prüfung und Ausstellung verschwunden.'); // Wer eine Root-Konsole in die Steuerungsebene aufmacht, steht mit // Namen im Log. Die Brücke kennt nur die Nummer des Betreibers und // nicht die Adresse, von der aus gefragt wurde — beides weiß allein // diese Seite der Anwendung, und ohne diese Zeile wäre es nirgends // festgehalten. Der INHALT der Sitzung wird bewusst nicht // mitgeschrieben: er enthält zwangsläufig Passwörter und Schlüssel im // Klartext, und ein Mitschnitt davon wäre ein zweites Geheimnislager. Log::warning('Root-Konsole zum CluPilot-Server angefordert.', [ 'operator' => $for->name, 'operator_id' => $for->id, 'from' => request()->ip(), ]); return TicketStore::issue([ 'operator_id' => $for->id, 'host_uuid' => 'server', 'ip' => $setup->address, 'user' => 'root', 'private_key' => (string) app(SecretVault::class)->get(ServerIdentity::VAULT_KEY), 'fingerprint' => $setup->fingerprint, ]); } }