«Добавить правильный ключ хоста в known_hosts» / несколько ключей SSH хоста для каждого имени хоста?

147

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

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
[...].
Please contact your system administrator.
Add correct host key in /home/sward/.ssh/known_hosts to get rid of this message.
Offending RSA key in /home/sward/.ssh/known_hosts:86
RSA host key for [...] has changed and you have requested strict checking.
Host key verification failed.

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

Но я хотел бы, чтобы ssh принимал и старый ключ, и новый ключ. Язык в сообщении об ошибке (" Add correct host key") предполагает, что должен быть какой-то способ добавить правильный ключ хоста, не удаляя старый.

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

Возможно ли это, или сообщение об ошибке просто вводит в заблуждение?

Сэмюэл Эдвин Уорд
источник
9
Это ключ хоста, который генерирует ошибку. Хост должен иметь один и только один ключ. Это не имеет ничего общего с клиентскими или пользовательскими ключами. У вас есть один IP-адрес, который плавает между различными хостами или что-то?
Дэвид Шварц
4
В моем случае я знаю, что в ближайшем будущем я буду много переключаться между этими двумя клавишами, в то же время возясь с некоторыми вещами. Кажется, это также будет полезно в случае одного IP с несколькими хостами, которые вы предлагаете. Главным образом я просто хочу знать, возможно ли это для моего собственного образования, кроме какого-либо конкретного практического применения.
Сэмюэль Эдвин Уорд

Ответы:

148
  1. получите ключ rsa вашего сервера, где server_ipнаходится IP-адрес вашего сервера, например 192.168.2.1:

    $ ssh-keyscan -t rsa server_ip
    

    Пример ответа:

    # server_ip SSH-2.0-OpenSSH_4.3
    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG...
    
  2. и на клиенте скопируйте всю строку ответа server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG...и добавьте этот ключ в конец ~/.ssh/known_hostsфайла:

    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqx9m529...(the offending key, and/or the very bottom of the `known_hosts` file)
    server_ip ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwH5EXZG... (line you're adding, copied and pasted from above)
    
кванты
источник
12
Это сработало! Однако я использую «HashKnownHosts», поэтому запись выглядела немного неуместно. К счастью, ssh_config (5) указал мне на ssh-keygen (1), который объяснил, что я могу использовать «ssh-keygen -H» для хеширования не хэшированных записей. Спасибо!
Сэмюэль Эдвин Уорд
2
Это «работает», но вы не проверяете ключ, поэтому вы уязвимы для митм-атак ...
JasperWallace,
3
@JasperWallace, до тех пор , как первый шаг делается через безопасное соединение (например , с помощью локального хоста) оно должно быть довольно безопасно, я думаю
оны
3
Есть ли способ собрать все типы ключей с сервера? Иногда вы не знаете, являются ли они RSA, DSA, ECDSA, RSA1 ... и т. Д.
Sopalajo de Arrierez
3
@SopalajodeArrierez то же самое говорит и страница руководства вы можете отделить типы запятыми, так что ssh-keyscan -t rsa1,dsa,rsa,ecdsa,ed25519 server_ip- но единственная причина , чтобы найти rsa1и dsaключи, чтобы определить серверы , которые должны быть обновлены / переконфигурировать
kbolino
94

Удалите эту запись из known_hosts, используя:

ssh-keygen -R *ip_address_or_hostname*

Это удалит проблемный IP-адрес или имя хоста из файла known_hosts и попытается подключиться снова.

Из справочных страниц:

-R hostname
Удаляет все ключи, принадлежащие имени хоста, из файла known_hosts. Эта опция полезна для удаления хэшированных хостов (см. Опцию -H выше).

Луис Абарка
источник
11
msgstr "как добавить новый ключ хоста, не удаляя старый."
Сэмюэль Эдвин Уорд
4
Это лучшее решение!
Томас Деко
8
Как это имеет 19 голосов? Это не близко к ответу на заданный вопрос ..
Моломби
2
Ваш вопрос встает вторым, когда я захожу в Google по запросу «git ssh update host key автоматически». Этот ответ - то, что я искал. Открытие нового вопроса именно с тем, что я хочу, может закрыть его как дубликат.
Джейсон Гомаат
Имя хоста тоже работает
damluar
18

Очень простой способ:

cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak

Затем отредактируйте known_hosts, чтобы очистить исходный ключ, затем выполните ssh для хоста, используя:

ssh name@computer

Это добавит новый ключ автоматически; затем сравните два файла. Такая программа, как meld, - хороший способ сравнить два файла. Затем объедините файлы, чтобы в known_hosts содержались оба ключа.

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

РЕДАКТИРОВАТЬ 2015/06

Я должен добавить, возвращаясь к нему сейчас, что я заметил еще более простой способ [до тех пор, пока запись является идентифицируемой, обычно по имени хоста / IP-адресу, не считая сообщения об ошибке, ссылающегося на его конкретное местоположение];

  1. Отредактируйте известные_хосты так, чтобы временно добавить # в начале «старой» записи в известных_хостах
  2. Подключите [ssh к хосту], согласитесь на приглашение для добавления нового ключа «автоматически»
  3. Затем заново отредактируйте known_hosts, чтобы удалить #

Есть даже опция HostKeyAlias, как в

ssh -o HostKeyAlias=mynewaliasforthemachine name@computer

затем, после того, как клиент ssh добавит новый ключ под псевдонимом, вы можете либо отредактировать known_hosts, чтобы заменить псевдоним «реальным» именем хоста / IP-адресом, либо подключиться к этому воплощению этого хоста с опцией псевдонима

отметка
источник
Это «слияние»? meldmerge.org
Сэмюэл Эдвин Уорд
это сочетание :) apt-get / yum имя установки просто объединено
Марк
Я сделал вариант вашего предложения, который работал хорошо - вместо cp, mv, затем ssh, затем cat ~ / .ssh / known_hosts.bak ~ / .ssh / known_hosts> tmp; mv tmp ~ / .ssh / known_hosts
Питер Н Льюис
6

