Inloggen
NL

Tutorial: een verbinding via SSH, stap voor stap

Het voorbeeldproject apps/hello-ssh bereikt een Redis-server die alleen een SSH-server (een bastion) kan bereiken: ssh -W host:port, de datastroom van de verbinding is de stroom naar Redis. Op de computer is het de ssh van het systeem; in de browser de echte OpenSSH-client gecompileerd naar WebAssembly, via een pipe aan je PHP gekoppeld.

1. De toepassing maken

bin/jumphp gui:new mon-ssh "Mon SSH" && bin/jumphp install mon-ssh

2. Het venster

forms/MainForm.form.yaml (kopieer apps/hello-ssh/forms/MainForm.form.yaml): de SSH-server (sshHost, sshPort, sshUser), een knop « Choose a key file… » (chooseKey), de wachtzin van de sleutel (passphrase), het doel gezien vanaf de bastion (host, port), een knop ping, status, result.

3. De sleutel: de bestandskiezer

Een browser heeft geen map ~/.ssh: je vraagt de persoon om het bestand. FilePicker::open() werkt op de computer EN in de browser (roep het aan vanuit een klik); het gekozen bestand komt op een pad dat je leest en daarna wist. Je bewaart het in de sleutelhanger van de toepassing ($this->engine->sshKeyring(): de rol van een agent, die de browser niet heeft).

public function onChooseKey(Button $sender): void
{
    FilePicker::open(['title' => 'SSH private key'])->then(function (?string $file): void {
        if ($file === null) { return; }                                   // annulé
        $text = (string)file_get_contents($file);
        unlink($file);
        $this->engine->sshKeyring()->add(basename($file), $text, $this->passphrase->text);   // nom, clé, phrase secrète
        $this->keyState->text = 'Keys: ' . implode(', ', $this->engine->sshKeyring()->names());
    });
}

De sleutel blijft in de opslag van de toepassing (var/ssh_keyring.json: IndexedDB in de browser, de gegevensmap op de computer) en wordt nooit naar de server gestuurd: hij gaat naar het geheugen van de SSH-client. Elke verbinding biedt alle sleutels van de sleutelhanger aan, zoals een agent.

4. Verbinden

$options = ['sshHost' => 'bastion.exemple.com', 'sshPort' => 22, 'sshUser' => 'moi', 'sshKeys' => $this->engine->sshKeyring()->all()];
$connection = $this->engine->ssh()->connect('127.0.0.1', 6379, $options);      // 127.0.0.1:6379 vu depuis le bastion
$connection->on('open', fn () => $connection->write("PING\r\n"));
$connection->on('data', fn (string $bytes) => $this->result->text = trim($bytes));
$connection->on('error', fn (string $m) => $this->result->text = $m);          // « Permission denied (publickey) », « Could not resolve hostname »...
$connection->on('knownHosts', fn (string $text) => $this->engine->storage->writeJson('known_hosts.json', ['text' => $text]));   // l'empreinte du serveur, gardée

Dezelfde gebeurtenissen als bij tcp(). Voor code die een Tcp aanneemt (zoals de MySQL-client van apps/jumphpsql): $this->engine->ssh()->via($options) heeft dezelfde connect($host, $port, $timeout). De opties: docs/ssh-wasm.md.

5. Testen

bin/jumphp test mon-ssh      # le trousseau, les champs manquants, un ssh qui n'atteint pas son serveur (le message dit pourquoi)
bin/jumphp shot mon-ssh
bin/jumphp run mon-ssh       # sur l'ordinateur : le ssh du système (votre agent et ~/.ssh marchent aussi)

6. De browser: twee rechten

bin/jumphp build mon-ssh && bin/jumphp serve mon-ssh

In de browser lopen twee lagen via de TCP-brug van jumphp.net, die alleen goedgekeurde toepassingen toelaat: de SSH-client (WebAssembly) verbindt met de bastion (poort 22 of een andere) → het recht SSH is nodig. (Een SQL-client die rechtstreeks met een database praat, heeft het recht TCP nodig.) Studio → het project → Accès SSH → « Demander l'accès SSH »; de beheerder keurt het goed voor de gepubliceerde commit.

Het SSH-recht is ruimer (elke poort van een openbaar adres, nooit een privéadres): de beheerder geeft het alleen aan code die hij heeft bekeken. Statistieken, logboek, afsluiten en blokkeren: Administration → Pont TCP.

7. Controleren in de browser

Projectpagina op jumphp.net: kies je sleutel (de bestandskiezer van je computer opent), geef de bastion en het doel op, klik « Send PING through SSH »: The server answered: +PONG. De eerste seconden toont « The SSH session is starting… »: de SSH-client start in een Web Worker (een bestand van 3,8 MB dat op aanvraag wordt geladen).

Hoe het werkt (twee wasm verbonden door een pipe), de beveiliging en het compileren van OpenSSH: docs/ssh-wasm.md. De eerste tutorial: docs/tuto-tcp.md.