Coder Social home page Coder Social logo

SSH forwardOut Question about ssh2 HOT 16 CLOSED

mscdex avatar mscdex commented on May 29, 2024
SSH forwardOut Question

from ssh2.

Comments (16)

mscdex avatar mscdex commented on May 29, 2024 1

Why not just set up a tcp server and on connection, pipe the socket to a new forwarded stream? Something like (assuming your remote web server is running on port 80):

var net = require('net');

// Connect to ssh server first.... then....

net.createServer(function(sock) {
  // may want to sock.pause() first if on an older (pre-v0.10-ish?) node version
  c.forwardOut(sock.remoteAddress, sock.remotePort, '127.0.0.1', 80, function(err, stream) {
    if (err) throw err; // do something better than this

    sock.pipe(stream);
    stream.pipe(sock);

    // sock.resume() here if you paused earlier
  });
}).listen(8000);

That isn't tested, but you get the idea.... the http client connects to port 8000, which should then get transferred to the web server on the other side. No other work should be necessary.

from ssh2.

sparkleholic avatar sparkleholic commented on May 29, 2024 1

@mscdex
It seems to be fixed via the following code. :-)

net.createServer(function(sock) {
  c.forwardOut(sock.remoteAddress, sock.remotePort, '127.0.0.1', 80, function(err, stream) {
    if (err) throw err; // do something better than this

    sock.on('data', function(data) {
        if (stream.write(data) === false) {
             sock.pause();
        } 
     });
    stream.on('drain', function() {
       sock.resume();
    });
    stream.on('data', function(data) {
       sock.write(data);
    });
  });
}).listen(8000);

from ssh2.

sidorares avatar sidorares commented on May 29, 2024 1

I was confused as well with 'local stream' vs local ip:port
Here is my understanding what forwardOut does:

  • ask remote ssh server to establish tcp connection to rip:rport
  • create local stream, pipe it to ssh 'tcp local' protocol

So what's the purpose of local ip / local port arguments?

from ssh2.

mscdex avatar mscdex commented on May 29, 2024

If I understand what you're asking correctly, it sounds like you might need/want to set up some kind of SOCKS proxy or something and forward connections that way? It would simplify things since you would only need to forward a single port over ssh.

However that may limit throughput some since all connections would just be using a single channel stream. That may or may not be a problem though depending on your needs.

from ssh2.

rawberg avatar rawberg commented on May 29, 2024

I was hoping to avoid setting up a socks proxy as it seemed like overkill. The client application I'm building will be connecting to different remote servers via ssh and communicating via websockets with an agent/daemon installed on each server.

Using fowardOut requires all traffic to be sent through the stream provided by the callback via stream.write() correct?

from ssh2.

mscdex avatar mscdex commented on May 29, 2024

Ok, so I think what you could do is when you receive the HTTP upgrade request for the websocket locally, start a forwardOut() (assuming you are already connected, if not connect first obviously). Then pass that request (header and all) through the tunnel. Then the remote web server should respond and continue with the websocket upgrade handshake as normal.

from ssh2.

rawberg avatar rawberg commented on May 29, 2024

Thanks for the tips! I'm going to see if I can figure out how to make the socket.io/engine.io client communicate through the stream provided by forwardOut(). I'll post an update if I get it working.

from ssh2.

rawberg avatar rawberg commented on May 29, 2024

I've been looking into this further. I've taken websockets out of the equation for now to keep things simple. Right now I'd just like to forward a standard http.get request through the ssh tunnel. It works when I manually write the raw headers into the stream (like in your example).

However I'm not able to make the request happen using an http.ClientRequest instance. Going through the node source code for the ClientRequest class I can see it trying to create a new socket connection. Should I be trying to get the http request to use the same socket as the ssh2 object? If so it looks like I can pass a file descriptor to the createHandle function but I'm not sure how to get the file descriptor of the socket ssh2 is using. Is there a better way?

An alternative would be to create an http server instance locally, connect to it and then pipe that stream into the ssh2 connection. I'd like to avoid that approach if possible as it seems like there should be a way to do it with the forwarded connection. Any ideas?

from ssh2.

rawberg avatar rawberg commented on May 29, 2024

That works perfectly! Thank you for taking the time to show me the light through the SSH tunnel! I'll add this example to the readme.

from ssh2.

sparkleholic avatar sparkleholic commented on May 29, 2024

Hello @mscdex , @rawberg :
I'm using the similar code like the previous posted example.

"Browser" <--> "Host PC Node"(net.createServer() & ssh.forwardOut()) <--(ssh)--> "Remote PC Server"

The response for the request of browser should be some ".js" files like "A.js", "B.js", but sometimes, the contents of ".js" are mixed.

Have you seen this case ?

from ssh2.

mscdex avatar mscdex commented on May 29, 2024

@sparkleholic Hard to say without seeing any code.

from ssh2.

sparkleholic avatar sparkleholic commented on May 29, 2024

Hi @mscdex
It is almost same code as suggested in previous comment.

var net = require('net');

// Connect to ssh server first.... then....

var localServer = net.createServer(function(sock) {
  sock.pause();

  c.forwardOut(sock.remoteAddress, sock.remotePort, '127.0.0.1', 8080, function(err, stream) {
    if (err) throw err; // do something better than this

    stream.pause();
    sock.pipe(stream);
    stream.pipe(sock);
    sock.resume();
    stream.resume();
  });
});
localServer.listen(0 /*random*/, "127.0.0.1", null, (function() { ...}));
  • Node 10.0.18 & 10.0.22 (Tested in Both)
  • ssh2 0.2.12

This is not always happened. 1~2 times of 10.

from ssh2.

mscdex avatar mscdex commented on May 29, 2024

You should be able to just do this with streams2, I don't know if it will solve your problem though:

net.createServer(function(sock) {
  c.forwardOut(sock.remoteAddress, sock.remotePort, '127.0.0.1', 80, function(err, stream) {
    if (err) throw err; // do something better than this

    sock.pipe(stream).pipe(sock);
  });
}).listen(8000);

from ssh2.

sparkleholic avatar sparkleholic commented on May 29, 2024

I just tried... but unfortunately it still is causing a same problem. :-(

from ssh2.

mscdex avatar mscdex commented on May 29, 2024

Glad to hear you got it sorted out :-)

from ssh2.

sidorares avatar sidorares commented on May 29, 2024

I think I found the answer here - #99 (comment)

from ssh2.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.