Skip to content

Support Unix domain socket (local) forwarding - #31

Merged
fernandezcuesta merged 1 commit into
pahaz:masterfrom
RasterBurn:master
Mar 8, 2016
Merged

fernandezcuesta merged 1 commit into
pahaz:masterfrom
RasterBurn:master

Conversation

@RasterBurn

Copy link
Copy Markdown
Contributor

My goal is to support socket forwarding similar to what OpenSSH 6.7 supports. In my case, I am only supporting forwarding to a Unix domain socket on the local side of the forward, not on the remote end.

The benefit I'm gaining out of this patch is that I can forward a remote port to a local Unix domain socket, so only users on the system that have read permissions on socket file can connect to the tunnel. This, I believe, will be more secure on a multiuser system.

To use socket forwarding, just replace your local_bind_address tuple with a string that represents the unix socket path:

from sshtunnel.sshtunnel import SSHTunnelForwarder
from time import sleep
import os
os.umask(077)
with SSHTunnelForwarder(
    ('remotehost',22),
    ssh_username='myusername',
    ssh_password='mysecretpassword',
    local_bind_address='/tmp/foo.sock') as server:
    while True:
        # press Ctrl-C for stopping
        sleep(1)
print "FINISH!"

To implement this functionality, I created two new ForwardServer classes:

  • _UnixStreamFowardServer
  • _ThreadingUnixStreamForwardServer

These are no different than their _ForwardServer counterparts except that they use TCPServer's subclass: UnixStreamServer (see docs). UnixStreamServer uses Unix domain sockets, so it's not usable on Windows.

When local_bind_address is a tuple, the code will use the existing _ForwardServer, and otherwise it will select the _UnixStreamForwardServer.

I am a little concerned about the _ForwardHandler code where I have to pass paramiko's open_channel a fake source address. First off, paramiko doesn't support the socket forwarding protocol yet (paramiko/paramiko#544 seeks to implement this). Even so, this code still seems to work with "direct-tcpip".

Second, when using the AF_UNIX address family, getpeername returns a a string instead of an address tuple like AF_INET (ref docs). When I detect that getpeername doesn't return a tuple, I assume it's AF_UNIX, and then generate a dummy address tuple.

Comment thread sshtunnel.py

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this python 3.x compatible?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use string_types

@pahaz

pahaz commented Dec 22, 2015

Copy link
Copy Markdown
Owner

This is realy cool reature. But do you have any time for merge you changes with master? Can you write test for check this functionality?

@pahaz

pahaz commented Feb 11, 2016

Copy link
Copy Markdown
Owner

Is this feature interesting for anyone else?

@fernandezcuesta

Copy link
Copy Markdown
Collaborator

Yes, looks like an interesting enhancement, maybe for 0.0.8?

@fernandezcuesta fernandezcuesta added this to the 0.0.8 milestone Feb 24, 2016
fernandezcuesta added a commit that referenced this pull request Feb 24, 2016
@fernandezcuesta
fernandezcuesta merged commit ac5ba79 into pahaz:master Mar 8, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants