«Код хоста для ... не найден» в коде pysftp, хотя cnopts.hostkeys имеет значение None - PullRequest
2 голосов
/ 14 марта 2019

Фон

Для SFTP через другой сервер я использую следующую команду в командной строке UNIX:

sftp -i /some_dir/another_dir/key -oPort=12345 user@12.123.456.789

Чего я хочу достичь

Я хочу преобразовать это в команду, которая будет использоваться с PySFTP.

Что я пробовал

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys = None

# source: https://pysftp.readthedocs.io/en/release_0.2.7/pysftp.html
srv = pysftp.Connection("user@12.123.456.789", port="12345",  
                         private_key_pass="/some_dir/another_dir/key")

Обнаружены ошибки

File "./aws_sql_dumper.py", line 14, in <module>
    srv = pysftp.Connection("user@12.123.456.789", port="12345",  private_key_pass="/some_dir/another_dir/key")
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 132, in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "/usr/local/lib/python3.4/dist-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 user@12.123.456.789 found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x7f6067c7ea20>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 1013, in __del__
    self.close()
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 784, in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live'

Исследования выполнены

Я прочитал следующее:

Вопрос

Я думаю, что делаю что-то не так. Как мне принять команду SFTP, используемую в командной строке UNIX, для принятия / интерпретации pysftp?


Изменения

Я изменил несколько вещей вокруг

import pysftp
cnopts = pysftp.CnOpts()
cnopts.hostkeys.load('/home/some_dir/.ssh/known_hosts')

# source: https://pysftp.readthedocs.io/en/release_0.2.7/pysftp.html
srv = pysftp.Connection("user@12.123.456.789", port="12345",  
                         private_key="/some_dir/another_dir/key", cnopts=cnopts)

Выход после изменения

Traceback (most recent call last):
  File "./aws_sql_dumper.py", line 17, in <module>
    srv = pysftp.Connection("user@12.123.456.789", port="12345",  private_key="/some_dir/another_dir/key", cnopts=cnopts)
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 132, in __init__
    self._tconnect['hostkey'] = self._cnopts.get_hostkey(host)
  File "/usr/local/lib/python3.4/dist-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 user@12.123.456.789" found.
Exception ignored in: <bound method Connection.__del__ of <pysftp.Connection object at 0x7f8120dc6438>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 1013, in __del__
    self.close()
  File "/usr/local/lib/python3.4/dist-packages/pysftp/__init__.py", line 784, in close
    if self._sftp_live:
AttributeError: 'Connection' object has no attribute '_sftp_live

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

После долгих проб и ошибок преобразование следующей команды SFTP, введенной в терминал:

sftp -i /some_dir/another_dir/key -oPort=12345 user@12.123.456.789

может быть переведено * в:

paramiko.SSHClient().connect(hostname='12.123.456.789', username='user', port=12345,
                             key_filename='/some_dir/another_dir/key')

Весь сокращенный код:

#!/usr/bin/python3

import paramiko

try:
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.WarningPolicy)
    client.connect(hostname='12.123.456.789', username='user', port=12345, 
                   key_filename='/some_dir/another_dir/key')

    # -------------------------- [ just for testing ] --------------------------
    stdin, stdout, stderr = client.exec_command('ls -la')   # THIS IS FOR TESTING
    print(stdout.read())                                    # AND PRINTING OUT

finally:
    client.close()
0 голосов
/ 14 марта 2019

Вы никогда не используете переменную cnopts.

Вам необходимо передать его параметру cnopts класса Connection в качестве ответа bad (в то время как голосование чаще всего поддерживается)на Проверка ключа хоста с помощью pysftp показывает.

Как только вы решите это, у вас возникнет проблема с закрытым ключом, так как вы передадите его параметру private_key_pass ( "privateключевая фраза ") вместо private_key.

srv = pysftp.Connection("user@12.123.456.789", port="12345",  
                         private_key="/some_dir/another_dir/key", cnopts=cnopts)

Хотя вы не должны делать cnopts.hostkeys = None, так как при этом вы потеряете безопасность.Правильным решением является проверка ключа хоста.Проверьте мой ответ на тот же вопрос для правильного решения.

...