Reputation: 1109
I am downloading some files with the following SSH config:
Host proxy
Hostname proxy.example.com
User proxyuser
IdentityFile ~/.ssh/proxy_id_rsa
Host target # uses password auth
Hostname target.example.com
User targetuser
ProxyCommand ssh proxy nc %h %p
I'm trying to automate downloading the files--currently using paramiko, but could use another library if it would be easier.
Here's what I'm trying based on some other answers:
from paramiko.proxy import ProxyCommand
from paramiko.transport import Transport
from paramiko.sftp_client import SFTPClient
proxy = ProxyCommand('ssh -i /Users/ben/.ssh/proxy_id_rsa [email protected] nc target.example.com 22')
client = SFTPClient(proxy)
client.connect(username='targetuser', password='targetpassword')
However, this throws the error
Traceback (most recent call last):
File "sftp.py", line 6, in <module>
client = SFTPClient(proxy)
File "/Users/ben/.virtualenvs/venv/lib/python3.5/site-packages/paramiko/sftp_client.py", line 99, in __init__
server_version = self._send_version()
File "/Users/ben/.virtualenvs/venv/lib/python3.5/site-packages/paramiko/sftp.py", line 105, in _send_version
t, data = self._read_packet()
File "/Users/ben/.virtualenvs/venv/lib/python3.5/site-packages/paramiko/sftp.py", line 177, in _read_packet
raise SFTPError('Garbage packet received')
paramiko.sftp.SFTPError: Garbage packet received
Unfortunately the error message is not very helpful so I'm at a loss for what I could change. I can't change the config on target
and I'd prefer not to change the config on proxy
if avoidable. Any suggestions?
Upvotes: 1
Views: 2370
Reputation: 1109
Solved with the following:
class PatchedProxyCommand(ProxyCommand):
# work around https://github.com/paramiko/paramiko/issues/789
@property
def closed(self):
return self.process.returncode is not None
@property
def _closed(self):
# Concession to Python 3 socket-like API
return self.closed
def close(self):
self.process.kill()
self.process.poll()
proxy = PatchedProxyCommand('ssh -i /Users/ben/.ssh/proxy_id_rsa '
'[email protected] nc target.example.com 22')
transport = Transport(proxy)
key = HostKeyEntry.from_line('target.example.com ssh-rsa '
'AAAAB3NzaC1yc2EAAAA/base64+stuff==').key
transport.connect(hostkey=key,
username='targetuser', password='targetpass')
sftp = SFTPClient.from_transport(transport)
print(sftp.listdir())
Upvotes: 1