Paramiko: SOCKS proxy support, like 'ssh -D'

Created on 6 May 2017  Â·  28Comments  Â·  Source: paramiko/paramiko

Hi, I'd like to create a SOCKS proxy from an accessible SSH server, in order to pass Python Requests over that server.
Is it possible to do this using paramiko?

Feature Needs investigation Needs patch

Most helpful comment

@Cellebyte Yes, I really need socks functionality...

All 28 comments

Thought there was an open feature req for SOCKS but all I see is #508 which mentions it in passing. Let's make it this ticket. Thanks for the report!

I also saw some offhand references to using ProxyCommand support to talk to a SOCKS process; I don't use SOCKS myself so not sure how workable that is, but if you haven't already looked into that I'd suggest doing so.

  • is their a way to hack it myself?
  • and if so, how can I achieve it.
  • need this feature purely dew to firewall restrictions.

Any updates here?

Look for your needs.

  • Do you really need Dynamic Forward?
  • I achieve my solution by using something like ssh -L in paramiko

Problem

  • ssl certificate verification does not work with Local Forward because all your requests go to localhost.

@Cellebyte Yes, I really need socks functionality...

Support for dynamic port forwarding would be great!

Same

We need it

we need it

i need it .

I need it!

Need it :)

I NEED IT!

2 years

I know man..came here looking for that too..

Same

i need it

ssh -D would be good!~

heh, I thought I was just missing something as I assumed this was part of the package.... another vote to include. ssh -D

+1

