Ich schreibe ein Programm mit pysftp und es möchte den SSH-Hostschlüssel anhand überprüfen C:\Users\JohnCalvin\.ssh\known_hosts
.
Mit PuTTY speichert das Terminalprogramm es in der Registrierung [HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys]
.
Wie kann ich den Unterschied zwischen pysftp und PuTTY in Einklang bringen?
Mein Code lautet:
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()
Die Fehlerantwort, die ich erhalte, lautet:
E: \ Programme (x86) \ Anaconda3 \ lib \ site-packages \ pysftp__init __. Py: 61: UserWarning:
HostKeys konnte nicht aus C: \ Users \ JohnCalvin.ssh \ unknown_hosts geladen werden.
Sie müssen HostKeys (cnopts.hostkeys.load (Dateiname)) explizit laden oder die Überprüfung von HostKey deaktivieren (cnopts.hostkeys = None). warnings.warn (wmsg, UserWarning) Traceback (letzter Aufruf zuletzt): Datei "E: \ OneDrive \ Python \ GIT \ DigitalCloud \ pysftp_tutorial.py", Zeile 14, in push_file_to_server () Datei "E: \ OneDrive \ Python \ GIT \ DigitalCloud \ pysftp_tutorial.py ", Zeile 7, in push_file_to_server s = sftp.Connection (Host = '138.99.99.129', Benutzername = 'root', Passwort = '********') Datei" E. : \ Programme (x86) \ Anaconda3 \ lib \ site-packages \ pysftp__init __. Py ", Zeile 132, in init self._tconnect ['hostkey'] = self._cnopts.get_hostkey (host) Datei "E: \ Programme (x86) \ Anaconda3 \ lib \ site-packages \ pysftp__init __. py", Zeile 71, in get_hostkey erhöhen SSHException (" Kein Hostschlüssel für Host% s gefunden. "% Host) paramiko.ssh_exception.SSHException: Kein Hostschlüssel für Host 138.99.99.129 gefunden. Ausnahme ignoriert in:> Traceback (letzter Aufruf zuletzt): Datei "E: \ Programme (x86) \ Anaconda3 \ lib \ site-packages \ pysftp__init __. Py", Zeile 1013, in del self.close () Datei "E. : \ Programme (x86) \ Anaconda3 \ lib \ site-packages \ pysftp__init __. Py ", Zeile 784, in close if self._sftp_live: AttributeError: Das Objekt 'Connection' hat kein Attribut '_sftp_live'.
quelle
pysftp
Antworten:
Nicht einstellen
cnopts.hostkeys = None
(wie die am zweithäufigsten bewertete Antwort zeigt), es sei denn, Sie kümmern sich nicht um die Sicherheit. Sie verlieren dadurch den Schutz vor Man-in-the-Middle-Angriffen .Verwenden Sie
CnOpts.hostkeys
(RückgabeHostKeys
), um vertrauenswürdige Hostschlüssel zu verwalten.cnopts = pysftp.CnOpts(knownhosts='known_hosts') with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
Dabei
known_hosts
enthält der einen öffentlichen Serverschlüssel in einem Format wie:Wenn Sie keine externe Datei verwenden möchten, können Sie diese auch verwenden
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:
Ab pysftp 0.2.9 wird bei diesem Ansatz eine Warnung ausgegeben, die wie ein Fehler
aussieht: Die Warnung "HostKeys konnte nicht geladen werden" beim Herstellen einer Verbindung zum SFTP-Server mit pysftp
Eine einfache Möglichkeit, den Hostschlüssel in diesem Format abzurufen, ist die Verwendung von OpenSSH
ssh-keyscan
:(Aufgrund eines Fehlers in pysftp funktioniert dies nicht, wenn der Server einen nicht standardmäßigen Port verwendet. Der Eintrag beginnt mit
[example.com]:port
+ Vorsicht vor der Umleitungssh-keyscan
in eine Datei in PowerShell. )Sie können die Anwendung auch automatisch dazu
bringen, dasselbe zu tun : Verwenden Sie Paramiko AutoAddPolicy mit pysftp
(Es werden automatisch Hostschlüssel neuer Hosts hinzugefügt, bei bekannten Hostschlüsseln
known_hosts
wird jedoch kein geänderter Schlüssel akzeptiert.)Aus Sicherheitsgründen sollten Sie den Hostschlüssel jedoch nicht remote abrufen, da Sie nicht sicher sein können, ob Sie nicht bereits angegriffen werden.
Siehe meinen Artikel Woher bekomme ich den Fingerabdruck des SSH-Hostschlüssels, um den Server zu autorisieren?
Es ist für meinen WinSCP-SFTP-Client, aber die meisten Informationen dort sind im Allgemeinen gültig.
Wenn Sie den Hostschlüssel nur anhand seines Fingerabdrucks überprüfen müssen, lesen Sie Python - pysftp / paramiko - Überprüfen Sie den Hostschlüssel anhand seines Fingerabdrucks .
quelle
hostname
param in ,cnopts.hostkeys.add()
wenn es erscheint inknown_hosts
wie|1|xyzxyzxyz=|abcabcabc=
?pysftp.Connection
.Eine Möglichkeit besteht darin, die Hostschlüsselanforderung zu deaktivieren:
import pysftp cnopts = pysftp.CnOpts() cnopts.hostkeys = None with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp: sftp.put(local_path, remote_path)
Weitere Informationen dazu finden Sie hier: https://stackoverflow.com/a/38355117/1060738
Wichtige Notiz:
Durch das Einstellen
cnopts.hostkeys=None
verlieren Sie dadurch den Schutz vor Man-in-the-Middle-Angriffen. Verwenden Sie die Antwort @ martin-prikryl, um dies zu vermeiden.quelle
Versuchen Sie, die Version 0.2.8 der Pysftp-Bibliothek zu verwenden.
$ pip uninstall pysftp && pip install pysftp==0.2.8
Und versuchen Sie es damit:
try: ftp = pysftp.Connection(host, username=user, password=password) except: print("Couldn't connect to ftp") return False
Warum das? Grundsätzlich ist ein Fehler mit der 0.2.9 von pysftp hier alle Details https://github.com/Yenthe666/auto_backup/issues/47
quelle
Wenn Sie versuchen, über pysftp eine Verbindung zu "normalem" FTP herzustellen, müssen Sie den Hostschlüssel auf Keine setzen.
import pysftp cnopts = pysftp.CnOpts() cnopts.hostkeys = None with pysftp.Connection(host='****',username='****',password='***',port=22,cnopts=cnopts) as sftp: print('DO SOMETHING')
quelle
Kochbuch, um verschiedene Arten von pysftp.CnOpts () und Hostkeys-Optionen zu verwenden.
Quelle: https://pysftp.readthedocs.io/en/release_0.2.9/cookbook.html
Die Überprüfung des Hostschlüssels ist standardmäßig aktiviert. Standardmäßig werden ~ / .ssh / unknown_hosts verwendet. Wenn Sie die Hostschlüsselprüfung deaktivieren möchten (NICHT EMPFOHLEN), müssen Sie die Standard-CnOpts ändern und die .hostkeys auf Keine setzen.
import pysftp cnopts = pysftp.CnOpts() cnopts.hostkeys = None with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts): # do stuff here
Um eine völlig andere Datei mit bekannten_Hosts zu verwenden, können Sie CnOpts überschreiben, die nach ~ / .ssh / bekannte_Hosts suchen, indem Sie die Datei beim Instanziieren angeben.
import pysftp cnopts = pysftp.CnOpts(knownhosts='path/to/your/knownhostsfile') with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts): # do stuff here
Wenn Sie ~ / .ssh / unknown_hosts verwenden möchten, aber zusätzliche bekannte Hostschlüssel hinzufügen möchten, können Sie mithilfe der .load-Methode zusätzliche Dateien im bekannten_host-Format aktualisieren.
import pysftp cnopts = pysftp.CnOpts() cnopts.hostkeys.load('path/to/your/extra_knownhosts') with pysftp.Connection('host', username='me', password='pass', cnopts=cnopts): # do stuff here
quelle
Stellen Sie zuerst mit einem Windows-SSH-Client eine Verbindung zum Server her, der die Datei unknown_hosts verwendet. PuTTy speichert die Daten in der Windows-Registrierung. OpenSSH verwendet jedoch die Datei unknown_hosts und fügt dort nach dem Herstellen der Verbindung Einträge hinzu. Der Standardspeicherort für die Datei ist% USERPROFILE% .ssh. ich hoffe das hilft
quelle
Hallo, wir hatten irgendwie das gleiche Problem, wenn ich dich gut verstehe. Überprüfen Sie also, welche Pysftp-Version Sie verwenden. Wenn es das neueste ist, das 0.2.9 auf 0.2.8 herabgestuft wird. Überprüfen Sie dies heraus. https://github.com/Yenthe666/auto_backup/issues/47
quelle
Ich habe
auto_add_key
in meiner Pysftp Github Gabel implementiert .auto_add_key
fügt den Schlüssel hinzu,known_hosts
wennauto_add_key=True
Sobald ein Schlüssel für einen Host in
known_hosts
diesem Schlüssel vorhanden ist, wird geprüft.Bitte verweisen Sie auf Martin Prikryl -> Antwort zu Sicherheitsbedenken.
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()
Hinweis: Warum Kontextmanager verwenden?
import pysftp with pysftp.Connection(host, username="whatever", password="whatever", auto_add_key=True) as sftp: #do your stuff here #connection closed
quelle
FWIR, wenn die Authentifizierung nur Benutzername & pw, fügen Sie Remote - Server IP - Adresse known_hosts wie
ssh-keyscan -H 192.168.1.162 >> ~/.ssh/known_hosts
für ref https://www.techrepublic.com/article/how-to-easily-add-an-ssh-fingerprint-to-your- bekannte Hosts-Datei-in-Linux /quelle