Подтвердить что ты не робот

Проверить ключ хоста с помощью pysftp

Я пишу программу с использованием pysftp, и она хочет проверить ключ хоста SSH на C:\Users\JohnCalvin\.ssh\known_hosts.

Используя PuTTY, программа терминала сохраняет его в реестре [HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys].

Как примирить разницу между pysftp и PuTTY?

Мой код:

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()

Ответ на ошибку, который я получаю:

E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init __. py: 61: UserWarning:
Не удалось загрузить HostKeys из C:\Users\JohnCalvin.ssh\known_hosts.
Вам нужно будет явно загрузить HostKeys (cnopts.hostkeys.load(filename)) или отключить проверкуHostKey (cnopts.hostkeys = None). warnings.warn(wmsg, UserWarning) Traceback (последний последний вызов): Файл "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", строка 14, в     push_file_to_server() Файл "E:\OneDrive\Python\GIT\DigitalCloud\pysftp_tutorial.py", строка 7, в push_file_to_server     s = sftp.Connection(host = '138.99.99.129', username = 'root', password = '********') Файл "E:\Program Files" (x86)\Anaconda3\lib\site-packages\pysftp__init __. py ", строка 132, в INIT    self._tconnect ['hostkey'] = self._cnopts.get_hostkey (host) Файл "E:\Program Files" (x86)\Anaconda3\lib\site-packages\pysftp__init __. py ", строка 71, в get_hostkey     raise SSHException ( "Нет хоста для хоста% s найдено".% host) paramiko.ssh_exception.SSHException: Нет хоста для хоста 138.99.99.129 найденный. Исключение игнорируется в: > Traceback (большинство последний последний вызов): Файл "E:\Program Files" (x86)\Anaconda3\lib\site-packages\pysftp__init __. py ", строка 1013, в дель    self.close() Файл" E:\Program Files (x86)\Anaconda3\lib\site-packages\pysftp__init __. py ", строка 784, в Закрыть     if self._sftp_live: AttributeError: объект" Connection "не имеет атрибута" _sftp_live"

4b9b3361

Ответ 1

У меня сработало следующее решение:

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None   
with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:
    sftp.put(local_path, remote_path)

Вы можете найти больше информации здесь: fooobar.com/questions/231069/...

* Редактировать *

Установив cnopts.hostkeys=None, вы потеряете защиту от атак "Человек посередине". Используйте @martin-prikryl answer, чтобы избежать этого.

Ответ 2

Не устанавливайте cnopts.hostkeys = None (как показывает ответ с наибольшим количеством голосов), если вы не заботитесь о безопасности. При этом вы теряете защиту от атак "Человек посередине ".


Используйте CnOpts.hostkeys (возвращает HostKeys) для управления ключами доверенного хоста.

cnopts = pysftp.CnOpts()
cnopts.hostkeys.load('known_hosts')

with pysftp.Connection(host, username, password, cnopts=cnopts) as sftp:

где known_hosts содержит открытый ключ [s] сервера в таком формате:

example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

Если вы не хотите использовать внешний файл, вы также можете использовать

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:

Простой способ получить ключ хоста в этом формате - использовать ssh-keyscan OpenSSH:

$ ssh-keyscan example.com
# example.com SSH-2.0-OpenSSH_5.3
example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB...

Вы также можете заставить приложение делать то же самое автоматически:
Используйте Paramiko AutoAddPolicy с pysftp
(Он автоматически добавит ключи хостов новых хостов к known_hosts, но для известных ключей хостов он не примет измененный ключ)


Хотя для обеспечения абсолютной безопасности вам не следует извлекать ключ хоста удаленно, так как вы не можете быть уверены, что вас уже не атакуют.

См. Мою статью. Где взять отпечаток ключа хоста SSH для авторизации сервера?
Это для моего WinSCP SFTP-клиента, но большая часть информации там действительна в целом.


Если вам нужно проверить ключ хоста, используя только его отпечаток, см. Python - pysftp/paramiko - Проверить ключ хоста, используя его отпечаток.

Ответ 3

Попробуйте использовать библиотеку pysftp версии 0.2.8. $ pip uninstall pysftp && pip install pysftp==0.2.8

И попробуйте с этим:

try:
    ftp = pysftp.Connection(host, username=user, password=password)
 except:
    print("Couldn't connect to ftp")
    return False

Почему это? В основном это ошибка с 0.2.9 pysftp здесь все подробности https://github.com/Yenthe666/auto_backup/issues/47

Ответ 4

Привет. У нас была такая же проблема, если я вас хорошо понимаю. Поэтому проверьте, какую версию pysftp вы используете. Если он самый последний, который составляет 0.2.9, понизится до 0.2.8. Проверь это. https://github.com/Yenthe666/auto_backup/issues/47

Ответ 5

Я реализовал auto_add_key в моей вилке pysftp github.

auto_add_key добавит ключ к known_hosts, если auto_add_key=True
Когда ключ для хоста присутствует в known_hosts, этот ключ будет проверен.

Пожалуйста, ответьте Martin Prikrylответ о проблемах безопасности.

Хотя в целях абсолютной безопасности вам не следует извлекать ключ хоста удаленно, так как вы не можете быть уверены, что вас уже не атакуют.

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()

Примечание: Зачем использовать контекстный менеджер

import pysftp
with pysftp.Connection(host, username="whatever", password="whatever", auto_add_key=True) as sftp:
    #do your stuff here
#connection closed

Ответ 6

Сначала подключитесь к серверу с помощью ssh-клиента Windows, который использует файл known_hosts. PuTTy хранит данные в реестре Windows, однако OpenSSH использует файл known_hosts и будет добавлять записи там после подключения. Расположение по умолчанию для файла:% USERPROFILE%.ssh. Надеюсь, это поможет