J'écris un programme en utilisant pysftp, et il veut vérifier la clé d'hôte SSH par rapport à C:\Users\JohnCalvin\.ssh\known_hosts
.
En utilisant PuTTY, le programme du terminal l’enregistre dans le registre [HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys]
.
Comment concilier la différence entre pysftp et PuTTY?
Mon code est:
import pysftp as sftp
def Push_file_to_server():
s = sftp.Connection(Host='138.99.99.129', username='root', password='*********')
local_path = "testme.txt"
remote_path = "/home/testme.txt"
s.put(local_path, remote_path)
s.close()
Push_file_to_server()
La réponse d'erreur que je reçois est:
E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init __. Py: 61: UserWarning:
Impossible de charger HostKeys à partir de C:\Users\JohnCalvin.ssh\known_hosts.
Vous devrez explicitement charger HostKeys (cnopts.hostkeys.load (nom du fichier)) ou désactiver la vérification de HostHkeyKey (cnopts.hostkeys = None). warnings.warn (wmsg, UserWarning) Traceback (appel le plus récent en dernier): fichier "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", ligne 14, dans Push_file_to_server () Fichier "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py ", ligne 7, dans Push_file_to_server s = sftp.Connection (Host = '138.99.99.129', nom d'utilisateur = 'root', mot de passe = '********') Fichier" E :\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init __. Py ", ligne 132, dans init self._tconnect ['hostkey'] = self._cnopts.get_hostkey (hôte) Fichier "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init __. Py", ligne 71, dans get_hostkey, relance SSHException ("Aucune clé d'hôte pour l'hôte% s trouvée."% Host) paramiko.ssh_exception.SSHException. : Aucune clé d'hôte pour l'hôte 138.99.99.129 trouvée. Exception ignorée dans:> Traceback (appel le plus récent en dernier): Fichier "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init __. Py", ligne 1013, dans del self .close () Fichier "E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init __. py", ligne 784, à proximité si self._sftp_live: AttributeError: l'objet 'Connexion' n'a pas d'attribut '_sftp_live'
La solution suivante a fonctionné pour moi:
import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None
with pysftp.Connection(Host, username, password, cnopts=cnopts) as sftp:
sftp.put(local_path, remote_path)
Vous pouvez trouver plus d'informations ici: https://stackoverflow.com/a/38355117/1060738
Ne définissez pas _cnopts.hostkeys = None
_ (comme le montre la réponse la plus votée), à moins que vous ne vous préoccupiez pas de la sécurité. Vous perdez ainsi une protection contre attaques de type homme au milie .
Utilisez _CnOpts.hostkeys
_ (renvoie HostKeys
) pour gérer les clés d’hôte approuvé.
_cnopts = pysftp.CnOpts()
cnopts.hostkeys.load('known_hosts')
with pysftp.Connection(Host, username, password, cnopts=cnopts) as sftp:
_
où _known_hosts
_ contient une clé publique de serveur [s] dans un format tel que:
_example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...
_
Si vous ne souhaitez pas utiliser de fichier externe, vous pouvez également utiliser
_from base64 import decodebytes
# ...
keydata = b"""AAAAB3NzaC1yc2EAAAADAQAB..."""
key = paramiko.RSAKey(data=decodebytes(keydata))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add('example.com', 'ssh-rsa', key)
with pysftp.Connection(Host, username, password, cnopts=cnopts) as sftp:
_
Un moyen simple de récupérer la clé d’hôte dans ce format consiste à utiliser OpenSSH ssh-keyscan
:
_$ ssh-keyscan example.com
# example.com SSH-2.0-OpenSSH_5.3
example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...
_
Vous pouvez également faire en sorte que l'application fasse la même chose automatiquement:
tilisez Paramiko AutoAddPolicy avec pysftp
(Il ajoutera automatiquement les clés d'hôte des nouveaux hôtes à _known_hosts
_, mais pour les clés d'hôte connues, il n'acceptera pas une clé modifiée.)
Cependant, pour une sécurité absolue, vous ne devez pas récupérer la clé de l'hôte à distance, car vous ne pouvez pas en être sûr, si vous n'êtes pas déjà attaqué.
Voir mon article Où puis-je obtenir l'empreinte de la clé de l'hôte SSH pour autoriser le serveur?
C'est pour mon client WinSCP SFTP, mais la plupart des informations sont valables en général.
Si vous devez vérifier la clé de l'hôte en utilisant uniquement son empreinte, reportez-vous à la section Python - pysftp/paramiko - Vérifier la clé en utilisant son empreinte .
Essayez d’utiliser la version 0.2.8 de la bibliothèque pysftp. $ pip uninstall pysftp && pip install pysftp==0.2.8
Et essayez avec ceci:
try:
ftp = pysftp.Connection(Host, username=user, password=password)
except:
print("Couldn't connect to ftp")
return False
Pourquoi ça? Fondamentalement, est un bug avec la 0.2.9 de pysftp ici tous les détails https://github.com/Yenthe666/auto_backup/issues/47
J'ai implémenté auto_add_key
dans ma fourche pysftp github .
auto_add_key
ajoutera la clé à known_hosts
si auto_add_key=True
Une fois qu'une clé est présente pour un hôte dans known_hosts
cette clé sera vérifiée.
Veuillez indiquer Martin Prikryl -> réponse à propos des problèmes de sécurité.
Cependant, pour une sécurité absolue, vous ne devez pas récupérer la clé de l'hôte à distance, car vous ne pouvez pas en être sûr, si vous n'êtes pas déjà attaqué.
import pysftp as sftp
def Push_file_to_server():
s = sftp.Connection(Host='138.99.99.129', username='root', password='pass', auto_add_key=True)
local_path = "testme.txt"
remote_path = "/home/testme.txt"
s.put(local_path, remote_path)
s.close()
Push_file_to_server()
Remarque: Pourquoi utiliser le gestionnaire de contexte
import pysftp
with pysftp.Connection(Host, username="whatever", password="whatever", auto_add_key=True) as sftp:
#do your stuff here
#connection closed
Salut Nous avons eu le même problème si je vous ai bien compris. Vérifiez donc quelle version de pysftp vous utilisez. Si c'est le dernier en date, la version 0.2.9 est abaissée à 0.2.8. Regarde ça. https://github.com/Yenthe666/auto_backup/issues/47