J'ai ceci:
curl localhost:4004
quand je frappe le serveur avec:
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');
et que je tape des commandes bash, rien n'est envoyé vers ma console, tout le monde sait pourquoi?
Remarque : pour résoudre le problème de 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 (toutes les recommandations sur les schémas d'authentification lmk).
Plus important encore , je cherche des invites de shell pour apparaître ... apparemment bash en lui-même n'ouvre pas un shell / invite?
4 Réponses :
Ceci est une réponse partielle, mais j'ai commencé une prime parce que je cherche quelque chose de mieux. J'ai pu créer quelque chose de rudimentaire avec TCP comme ceci:
docker exec -ti <container> /bin/bash
je ne sais pas pourquoi cela ne fonctionnera pas avec HTTP. Je me connecte dessus en utilisant netcat:
nc localhost 4004
mais cela n'ouvre pas 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 à répliquer le shell l'expérience que vous avez lorsque vous faites quelque chose comme:
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');
lorsque j'exécute mon script, cela "fonctionne", mais je ne obtenir toutes les invites du shell ou quelque chose comme ça. (Une façon de résoudre ce problème pourrait être avec ssh, mais j'essaie de trouver une autre façon).
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émarrez un serveur http avec le package npm http-server
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);
});
Démarrez maintenant séparément une session telnet
nc localhost 8080
OU
telnet localhost 8080
Et puis tapez quelque chose comme GET /
Utilisez le client telnet au lieu de nc
Vérifiez ceci: 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 sur https://github.com/mscdex/ssh2
npm install -g http-server cd ~/ <Any directory> http-server
Je veux ouvrir un terminal sur la machine distante, comme ssh, cela ne fera pas ça tmk ... Je vais rendre la question un peu plus claire.
Vous ne pouvez pas ouvrir un terminal (ssh) car ssh nécessite une connexion bidirectionnelle continue. HTTP n'acceptera qu'une seule requête et enverra une réponse. C'est ainsi que fonctionnent les serveurs http.
oui c'est pourquoi ma réponse partielle a tcp pas http, tu as raison
si vous démarrez un serveur tcp, vous pouvez le faire réagir aux commandes que vous envoyez comme vous le souhaitez. HTTP ne divertira pas cela. Une demande, une réponse. Sauf si vous utilisez keep-alive
ouais essaie mon code tcp, tu verras ce que je veux dire, ça marche, mais ça n'ouvre pas de terminal, juste bash
D'accord. C'est plus une question d'application. SSH est une couche d'application sur le réseau. Les données sont constamment échangées sur le serveur et le client. Vous ne le voyez tout simplement pas. Vous devrez implémenter tout cela en utilisant tcp. Ou vous pouvez utiliser xnite.me/programming/ 2018/01/15 / nodejs-ssh-server-example.ht ml
Si vous souhaitez en créer un vous-même, vous devrez implémenter un client qui transfère les données à chaque frappe. Et le serveur enverra des données dans un autre format (json peut-être) et le client l'interprétera et montrera quelque chose de similaire au fonctionnement d'un shell. C'est un peu de travail, mais peut être fait
Eh bien, je pense peut-être installer un programme de terminal et lorsque le terminal s'ouvre, il exécute simplement bash? il doit y avoir un programme de terminal que je peux installer et puis je peux l'exécuter?
@MrCholo Je vous ai donné deux URL qui fournissent exactement cela.
@AhmedMasud il veut créer un programme qui peut agir comme un serveur de terminal (ssh). Ceux que vous avez partagés se connectent à ssh via le navigateur, ils n'implémentent pas de serveurs ssh
@MrCholo J'ai trouvé quelque chose en javascript que vous voudrez peut-être regarder
@SomeshMukherjee soupir il n'a jamais mentionné ssh et il ne dit pas qu'il veut créer un SSH dans la question originale, même dans le commentaire il confond ssh avec un tty. un TERMINAL ≠ ssh.
Il est possible de faire cela "sur le Web" pour ainsi dire. Cependant, votre approche ne fonctionnera pas, car vous mélangez des paradigmes (batch vs interactif), et il vous manque de gros morceaux de configuration nécessaires pour exécuter les applications de terminal.
Normalement, je vous montrerais comment programmer ceci, cependant, c'est vraiment compliqué. Jetez un œil à:
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 depuis node.js pour servir des applications de terminal via HTTP.
Vos approches sont assez mitigées, néanmoins, chaque fois que vous vous connectez finalement au serveur distant, n'utilisez pas 'bash' comme méthode pour démarrer la connexion, BASH est juste né de nouveau shell avec d'autres commandes et des trucs dedans,
Utilisez plutôt certains des programmes suivants, des noms de ligne de commande: c'est-à-dire:
~ $ 'gnome-terminal' ~ $ 'xterm'
là, vous allez maintenant référencer un vrai programme dans le système, même le code de niveau C du noyau a sa propre reconnaissance de ceux-ci, si elle n'est pas modifiée.
Une façon d'obtenir une expérience de terminal serait d'utiliser ssh, mais j'essaie de comprendre comment le faire sans ssh, en utilisant un autre programme de terminal ou quelque chose.