2 votes

Ouvrir un terminal/shell sur un serveur distant via une requête tcp

J'ai ça :

const http = require('http');
const cp = require('child_process');

const server = http.createServer((req,res) => {

  const bash = cp.spawn('bash');
  req.pipe(bash.stdin, {end:false);
  bash.stdout.pipe(res);
  bash.stderr.pipe(res);

});

server.listen('4004');

quand j'ai frappé le serveur avec :

curl localhost:4004

et je tape des commandes bash, rien n'est affiché sur ma console, quelqu'un sait pourquoi ?

Note : Pour aborder la sécurité, je prévois de l'exécuter dans un conteneur docker, d'utiliser https/ssl et de mettre en œuvre l'authentification (toute recommandation sur les schémas d'authentification lmk).

Plus important encore Je suis à la recherche de invites de l'obus pour apparaître ... apparemment bash n'ouvre pas un shell/prompt ?

0voto

C'est une réponse partielle, mais j'ai commencé un bounty parce que je suis à la recherche de quelque chose de mieux. J'ai pu créer quelque chose de rudimentaire avec TCP comme ceci :

const net = require('net');   // !use net package not http
const cp = require('child_process');

const server = net.createServer(s => {

  const bash = cp.spawn('bash');
  s.pipe(bash.stdin, {end:false});
  bash.stdout.pipe(s);
  bash.stderr.pipe(s);

});

server.listen('4004');

Je ne sais pas pourquoi cela ne fonctionne pas avec HTTP. Je m'y connecte en utilisant netcat :

nc localhost 4004

mais ce n'est pas l'ouverture d'un terminal, juste un processus bash. l'expérience n'est pas idéale, comme décrit ici : https://unix.stackexchange.com/questions/519364/bash-shell-modes-how-to-pipe-request-to-shell-on-remote-server

Cependant, je cherche à reproduire l'expérience de la coquille que vous avez lorsque vous faites quelque chose comme ça :

docker exec -ti <container> /bin/bash

quand je cours mon script cela "fonctionne", mais je Ne le fais pas. obtenir n'importe quel invites de l'obus ou quelque chose comme ça. (Une façon de résoudre ce problème pourrait être avec ssh, mais j'essaie de trouver un autre moyen).

0voto

Somesh Mukherjee Points 3213

Vous pouvez vous connecter à un serveur http avec telnet. Cela dépend de la façon dont vous démarrez le serveur http. Voici un exemple

Démarrer un serveur http avec le paquet npm http-server

npm install -g http-server 
cd ~/ <Any directory>
http-server

Maintenant, démarrez séparément une session telnet

telnet localhost 8080

OU

nc localhost 8080

Et puis tapez quelque chose comme GET /

Utiliser le client telnet au lieu de nc

Regarde ça : https://www.the-art-of-web.com/system/telnet-http11/ Mise à jour : Exécution d'un serveur ssh sur nodejs. Il vous permet d'exécuter un serveur ssh J'ai trouvé ceci à https://github.com/mscdex/ssh2

var fs = require('fs');
var crypto = require('crypto');
var inspect = require('util').inspect;

var ssh2 = require('ssh2');
var utils = ssh2.utils;

var allowedUser = Buffer.from('foo');
var allowedPassword = Buffer.from('bar');
var allowedPubKey = utils.parseKey(fs.readFileSync('foo.pub'));

new ssh2.Server({
  hostKeys: [fs.readFileSync('host.key')]
}, function(client) {
  console.log('Client connected!');

  client.on('authentication', function(ctx) {
    var user = Buffer.from(ctx.username);
    if (user.length !== allowedUser.length
        || !crypto.timingSafeEqual(user, allowedUser)) {
      return ctx.reject();
    }

    switch (ctx.method) {
      case 'password':
        var password = Buffer.from(ctx.password);
        if (password.length !== allowedPassword.length
            || !crypto.timingSafeEqual(password, allowedPassword)) {
          return ctx.reject();
        }
        break;
      case 'publickey':
        var allowedPubSSHKey = allowedPubKey.getPublicSSH();
        if (ctx.key.algo !== allowedPubKey.type
            || ctx.key.data.length !== allowedPubSSHKey.length
            || !crypto.timingSafeEqual(ctx.key.data, allowedPubSSHKey)
            || (ctx.signature && !allowedPubKey.verify(ctx.blob, ctx.signature))) {
          return ctx.reject();
        }
        break;
      default:
        return ctx.reject();
    }

    ctx.accept();
  }).on('ready', function() {
    console.log('Client authenticated!');

    client.on('session', function(accept, reject) {
      var session = accept();
      session.once('exec', function(accept, reject, info) {
        console.log('Client wants to execute: ' + inspect(info.command));
        var stream = accept();
        stream.stderr.write('Oh no, the dreaded errors!\n');
        stream.write('Just kidding about the errors!\n');
        stream.exit(0);
        stream.end();
      });
    });
  }).on('end', function() {
    console.log('Client disconnected');
  });
}).listen(0, '127.0.0.1', function() {
  console.log('Listening on port ' + this.address().port);
});

0voto

Ahmed Masud Points 6603

Il est possible de le faire "sur le web", pour ainsi dire. Cependant, votre approche ne fonctionnera pas, car vous mélangez les paradigmes (batch et interactif) et vous oubliez de grandes parties de la configuration nécessaire pour exécuter des applications de terminal.

Normalement, je devrais vous montrer comment le programmer, mais c'est très compliqué. Jetez un coup d'oeil :

https://github.com/chjj/tty.js

et,

https://github.com/xtermjs/xterm.js

comme points de départ pour créer votre solution.

Les deux sont utilisables directement à partir de node.js pour servir des applications terminales via HTTP.

-2voto

Jonathan Theu Points 1

Vos approches sont assez variées, néanmoins, lorsque vous vous connectez finalement au serveur distant, n'utilisez pas 'bash' comme méthode de démarrage de la connexion, BASH n'est qu'un nouveau shell avec d'autres commandes et trucs dedans,

Utilisez plutôt certains des noms de programmes et de lignes de commande suivants : par exemple :

 ~ $ 'gnome-terminal'     

 ~ $ 'xterm'

Vous ferez alors référence à un véritable programme dans le système, même le code C au niveau du noyau a sa propre reconnaissance de ces programmes, s'il n'est pas modifié.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X