amphp / ssh

Async SSH client for PHP based on Amp.
35 stars 7 forks source link

Support Tunnels #2

Open trowski opened 5 years ago

trowski commented 5 years ago

Supporting tunneling with a class implementing Amp\Socket\Socket could be very useful.

joelwurtz commented 5 years ago

Yes, that was something that i got in mind, so we could pipe an ssh tunnel to any other amp library (like mysql / postgres / websocket / etc ...)

trowski commented 5 years ago

@joelwurtz Would you have some time to implement this soon?

joelwurtz commented 5 years ago

Unfortunately no and not before some weeks / months (currently buying / building house)

bwoebi commented 5 years ago

I'd like to add that I'd really love to see a possibility to do this, in particular tunneling a ssh tunnel through a ssh tunnel would be awesome (sometimes you need to access something from a non-public facing server ... and creating a port forwarding on the public server to the target server pretty much defeats the point of having the server not publicly available).

joelwurtz commented 5 years ago

Basically you just need to follow this part of the RFC : https://tools.ietf.org/html/rfc4254#section-7 and returning a Socket that wrap and hide this protocol

(All messages object should already be available in this library)

joelwurtz commented 5 years ago

see #3 if you want to test this, it work for a basic case, not sure everything is handle, would be nice to have some feedback so can properly finish this and merge it.

joelwurtz commented 5 years ago

And unfortunetaly @trowski i cannot implement Socket since there is no encryption support possible :/. I'm afraid supporting encryption would need to write everything by hand ? (which is too much for me)

trowski commented 5 years ago

Don't have time to look at or test this today, but I wanted to ping @kelunik that this is part of the reason why I made Socket an interface in master of amphp/socket. @joelwurtz I'd be interested in any feedback you have regarding how the interfaces in amphp/socket should be structured for a 1.0 release.

joelwurtz commented 5 years ago

Just read the Socket interface and since it does not need encryption it should be easier to implement here. However i'm quite unsure about reference and unreference, as far as i understand, it seems to add watcher on the event loop so that the loop will not stop if there is resource that needs to be read or write.

However in my context i don't think it make sense, since my main stream is already referenced, and then it use multiplexing over the same resource, what should the tunnel do here in this case ? (i'm guessing just have empty function ?)

bwoebi commented 5 years ago

@joelwurtz You should keep a count and if the number multiplexed sockets matches that count (i.e. all sockets over it are unreferenced), then you unreference the underlying stream as well, and vice versa.

joelwurtz commented 5 years ago

@bwoebi It's more subtile, as you can open a new ssh connection, create some tunnels / shell / process inside it (you can multiplex anything). And even if every tunnel / shell / process is close, you may still want to open something later with the existing ssh connection (and so keep it referenced).

Also the ssh connection have a internal listener as the server can ask some info / ping it / etc ... IMO only the ssh connection should be referenced on creation and unreferenced on close, but i think it's like that by default when using Amp\Socket\connect() (not very familiar with all internals details) ?

joelwurtz commented 5 years ago

Maybe i misunderstood @bwoebi, does reference / unreference is something used by third party library and user to force an event loop to be not stoped until they unreference everything (and not something done by the library itself) ?

In that case yes having an internal counter on the ssh ressource would be the way to go.

bwoebi commented 5 years ago

yeah, unreference is meant to allow automatic stopping of the loop if nothing is going on. You should only reference things within the loop which are contributing to the processing of your business logic. E.g. a sql connection not processing any jobs is not meaningful. Or in this case, a ssh tunnel which is not used. A connection you're actively uploading some file over is important.