Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I do SSH port forwarding from within Python Twisted?

Are there any examples of initiating an SSH session to a remote machine with port forwarding options from within Twisted using Conch such that one can pipe normal TCP traffic through the tunnel?

Scenario:

I have a server running a custom Twisted-based Protobuf RPC service and a machine with a Twisted-based RPC client installed. The server is also running SSH. Rather than talking to the RPC service on the server directly, I would like to connect to the server using SSH from the RPC client, setup port forwarding on the server, and communicate with the RPC service using Protobuf through the SSH tunnel.

I'm already able to setup port forwarding manually and have the RPC client talk to the RPC service by pointing the RPC client to a local port on the client box, I'm just curious as to how I can do this within the client directly.

like image 705
Bryan Avatar asked Oct 03 '12 14:10

Bryan


People also ask

Can SSH be used for port forwarding?

SSH is a secure shell and it offers a private connection between hosts. SSH port forwarding is one method that is used to tunnel traffic through an SSH connection. This can be done either locally or remotely if you are not close by to the target machine. Port 22 is used by default for establishing SSH connections.

What is SSH tunneling port forwarding?

SSH tunneling, or SSH port forwarding, is a method of transporting arbitrary data over an encrypted SSH connection. SSH tunnels allow connections made to a local port (that is, to a port on your own desktop) to be forwarded to a remote machine via a secure channel.

What is SSH dynamic port forwarding?

Also known as dynamic tunneling, or SSH SOCKS5 proxy, dynamic port forwarding allows you to specify a connect port that will forward every incoming traffic to the remote server dynamically. Dynamic port forwarding turns your SSH client into a SOCKS5 proxy server.


2 Answers

It would be awesome if there were improved documentation in Twisted for doing neat things with Conch (after all, how many other programmable SSH libraries are there?). Until that happy day comes, reading the implementation of the conch command line tool can be a big help.

Here we can see where port forwarding options from the command line are turned into some action over the SSH connection:

https://github.com/twisted/twisted/blob/4ffbe9f6851dbe7e9172f55905f264ecf50da3a6/src/twisted/conch/scripts/conch.py#L226-L238

I think you're asking about a local forwarding rule, so the localForwards loop is doing roughly what you want to do.

like image 107
Jean-Paul Calderone Avatar answered Sep 21 '22 06:09

Jean-Paul Calderone


Implementing a tunneling Twisted SSH client that does local port forwarding can be surprisingly simple.

Just create a basic Twisted Conch SSH client, and implement the port forwarding part in the serviceStarted method of the SSH connection class of your client:

from twisted.conch.ssh import forwarding

LOCALPORT = 8888
REMOTEHOST = "127.0.0.1"
REMOTEPORT = 9999

class Connection(connection.SSHConnection):

    def serviceStarted(self):
       Channel = forwarding.SSHListenClientForwardingChannel
       Factory = forwarding.SSHListenForwardingFactory
       factory = Factory(self, (REMOTEHOST, REMOTEPORT), Channel)
       s = reactor.listenTCP(LOCALPORT, factory)

That's all there's to it (REMOTEHOST is set to point to ssh server itself since that's what you said you're connecting to).

like image 25
Petri Avatar answered Sep 21 '22 06:09

Petri