У меня та же проблема с raspberry pi, который я загружаю с нескольких разных систем (система разработки для компиляции исполняемых файлов arm, project, xbmc и т. Д.) И столкнулся с той же проблемой. Они используют DHCP в локальной сети, и мой маршрутизатор всегда использовал один и тот же IP-адрес, поскольку MAC-адрес был одинаковым. Я решил это, используя разные доменные имена в моем файле hosts:

10.10.10.110 pi-dev
10.10.10.110 pi-xbmc
10.10.10.110 pi-etc

Файл known_hosts сохраняет отпечатки пальцев по имени хоста, поэтому, даже если это один и тот же IP-адрес, каждое уникальное имя хоста получает различную запись.

Мне надоело добавлять имена в файлы хостов каждый раз, когда я использовал новую систему, поэтому я придумал еще более ленивый способ, используя начальные нули на IP-адресах, например:

$ ssh pi@10.10.10.110
$ ssh pi@010.10.10.110
$ ssh pi@10.010.10.110

Каждый вариант (неканонизированного) IP-адреса получает свою собственную запись в known_hosts.

Майк
источник
1
Ребята из OpenSSH стали мудрее, эта лазейка больше не работает в более поздних версиях.
Майк
Вы можете использовать CheckHostIP noв , ~/.ssh/configчтобы иметь возможность по- прежнему использовать лазейку. Вы даже можете определить свои псевдонимы там, так что вам не придется возиться /etc/hostsи определять CheckHostIP noтолько для этих 3 имен хостов.
GnP
3

Если ваш клиент и сервер имеют OpenSSH 6.8 или новее, вы можете использовать эту UpdateHostKeys yesопцию в вашем ssh_configили ~/.ssh/config. Например:

Host *
    UpdateHostKeys yes

Это заставляет SSH хранить все ключи хоста, необходимые серверу known_hosts, и когда сервер меняет или удаляет один ключ хоста, ключ также изменяется или удаляется в вашем known_hosts.

Микаэла
источник
Это, безусловно, самый полезный ответ! Хотя он явно не предлагает способ решения исходного вопроса, если ключ хоста уже был изменен, все остальные ответы небезопасны, поскольку они не проверяют новый ключ хоста. Эта опция позволяет вам выполнять безопасное переключение на новые ключи хоста.
Яап
1

Я не понимаю, почему вы хотите работать с двумя ключами, но вы, безусловно, можете добавить более одного действительного ключа в ~/.ssh/known_hostsфайл, но вам придется сделать это вручную.

Другое решение может заключаться в использовании StrictHostKeyChecking=noопции для этого конкретного хоста:

