Парамико "Неизвестный сервер"

Я пытаюсь начать работу с библиотекой Paramiko, но библиотека выдает исключение, как только я пытаюсь подключиться с помощью следующей простой программы:

import paramiko
ssh = paramiko.SSHClient()
ssh.connect('127.0.0.1', username='boatzart', password='mypassword')

Я получаю ошибку:

Traceback (most recent call last):
File "test.py", line 6, in <module>
ssh.connect('127.0.0.1')
File "build/bdist.macosx-10.7-intel/egg/paramiko/client.py", line 316, in connect
File "build/bdist.macosx-10.7-intel/egg/paramiko/client.py", line 85, in missing_host_key
paramiko.SSHException: Unknown server 127.0.0.1

Это происходит независимо от того, какой сервер я пытаюсь.

6 ответов

Решение

Исключение было вызвано тем, что вы пропустили ключ хоста, довольно загадочный "Неизвестный сервер" является ключом - поскольку исключение было вызвано из missing_host_key

Попробуйте это вместо этого:

import paramiko

paramiko.util.log_to_file('ssh.log') # sets up logging

client = paramiko.SSHClient()
client.load_system_host_keys()
client.connect('127.0.0.1', username=username, password=password)
stdin, stdout, stderr = client.exec_command('ls -l')

Я столкнулся с той же проблемой, и вот решение, которое сработало для меня:

import paramiko

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('127.0.0.1', username=username, password=password)
stdin, stdout, stderr = client.exec_command('ls -l')

Это необходимо для установки политики, используемой при подключении к серверу, у которого нет ключа хоста ни в системном, ни в локальном объекте HostKeys. Политика по умолчанию - отклонять все неизвестные серверы (используя RejectPolicy). Вы можете заменить AutoAddPolicy или написать свой собственный класс политики.

Более подробная информация на paramiko api doc. Надеюсь это поможет.

Правильный путь:

  • Позвоните HostKeys.add в случае, возвращенном SSHClient.get_host_keys перед вызовом connect Передав ему доверенный ключ.

    keydata = b"""AAAAB3NzaC1yc2EAAAADAQAB..."""
    key = paramiko.RSAKey(data=decodebytes(keydata))
    client.get_host_keys().add('example.com', 'ssh-rsa', key) 
    
  • Или загрузите уже кэшированный хост-ключ (например, из командной строки ssh) с помощью client.load_system_host_keys(),

  • Или вы можете, по крайней мере, кэшировать хост-ключ с первой попытки, чтобы убедиться, что он не изменится в будущем.

    Для этого использования SSHClient.load_host_keys до connect, Это заставляет Paramiko автоматически добавлять новый ключ хоста в файл (в сочетании с AutoAddPolicy).

Я столкнулся с этой проблемой и хотел опубликовать решение здесь. Проблема была в том, что ssh-сервер отправлял ключи ecdsa, которые не поддерживаются (пока) с paramiko. В моей системе Debian Wheezy я отключил ecdsa, закомментировав одну строку в / etc / ssh / sshd_config:

# HostKey / etc / ssh / ssh_host_ecdsa_key

Перезапустил sshd, и он вернулся к использованию RSA. В моем файле known_hosts было несколько ключей ecdsa, поэтому я просто удалил их для сброса и вошел в систему вручную, чтобы воссоздать ключи. Оттуда Paramiko работал отлично, как и ожидалось, с проверкой ключа хоста RSA.

У меня была эта ошибка: я могу подключиться из оболочки, но paramiko говорит: "Неизвестный сервер workdevel114".

В известном_хосте было две похожих записи:

user@host> grep workdevel114 ~/.ssh/known_hosts
workdevel114 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC8qGbuI1BaBodi7sKWLfV8Eh+De80Th7HFLD4WiJWo57THl0Q+QcopUaU3pF....
user@host> grep I1BaBodi7sKWLfV8Eh+De80Th7HFLD4WiJWo57THl0Q+QcopUaU3pF ~/.ssh/known_hosts
workdevel114 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC8qGbuI1BaBodi7sK...
|1|f/auQ9nY5dFbVtOdY3ocjtVO9dM=|esvazUDTT3VIcLk9DxmPI6FZt1s= ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC8qGbuI1BaBodi7sKWLfV8Eh+De80Th7HFLD4...

Запись секунд (|1|....), кажется, сбивает с толку paramiko. Я думаю, это связано с этим билетом: https://github.com/paramiko/paramiko/issues/67

Я решил это, добавив эту строку:

client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

Но это отключает проверку хоста протокола ssh в этом случае: Paramiko считает, что ключ хоста неизвестен, но он известен. Известный Ключ игнорируется. Мне все равно, потому что атаки "человек посередине" очень маловероятны в моей среде.

параико-версия: 1.7.7.1-1ubuntu1

Я попытался включить часть ответа Мартина Прикрыла в один класс с помощью менеджера контекста.

Или вы можете хотя бы кэшировать ключ хоста с первой попытки, чтобы убедиться, что он не изменится в будущем. Для этого использованияSSHClient.load_host_keys перед подключением. Это заставляет Paramiko автоматически добавлять новый ключ хоста в файл (в сочетании сAutoAddPolicy).

      
import paramiko
from paramiko import client, sftp_client


class SFTP:
    sftp: sftp_client.SFTPClient
    ssh: client.SSHClient
    host: str
    user: str
    password: str

    def __init__(self, host: str, user: str, password: str):
        self.host = host
        self.user = user
        self.password = password

    def __enter__(self) -> sftp_client.SFTPClient:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        ssh.load_system_host_keys()
        ssh.connect(self.host, username=self.user, password=self.password)
        self.ssh = ssh

        sftp = ssh.open_sftp()
        self.sftp = sftp
        return sftp

    def __exit__(self, exc, _, __) -> bool:
        if exc is None:
            self.sftp.close()
            self.ssh.close()
            return True

        raise exc

Пример:

      
with SFTP('host', 'user', 'password') as sftp:
    ...
Другие вопросы по тегам