Paramiko: навсегда добавить host_key в known_hosts

Этот код помогает мне установить ssh-соединение. Я знаю, что set_missing_host_key_policy помогает, когда ключ не найден в known_hosts. Но он ведет себя не так, как настоящий ssh, потому что после первого запуска этого кода я предположил, что host_key будет добавлено к known_hosts и что мне больше не нужна функция set_missing_host_key_policy(). Но я ошибся (paramiko.ssh_exception.SSHException). Как я могу навсегда добавить host_key к known_hosts, используя paramiko? (Поскольку определенная часть внутреннего кода написана на «C», и host_key нужно найти в known_hosts)

Или я что-то не так понимаю? Мне нужно руководство по этому поводу...

import paramiko

client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=str(host),username =str(user),password=str(pswd))

person nidHi    schedule 16.09.2016    source источник


Ответы (3)


Из документации пакета сравните

client.load_system_host_keys(filename=None)

Load host keys from a system (read-only) file.  Host keys read with
this method will not be saved back by `save_host_keys`.

с

client.load_host_keys(filename)

Load host keys from a local host-key file.  Host keys read with this
method will be checked after keys loaded via `load_system_host_keys`,
but will be saved back by `save_host_keys` (so they can be modified).
The missing host key policy `.AutoAddPolicy` adds keys to this set and
saves them, when connecting to a previously-unknown server.

Таким образом, чтобы Paramiko хранил любые новые ключи хоста, вам нужно использовать load_host_keys, а не load_system_host_keys. Например.

client.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))

Но обычно рекомендуется избегать использования AutoAddPolicy, так как это делает вас уязвимыми для атак типа "человек посередине". В итоге я создал локальный known_hosts в той же папке, что и скрипт:

ssh -o GlobalKnownHostsFile=/dev/null -o UserKnownHostsFile=./known_hosts user@host

а затем вместо этого загрузите этот файл:

client.load_host_keys(os.path.join(os.path.dirname(__file__), 'known_hosts'))

Таким образом, я могу распространять known_hosts вместе со своим скриптом и запускать его на разных машинах, не затрагивая фактические известные_хосты на этих машинах.

person danmichaelo    schedule 11.02.2017
comment
Если вы сгенерируете known_hosts с помощью ssh, это в основном то же самое, что если вы сгенерируете его с помощью AutoAddPolicy (конечно, я имею в виду, если вы сгенерируете его самостоятельно, а затем распространите с помощью скрипта). +1 - person Martin Prikryl; 05.12.2017
comment
Я считаю, что использовать библиотеку Path немного чище: hostkeys = Path.cwd() / 'known_hosts' client.load_host_keys(hostkeys) - person Harper; 12.08.2019

Если вы хотите добавить один конкретный ключ во время выполнения (без какого-либо файла):

from paramiko import RSAKey
from paramiko.py3compat import decodebytes

client = SSHClient()

# known host key
know_host_key = "<KEY>"
keyObj = RSAKey(data=decodebytes(know_host_key.encode()))

# add to host keys
client.get_host_keys().add(hostname=HOST, keytype="ssh-rsa", key=keyObj)

# login to ssh hostname
client.connect(hostname=HOST, port=PORT, username=USER)...

источник: https://github.com/paramiko/paramiko/blob/2.6.0/tests/test_hostkeys.py#L75-L84

person Ramon Medeiros    schedule 12.12.2019
comment
Это сш. Как вы устанавливаете known_hosts, когда сервер разрешает только базовые соединения sftp? - person isaaclw; 22.02.2021

person    schedule
comment
Как это отвечает на вопрос о постоянном добавлении host_key к known_hosts? - person Martin Prikryl; 08.08.2018