Steven
Steven

Reputation: 15273

Python Connect over HTTP proxy with pysftp

Currently, I am doing SFTP transfer using Python subprocess.POPEN and PuTTY psftp.exe.

It is working, but not really clean nor transportable.

I would like to reproduce the same behavior using Python pysftp, but I do not know where to input all the parameters. I have in PuTTY the following configuration:

How should I input all these parameters in pysftp so I can retrieve my files?

EDIT: Using the answer from Martin Prikryl, I found some new stuffs to explore. If I understand well, I need to use a socket. Put I still have some problem to input all the information I need.

import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
proxy = ("gw.proxy.fr",1234)
sock.connect(proxy)
target=("123.123.123.255",23)
cmd_connect = "CONNECT {}:{} HTTP/1.1\r\n\r\n".format(*target)
sock.sendall(cmd_connect)

The respond that I receive from this is HTTP/1.0 407 Proxy Authentication Required, which is kind of normal because I did not use the Proxy authentication information anywhere. So, do you have any idea how I can use them and input them into my socket ?

Upvotes: 7

Views: 11070

Answers (3)

Martin Prikryl
Martin Prikryl

Reputation: 202474

I do not think that the pysftp supports proxies. Though note that the pysftp is just a wrapper around Paramiko library, which does support proxies.

So I suggest you to use Paramiko directly.

For a start see How to ssh over HTTP proxy in Python Paramiko?, particularly the answer by @tintin.


To authenticate to the proxy, after the CONNECT command, add a Proxy-Authorization header like:

Proxy-Authorization: Basic <credentials>

where the <credentials> is base-64 encoded string username:password.

auth = 'Basic ' + base64.encodebytes("username:password".encode()).decode()
args = ("123.123.123.255", 23, auth)
cmd_connect = "CONNECT {}:{} HTTP/1.1\r\nProxy-Authorization: {}\r\n\r\n".format(*args)

Upvotes: 2

Cristhian Gonzalez
Cristhian Gonzalez

Reputation: 71

try this:

import paramiko

use_proxy = True

# PROXY
host_proxy = ''
port_proxy = ''

# SFTP
host = ''
port = 22
username = ''
password = ''

try:
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    if host_proxy and use_proxy:
    # find the path to nc on the command line: "which nc"
        proxy = paramiko.ProxyCommand(f"/bin/nc --proxy {host_proxy}:{port_proxy} {host} {port}") 
        trans = paramiko.Transport(proxy)
    else:
        trans = paramiko.Transport((host, port))
    trans.connect(username=username, password=password)
    sftp = paramiko.SFTPClient.from_transport(trans)
except Exception as e:
    print(e)


sftp.listdir('.')

sftp.close()
trans.close()

Remember to install ncat if you run in docker, in debian. Not install netcat, it's the older version and does not work well.

apt-get -y update && apt-get -y install ncat

Upvotes: 0

Aziz Alto
Aziz Alto

Reputation: 20351

In my case, I do this:

import pysftp
import paramiko

hostname, prot = 'some.host.name', 22
proxy = paramiko.proxy.ProxyCommand('/usr/bin/nc --proxy proxy.foobar:8080 %s %d' % (hostname, port))
t = paramiko.Transport(sock=proxy)
t.connect(username='abc', password='123')

sftp = paramiko.SFTPClient.from_transport(t) # back to pysftp wrapper
sftp.listdir('.')

Upvotes: 2

Related Questions