Reputation: 51063
I am trying to push a file to an FTP server using the following code from a Python 3 course I am following. I know this question has been asked before, but other questions don't seem to have tried as many attempts as I have.
import pysftp as sftp
import paramiko
from base64 import decodebytes
def get_cnoopts():
#keydata = b"""2048 SHA256:XpP32aA8DFDaJ46A3V7GEXk+wJldB3K7HHAFlD4pvQ4 root@DevTuts (RSA)"""
keydata = b"""2048 SHA256:XpP32aA8DFDaJ46A3V7GEXk+wJldB3K7HHAFlD4pvQ4"""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnoopts = sftp.CnOpts()
cnoopts.hostkeys.add("178.62.45.50", "ssh-rsa", key)
def push_file():
s = sftp.Connection("198.63.45.20", username="root", password="sfewewetw", cnopts=get_cnoopts())
local_path = "testme.txt"
remote_path = "/home/testme.txt"
s.put(local_path, remote_path)
s.close()
push_file()
I have changed sensitive data above to protect the innocent, so this code will never work for you as is.
I first tried without the cnopts=get_cnoopts()
argument, and then I get the very explanatory error:
SSHException: No hostkey for host 178.62.45.50 found.
Then I found the code for get_cnoopts
in an answer here on this SO answer, but now I have to find a key that doesn't throw an error on decodebytes
.
Finding host keys with ssh-keyscan
yields:
# 178.62.45.50:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
178.62.45.50 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHTaCuJ+5dzrHyHWr7GwD/c2x7cwL2IaEiXpI+ygd4Ma
# 178.62.45.50:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
178.62.45.50 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGeglgB51BVCuh6wVZFrp2iyBEOFpaLDiSobQT+41Nn39kSGEJXBUPJ+aJfLRZ2e4Eu2o+3DV4gKsG4IEnV10WpBQxAmuq4EQesO/wTQdfgregarteartyertyer5sJwKkyTvLxBLX3AplbS1zBrSTvMWnqqvNV8IaqcR43JOkdt8frtm6dELalNpdTN4Vm/+VdRiFpzUIUj4lyVcnlttXXreE7p8qciRRfCFYA5OhsAvsSDxccv99dvHDYsrdomHZRbpYzel2QNSWLylEsnbRLDABY13n4xtELXC0Us8QyMjhF2x5l7fkm4RYjQmheNdkoN1Ot
# 178.62.45.50:22 SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3
178.62.45.50 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNretryreyrtZE8I2opSVi7R+2nlGMOs05s8j1NZfH3vIB7mL1ehfPbgp8Sjg8daQxQkm0U+NqWjCRE=
I tried all key lines, and the first gives me:
SSHException: No hostkey for host 178.62.45.50 found.
When I say I tried all key lines is that for each potential key given by ssh-keyscan
, I have substituted each line in the output for my keydata
variable value in my Python script.
Now I have tried using the entire string for keydata
, and skipping the words from the beginning of the key string and both give me the same error. Using the second and third key strings I get the same error. The answer I examined also suggests using pysftp.CnOpts(knownhosts='known_hosts')
where 'known_hosts' contains a server public key.
Then I tried another approach suggested in the same answer, as an alternative to get_cnoopts
:
def get_cnoopts():
cnoopts = sftp.CnOpts(knownhosts="""178.62.45.50 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGeglgB51BVCuh6wVZFrp2iyBEOFpaLDiSobQT+41Nn39kSGEJXBUPJ+aJfLRZ2e4Eu2o+3DV4gKsG4IEnV10WpBQxAmuq4EQesO/wTQCXuUPw7LknIbIA3pFvJUxOa1K3xRm2TZgs9esJwKkyTvLxBLX3AplbS1zBrSTvMWnqqvNV8IaqcR43JOkdt8frtm6dELalNpdTN4Vm/+VdRiFpzUIUj4lyVcnlttXXreE7p8qciRRfCFYA5OhsAvsSDxccv99dvHDYsrdomHZRbpYzel2QNSWLylEsnbRLDABY13n4xtELXC0Us8QyMjhF2x5l7fkm4RYjQmheNdkoN1Ot""")
return cnoopts
and I got the same error. Then I tried another suggestion, to use the winSCP->Server and protocol information dialogue, which lists MD5 and SHA-256 keys nice and explicitly. I have tried both key strings, with and without prefixes like
ssh-ed25519 255`, with the same error.
I suspect either the course's code is out of date, or I'm introducing some sort of encoding problem with copy and pasting between a source and my Python code. What could be wrong here?
Upvotes: 0
Views: 1562
Reputation: 5201
Your get_cnoopts()
doesn't return
anything, so cnoopts=get_cnoopts()
will be the same as cnoopts=
. Try adding return cnoopts
to the end of your get_cnoopts()
function:
def get_cnoopts():
keydata = b"""AAAA..."""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnoopts = sftp.CnOpts()
cnoopts.hostkeys.add("178.62.45.50", "ssh-rsa", key)
return cnoopts
I've been frustrated by pysftp's key handling myself - I only managed to get it to work by manually loading (like you do) the host's RSA key, after copy/pasting from the output of ssh-keyscan
. But the key snippets you show in your code look incorrect: an ssh RSA key should always begin with "AAAA" followed by a continuous stream of base64-encoded text (so no spaces, or hyphens). Try making these two changes and report back.
Upvotes: 1