pysftp wirft paramiko.ssh_exception.SSHException, obwohl die Datei unknown_hosts bereitgestellt wird?
Fehler bekommen
paramiko.ssh_exception.SSHException: Kein Hostschlüssel für Host target.org gefunden.
bei Verwendung pysftp(für eine Verbindung, für die ein bestimmter Port erforderlich ist), obwohl ich dieselbe Datei "unknown_hosts" bereitstelle, die ursprünglich für die Verbindung zu diesem Speicherort verwendet wurde (siehe den Beitrag hier ). Dh. tat ...
[airflow@airflowetl reporting]$ sftp -oPort=15259 [email protected]
The authenticity of host '[target.org]:15259 ([205.172.2.88]:15259)' can't be established.
RSA key fingerprint is SHA256:UM6OflG0rkcYohes7qOlYoJZ4TIqVd0JQSh7HXYZQVA.
RSA key fingerprint is MD5:33:c2:30:22:57:5b:57:98:2f:11:07:4d:a3:4a:10:0f.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[target.org]:15259,[205.172.2.88]:15259' (RSA) to the list of known hosts.
password
Enter password for my_user
Password:
Connected to target.org.
sftp> ls
csv_drop test_results
sftp> exit
und kopierte dann die /home/me/.ssh/known_hostsan einen anderen Ort
[airflow@airflowetl .ssh]$ ls -lha
total 8.0K
drwx------ 2 airflow airflows 25 Oct 19 17:31 .
drwx------. 32 airflow airflows 4.0K Oct 19 17:31 ..
-rw-r--r-- 1 airflow airflows 777 Oct 19 17:32 known_hosts
[airflow@airflowetl .ssh]$ ls -lha /home/airflow/projects/backups/reporting/configs/known_hosts
-rw-r--r-- 1 airflow airflows 777 Oct 19 17:34 /home/airflow/projects/backups/reporting/configs/known_hosts
(unter Hinweis darauf, dass die Berechtigungen der Name für das Original und die Kopie sind), der verwendet wird wie ...
# connect to ftp location
assert os.path.isfile(os.path.join(PROJECT_HOME, "configs", "known_hosts"))
cnopts = pysftp.CnOpts(knownhosts=os.path.join(PROJECT_HOME, "configs", "known_hosts"))
#cnopts = pysftp.CnOpts(knownhosts="/home/airflow/.ssh/known_hosts")
HOSTNAME = "target.org"
PORT = 15259
sftp = pysftp.Connection(HOSTNAME,
port=PORT,
username=CREDS["sink"]["ftp_creds"]["username"],
password=CREDS["sink"]["ftp_creds"]["password"],
cnopts=cnopts)
print(sftp.pwd())
print(sftp.listdir())
sftp.cwd(CONF["reporting_configs"]["to"]["share_folder_path"])
print(sftp.pwd())
print(sftp.listdir())
Beim Ausführen des Skripts wird jedoch die Fehlermeldung angezeigt, dass der Hostschlüssel nicht gefunden werden konnte (Beachten Sie, dass selbst die Verwendung des ursprünglichen Dateipfads "unknown_hosts" denselben Fehler auslöst (und unabhängig davon, ob der Hostname oder die IP verwendet wird)). Was könnte das verursachen? Weitere Debugging-Schritte, bei denen ich versuchen könnte, weitere Informationen zu erhalten? Ich habe nicht viel Erfahrung mit so etwas.
Wenn ich während der Ausführung in den Debugger schaue, sehe ich, dass die cnopts-Hostschlüsseleinträge den richtigen Hostschlüssel zu enthalten scheinen ...
<HostKeyEntry ['[target.org]:15259', '[205.172.2.88]:15259']: <paramiko.rsakey.RSAKey object at 0x7f8d752d4208>>
Beachten Sie, dass der Hostschlüsseleintrag "[target.org]: 15259" lautet (dh der angegebene Port wird kombiniert), obwohl der Name, der als Dienstname für die Verbindungsfunktion angegeben wird, nur "target.org" lautet.
Der vollständige Traceback sieht aus wie ...
Traceback (most recent call last):
File "./source/local2ftp.2.py", line 52, in <module>
cnopts=cnopts)
File "/home/airflow/projects/backups/reporting/venv/lib/python3.6/site-packages/pysftp/__init__.py", line 132, in __init__
self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
File "/home/airflow/projects/backups/reporting/venv/lib/python3.6/site-packages/pysftp/__init__.py", line 71, in get_hostkey
raise SSHException("No hostkey for host %s found." % host)
paramiko.ssh_exception.SSHException: No hostkey for host target.org found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x7f1a61df6f98>>
Traceback (most recent call last):
File "/home/airflow/projects/backups/reporting/venv/lib/python3.6/site-packages/pysftp/__init__.py", line 1013, in __del__
self.close()
File "/home/airflow/projects/backups/reporting/venv/lib/python3.6/site-packages/pysftp/__init__.py", line 784, in close
if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'
Beachten Sie, dass der Benutzer, über den ich ursprünglich eine Verbindung über sftpdie Befehlszeile hergestellt habe und den ich im pysftpSkript verwende, nicht der Benutzer ist, der das Skript ausführt (der Benutzer, mit dem ich eine Verbindung zum SFTP-Server hergestellt habe, ist ein spezieller Satz von Anmeldeinformationen für die Verbindung). Ich weiß nicht, ob das relevant ist.
Antworten
Das pysftp unterstützt die Hostschlüsseleinträge mit dem Port nicht.
- Überspringen Sie entweder pysftp und verwenden Sie Paramiko direkt.
- Oder es hackt durch das Ersetzen
[target.org]:15259mittarget.orgin derknown_hostsDatei.
TLDR : Der Code erwartet, dass der pystfp.ConnectionHostname mit dem in der Hostschlüsseldatei übereinstimmt (z. B. ~/.ssh/known_hosts), aber wenn der rsa-Eintrag im Hostschlüsseldateieintrag mit einer Verbindung erstellt wurde, die den Port angibt und somit dazu führt, dass der rsa-Eintrag in unknown_hosts formatiert wird ein Weg, pysftpder nicht verstehen / handhaben konnte ,
mögen...
[airflow@airflowetl reporting]$ sftp -oPort=15259 [email protected]
Der rsa-Eintrag, der erstellt wird, sieht aus wie ...
'[target.org]:15259,[205.172.2.88]:15259 ssh-rsa AAAAB3HJGVJGCTCKHGVYTVKUH===...'
Also, wenn Sie diese Hostkey-Datei für die knownhostsin ...
cnopts = pysftp.CnOpts(knownhosts=os.path.join(path, to, hostkey, or, known_hosts, file))
hostname = "target.org"
port = 15259
sftp = pysftp.Connection(hostname, port, username=user, password=pass, cnopts=cnopts)
Der Code überprüft schließlich die Hostkey-Datei auf einen Eintrag, der aussieht
"target.org"
(was Sie als das eingegeben haben hostname) findet aber nur
"[target.org]:15259"
(Der Eintrag in der Datei hostkey / unknown_hosts, der für den spezifischen Port formatiert ist, an dem Sie eine Verbindung hergestellt haben), wirft also einen Fehler auf.
Beachten Sie auch , dass Sie nicht nur verwenden können „[target.org]: 15259“ als die hostnamefür die pysftp.Connection()Funktion entweder nur um es zu passen , wenn der pysftpCode dieser interne Prüfung tut , weil es sagen wird , dass es nicht den Namen des Dienstes erkennt seit (anscheinend) ist dies keine gültige Servicename-Darstellung (dh es wird nicht nur bekannt sein, diese Zeichenfolge in die hostnameund- portKomponenten zu trennen ).
Was ich tun musste war ...
- Kopieren Sie die Datei unknown_hosts, die erstellt wurde, als ich mich zum ersten Mal mit dem Host target.org verbunden habe
- Bearbeiten Sie diese Datei dann manuell so, dass sie aussieht
'target.org,205.172.2.88 ssh-rsa AAAAB3HJGVJGCTCKHGVYTVKUH===...'
Speziell im Code ist die pysftp.Connection()Funktion ...
- Versucht, den Hostschlüssel zu bekommen
- und verwendet die zugrunde liegende
ParaminkoModul zu versuchen, den hostkey Eintrag findet aus derknownhostsDatei im gegebenencnoptarg - die verwendet die Funktion hier die Zeichenfolge übereinstimmen wörtliche mit den Einträgen aus der hostkey Datei ,
hostnamedie Sie als die eingegebenepysftp.Connectionarg (die, wenn Sie mit einem bestimmten Port angeschlossen ist , erstellt einen rsa - Eintrag, wenn sie als wörtliche genommen ist nicht die Art und Weise formatiert Sie übergeben wahrscheinlich dashostnameArgument und sind nicht einmal ein gültiger Hostname. Dies verwirrt die Übereinstimmungslogik und führt dazu, dass keine Übereinstimmungen gefunden werden - Dadurch wird eine Ausnahme ausgelöst, hier wieder im
pysftpCode