Entrar
PT

Tutorial: uma ligação através de SSH, passo a passo

O projeto de exemplo apps/hello-ssh alcança um servidor Redis que só um servidor SSH (um bastião) consegue alcançar: ssh -W host:port, o fluxo da ligação é o fluxo para o Redis. No computador, é o ssh do sistema; no navegador, o verdadeiro cliente OpenSSH compilado para WebAssembly, ligado ao teu PHP por um pipe.

1. Criar a aplicação

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

2. A janela

forms/MainForm.form.yaml (copia apps/hello-ssh/forms/MainForm.form.yaml): o servidor SSH (sshHost, sshPort, sshUser), um botão « Choose a key file… » (chooseKey), a frase secreta da chave (passphrase), o destino visto do bastião (host, port), um botão ping, status, result.

3. A chave: o seletor de ficheiros

Um navegador não tem pasta ~/.ssh: pede-se o ficheiro à pessoa. FilePicker::open() funciona no computador E no navegador (chama-o a partir de um clique); o ficheiro escolhido chega a um caminho que se lê e depois se apaga. Guarda-se no porta-chaves da aplicação ($this->engine->sshKeyring(): o papel de um agente, que o navegador não tem).

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());
    });
}

A chave fica no armazenamento da aplicação (var/ssh_keyring.json: IndexedDB no navegador, a pasta de dados no computador) e nunca é enviada ao servidor: vai para a memória do cliente SSH. Cada ligação propõe todas as chaves do porta-chaves, como um agente.

4. Ligar-se

$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

Os mesmos eventos que com tcp(). Para código que recebe um Tcp (como o cliente MySQL de apps/jumphpsql): $this->engine->ssh()->via($options) tem o mesmo connect($host, $port, $timeout). As opções: docs/ssh-wasm.md.

5. Testar

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. O navegador: dois direitos

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

No navegador, dois níveis passam pela ponte TCP de jumphp.net, que só aceita as aplicações autorizadas: o cliente SSH (WebAssembly) liga-se ao bastião (porta 22 ou outra) → é preciso o direito SSH. (Um cliente SQL que fala diretamente com uma base de dados precisa do direito TCP.) Studio → o projeto → Accès SSH → « Demander l'accès SSH »; o administrador autoriza-o para o commit publicado.

O direito SSH é mais amplo (qualquer porta de um endereço público, nunca um endereço privado): o administrador só o concede a código que examinou. Estatísticas, registo, corte e bloqueio: Administration → Pont TCP.

7. Verificar no navegador

Página do projeto em jumphp.net: escolhe a tua chave (abre-se o seletor de ficheiros do teu computador), indica o bastião e o destino, clica em « Send PING through SSH »: The server answered: +PONG. Nos primeiros segundos aparece « The SSH session is starting… »: o cliente SSH arranca num Web Worker (um ficheiro de 3,8 MB carregado a pedido).

Como funciona (dois wasm ligados por um pipe), a segurança e a compilação do OpenSSH: docs/ssh-wasm.md. O primeiro tutorial: docs/tuto-tcp.md.