For those who have a need for this I adapted the socks5 server from Rushter ( https://github.com/rushter ) to forward the connection through a SSH tunnel using Fabric (https://github.com/fabric/fabric) because I'm lazy (and I use Fabric for my project). So with minor adaptation you can use this :
https://gist.github.com/cybiere/abe5caa3a7504bfd733eb2e5eb829fb1

As I've the need for a SOCKS proxy provided by paramiko as well, I started looking into this functionality. I have a working POC and would like to get some feedback on how interfacing with this functionality would be desired by other users. Depending on the outcome, this might allow me to upstream the functionality after polishing it (however no promises for that yet).

So here is how using the SOCKS proxy looks like with my current POC:

import paramiko
import requests

ssh_client = paramiko.SSHClient()
…
socks_proxy = ssh_client.open_socks_proxy(bind_address="127.0.0.1", port=1080)

proxies = {
            'http': 'socks5://127.0.0.1:1080',
            'https': 'socks5://127.0.0.1:1080',
        }
session = requests.Session()
session.proxies.update(proxies)
response = session.get("https://example.tld/")

socks_proxy.close()

ssh_client.close()

Calling ssh_client.open_socks_proxy() instanciates a SOCKS server which binds to the given address and port. The resulting socket accepts SOCKS connections, which get then unpacked by the SOCKS server and forwarded over a direct-tcpip channel per request to the desired destination. That's essentially the same as OpenSSH implements it.

To use the SOCKS proxy with requests one just has to configure requests to use the socket as SOCKS proxy. Of course the proxy can be used by any other application as well.

Finally socks_proxy.close() shuts down the proxy again. Calling this is optional as the proxy gets stopped whenever the SSH client gets closed too.

What do you think about this? Is that as you imagine SOCKS functionality in paramiko or do you have something different in mind?

that would work for me! Much more convenient to access APIs behind a
jumphost

On Wed, 24 Mar 2021 at 12:43, Daniel Roschka @.*>
wrote:

As I've the need for a SOCKS proxy provided by paramiko as well, I started
looking into this functionality. I have a working POC and would like to get
some feedback on how interfacing with this functionality would be desired
by other users. Depending on the outcome, this might allow me to upstream
the functionality after polishing it (however no promises for that yet).

So here is how using the SOCKS proxy looks like with my current POC:

import paramiko
import requests

ssh_client = paramiko.SSHClient()

…
socks_proxy = ssh_client.open_socks_proxy(bind_address="127.0.0.1", port=1080)

proxies = {

        'http': 'socks5://127.0.0.1:1080',

        'https': 'socks5://127.0.0.1:1080',

    }

session = requests.Session()
session.proxies.update(proxies)
response = session.get("https://example.tld/")

socks_proxy.close()

ssh_client.close()

Calling ssh_client.open_socks_proxy() instanciates a SOCKS server which
binds to the given address and port. The resulting socket accepts SOCKS
connections, which get then unpacked by the SOCKS server and forwarded over
a direct-tcpip channel per request to the desired destination. That's
essentially the same as OpenSSH implements it.

To use the SOCKS proxy with requests one just has to configure requests to
use the socket as SOCKS proxy. Of course the proxy can be used by any other
application as well.

Finally socks_proxy.close() shuts down the proxy again. Calling this is
optional as the proxy gets stopped whenever the SSH client gets closed too.

What do you think about this? Is that as you imagine SOCKS functionality
in paramiko or do you have something different in mind?

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/paramiko/paramiko/issues/955#issuecomment-805789024,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AHDBWJ3BEBNCA52P6PRZRNDTFHM6PANCNFSM4DKLANVQ
.

As I've the need for a SOCKS proxy provided by paramiko as well, I started looking into this functionality. I have a working POC and would like to get some feedback on how interfacing with this functionality would be desired by other users. Depending on the outcome, this might allow me to upstream the functionality after polishing it (however no promises for that yet).

So here is how using the SOCKS proxy looks like with my current POC:

import paramiko
import requests

ssh_client = paramiko.SSHClient()
…
socks_proxy = ssh_client.open_socks_proxy(bind_address="127.0.0.1", port=1080)

proxies = {
            'http': 'socks5://127.0.0.1:1080',
            'https': 'socks5://127.0.0.1:1080',
        }
session = requests.Session()
session.proxies.update(proxies)
response = session.get("https://example.tld/")

socks_proxy.close()

ssh_client.close()

Calling ssh_client.open_socks_proxy() instanciates a SOCKS server which binds to the given address and port. The resulting socket accepts SOCKS connections, which get then unpacked by the SOCKS server and forwarded over a direct-tcpip channel per request to the desired destination. That's essentially the same as OpenSSH implements it.

To use the SOCKS proxy with requests one just has to configure requests to use the socket as SOCKS proxy. Of course the proxy can be used by any other application as well.

Finally socks_proxy.close() shuts down the proxy again. Calling this is optional as the proxy gets stopped whenever the SSH client gets closed too.

What do you think about this? Is that as you imagine SOCKS functionality in paramiko or do you have something different in mind?

I think that would be perfect! Any chance you have a fork of this working that I can access?

You can find a fork with working code at https://github.com/yomagroup/paramiko/tree/wip-socks-proxy. Big disclaimer though: This code is not production ready yet and doesn't handle certain cases correctly! Don't use it for anything serious! I'll need some more time to iron out the remaining bugs and to polish it to make it ready for upstreaming. Until I get to that it might take a few weeks, as other topics have priority for me right now. I'll keep you posted about the progress.

@Dunedan thanks for taking a stab at this! As noted upthread I've no personal SOCKS experience but when you feel it's ready for review, please do @ me (here or in a new PR, linking back to this ticket/comment) and I'll hopefully find the time to take a gander.

@bitprophet Sounds good. I'll do. :+1:

If anybody is wondering about the current status: I'm still working on getting the code into an upstreamable state, whenever I find some time. It might still take a few more weeks before I get to a state I'm satisfied with.

@Dunedan Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Jpfonseca picture Jpfonseca  Â·  18Comments

Noctevent picture Noctevent  Â·  16Comments

ranamalo picture ranamalo  Â·  16Comments

bitprophet picture bitprophet  Â·  31Comments

sprenge picture sprenge  Â·  16Comments