Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use node ssh2 to start a user interactive ssh session?

Tags:

node.js

ssh

I've been trying to find a way to make a node script automatically open up an ssh connection for me. I don't want it to run any command, just open the connection and let me start typing.

I've found this question on ways to connect: SSH client for Node.js

Every way I've found thus far has been primarily focused on opening an ssh connection and running commands with node, but I don't want any commands to be run but the ones I type myself.

The package I'm trying to use is ssh2 https://github.com/mscdex/ssh2#installation

It connects well, but I can't find an example of a way to connect process.stdio to it easily. I can imagine convoluted ways of doing it, but it seems like there must be some very simple way.

I have read the section on "interactive shell session" but it appears to be a bit of a misnomer as it really just runs ls -l then exits. No interaction there at all.

https://github.com/mscdex/ssh2#start-an-interactive-shell-session

What is the proper way to use this tool to start a normal, basic, plain ol' tty ssh session?

like image 645
Seph Reed Avatar asked Feb 14 '26 08:02

Seph Reed


1 Answers

I ended up solving the issue. It's very strange that any issue arose as (when checking the source for ssh2) it appears that is set up to do exactly what I thought it should. In any case, this code worked for me:

const {host, password, port, username} = sshCreds;
return new Promise((resolve) => {
    var conn = new Client();
    conn.on('ready', function() {
        console.log('Client :: ready');
        conn.shell(function(err, stream) {
            if (err) throw err;

            const stdinListener = (data) => {
                skipNext = true;
                stream.stdin.write(data);
            };

            stream.on('close', function() {
                process.stdin.removeListener("data", stdinListener)
                conn.end();
                resolve();
            }).stderr.on('data', function(data) {
                resolve();
            });

            // skip next stops double printing of input
            let skipNext = false;
            stream.stdout.on("data", (data) => {
                if (skipNext) { return skipNext = false; }
                process.stdout.write(data);
            })

            process.stdin.on("data", stdinListener)
        });
    }).connect({
        host,
        port,
        username,
        password,
    });
})
like image 199
Seph Reed Avatar answered Feb 15 '26 23:02

Seph Reed