steelbrain / node-ssh

SSH2 with Promises
MIT License
942 stars 94 forks source link

Unable to SSH tunnel to hit private API #430

Open Joe-Kollin opened 2 years ago

Joe-Kollin commented 2 years ago

Hey all,

I have a server in a private subnet that is hosting a REST API on port 80 and a jump box in a public subnet that I would like to tunnel through so that I can invoke the REST API in the same execution with axios. When I run the command line command to tunnel everything works fine:

ssh -i "keypair.pem" -L 8081:<API HOST>:80 <JUMP BOX USER>@<JUMP BOX IP>

Once I run that command, as long as I keep the session open, I can hit the API through Postman/Axios. All good.

I am trying to do the same thing with this library, but the connection is not being exposed properly and I can't figure out why. Here is my code:

const ssh = new NodeSSH();
await ssh.connect({
  host: '<JUMP BOX IP>',
  username: '<JUMP BOX USER>',
  privateKey: `RSA KEY`
});
ssh.connection?.forwardOut('127.0.0.1', 8081, <API HOST>, 80);
const response = await axios.get(`http://localhost:8081/<ENDPOINT PATH>`);

The connection opens fine and I can exec commands as I want. This issue may be a result of using async/await as well, but I would like to stick using that model if possible.

Thanks in advance for the eyes and any ideas.

steelbrain commented 2 years ago

forwardOut is not a synchronous function, I think you may want to update your forwardOut to the following

await new Promise((resolve, reject) => {
  ssh.connection.forwardOut(..., (err, stream) => {
    if (err) {
      reject(err)
    } else {
      resolve(stream)
    } 
  })
})