ssh -o StrictHostKeyChecking=no user@host

который вы могли бы поместить в псевдоним в вашем ~/.profileили что-то подобное.

alias hc=ssh -o StrictHostKeyChecking=no user@host
Свен
источник
StrictHostKeyChecking, кажется, не помогает в этом случае; по-видимому, он определяет поведение, только когда хост отсутствует в файле known_hosts. Упоминается здесь: gossamer-threads.com/lists/openssh/dev/45349#45349
Сэмюэль Эдвин Уорд
Это работает здесь. Вы получите предупреждение, но вход в систему продолжается.
Свен
Это странно. Вы используете аутентификацию по паролю? Вы используете OpenSSH?
Сэмюэль Эдвин Уорд
1

Если вы только SSH в локальной сети, то ...

Простое решение - стереть старый файл ключа и заменить его пустым. Это позволит вам повторно авторизовать все ваши соединения с новыми ключами. Если у вас есть ключи ssh, хранящиеся для сайтов за пределами вашей локальной сети, вам необходимо убедиться, что ваше первоначальное соединение безопасно, как вы это делали при первом подключении к этому серверу.

например

cp known_hosts known_hosts.old
rm known_hosts
nano known_hosts

Затем нажмите пробел, backspace cntl + x и 'y', чтобы сохранить новый буфер (файл). Это плохая практика, но все в порядке, если вы не регулярно используете ssh'ы за пределами вашей локальной сети (например, универа или рабочего сервера).

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

Всегда лучше использовать код, который вы понимаете!

Аарон
источник
4
Стирание всего known_hostsфайла каждый раз сводит на нет большую часть безопасности, в противном случае предоставляемую ssh.
Касперд
Действительно, я бы сказал, что в защищенной внутренней сети безопаснее понимать ваш код и обходить безопасность, чем бездумно копировать код. Во внешней сети тогда ситуация была бы другой.
Аарон
-1

Так много ответов, но так много, которые отказываются от защиты, полностью отключая строгую проверку хоста, или уничтожая несвязанную информацию о хосте, или просто принуждают пользователя интерактивно принимать ключи, возможно, на более позднем этапе, когда это неожиданно.

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

  • Удалите старый ключ и обновите его одной командой

    ssh-keygen -R server.example.com && \
        ssh -o StrictHostKeyChecking=no server.example.com echo SSH host key updated.
    
  • Повторите с IP-адресом (ами) или другими именами хостов, если вы их используете.

Преимущество этого подхода состоит в том, что он перезагружает сервер ровно один раз. Большинство версий ssh-keygen, по-видимому, не возвращают ошибку, если сервер, который вы пытаетесь удалить, не существует в известном файле hosts, если это проблема для вас, используйте две команды по очереди.

Этот подход также проверяет подключение и выдает хорошее сообщение для журналов в команде ssh (которая входит в систему, обновляет ключ хоста и выводит обновленный ключ хоста SSH , а затем немедленно завершает работу.

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

Если вы используете эту технику, вам никогда не придется изменять команду ssh или отключать проверку хоста, кроме как во время этой одной команды ssh. Вы можете быть уверены, что будущие сеансы ssh будут работать без конфликтов или необходимости явно принимать новый ключ, если приведенная выше команда ssh выполняется без ошибок.

markgo2k
источник
-3

У меня такая же проблема.

Все, что я сделал, это sudo nano /home/user/.ssh/ host_allowстер ключ.

Когда я вернулся на сервер, он добавил новый ключ.

Дэвид
источник
2
Еще немного информации о том, почему это происходит, будет полезно для ответа.
Дрю Хури
-4

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

OUTPUT: as show in above example
Offending key in /home/user/.ssh/known_hosts:86

Удалите строку 86, как указано в известных хостах.

CODE: 
sed -i '86d' /home/user/.ssh/known_hosts

В следующий раз при доступе через ssh система автоматически добавит новый ключ.

более новые версии ssh

использовать:

ssh-keygen -R <hostname|ip address>

Это удалит запись имени хоста и примет резервную копию старого .known_hostкакknown_hosts.old

Вийкрам Симха
источник
4
«Но я бы хотел, чтобы ssh принимал и старый ключ, и новый ключ». Ваш ответ не делает этого.
Сэмюэль Эдвин Уорд