Сообщение WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! пугает не зря. SSH специально останавливает подключение, когда ключ удалённого хоста больше не совпадает с тем, что уже сохранён у клиента в known_hosts. Для администратора это развилка: иногда всё безобидно и связано с переустановкой сервера, миграцией, сменой IP или ротацией host key, а иногда это именно тот случай, ради которого защита и придумана, — предупреждение о возможной атаке man in the middle.
Самая частая ошибка в такой ситуации — сразу удалить запись и подключиться заново, не проверив, почему ключ изменился. Формально проблема исчезнет, но вы отключите собственную защиту именно в момент, когда она нужна больше всего. Безопасный путь другой: сначала понять причину, затем проверить новый отпечаток ключа по доверенному каналу, и только после этого обновить локальный known_hosts.
Ниже разберём практический сценарий для Debian/Ubuntu: как интерпретировать ошибку ssh host key verification failed, как использовать ssh-keygen -R и ssh-keyscan, когда изменение ключа нормально, а когда стоит остановиться и расследовать инцидент.
Что означает это предупреждение SSH
Когда вы впервые подключаетесь к серверу по SSH, клиент получает публичный host key удалённой стороны и сохраняет его локально. Обычно это файл ~/.ssh/known_hosts у конкретного пользователя. При следующих соединениях SSH сравнивает ключ сервера с уже известным значением. Если совпадения нет, соединение блокируется.
Это защищает от подмены узла. Допустим, раньше вы ходили на сервер 203.0.113.10, и клиент знает его ключ. Если теперь кто-то перехватывает трафик, поднимает поддельный SSH-сервис или DNS/IP указывает уже на другой хост, SSH видит несоответствие и показывает предупреждение.
Ключевая мысль простая: проблема не в том, что SSH «сломался», а в том, что он заметил изменение идентичности удалённого хоста и требует подтверждения, что это изменение легитимно.
Сообщение часто выглядит так:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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.
Host key verification failed.
Из этого текста видно две возможные группы причин: либо есть риск MITM, либо на сервере действительно изменился host key. На практике второе встречается регулярно, особенно после переустановки ОС, клонирования VM, пересоздания инстанса в облаке или ручной ротации ключей OpenSSH.
Когда изменение host key нормально
Смена ключа сама по себе не всегда проблема. В Debian и Ubuntu это может произойти после вполне штатных операций. Например, вы переустановили систему, восстановили сервер из шаблона, подняли новый экземпляр вместо старого, изменили hostname/IP в рамках миграции или вручную перевыпустили SSH host keys.
Особенно часто ошибка возникает после миграции на новый VDS, когда у нового сервера остаётся старый IP или DNS-имя, а содержимое /etc/ssh/ssh_host_* уже другое. Для клиента это выглядит как подмена хоста, хотя по факту это просто новый экземпляр сервера.
Нормальными причинами обычно бывают:
- переустановка Debian/Ubuntu на том же IP;
- восстановление из образа или шаблона;
- замена сервера при миграции;
- включение новых алгоритмов host key и отключение старых;
- плановая ротация ключей по политике безопасности.
Но даже если одна из этих причин кажется очевидной, подтверждение всё равно нужно. Если сервер «точно вчера переустанавливали» со слов коллеги в чате — это ещё не проверка. Нужен доверенный источник: консоль провайдера, out-of-band доступ, журнал изменений, CMDB, Ansible inventory, сохранённые отпечатки в документации или подтверждение от сотрудника, который реально выполнял работы.
Когда нужно подозревать атаку или ошибочную маршрутизацию
Есть ситуации, в которых удалять запись из known_hosts сразу не стоит. Например, если вы не планировали никаких работ, а ключ внезапно изменился. Или если меняется не один сервер, а сразу несколько. Или если у вас недавно были изменения DNS, балансировщиков, NAT, VPN, бастионов или корпоративного прокси.
Подозрительными признаками можно считать:
- изменение ключа без плановых работ;
- несовпадение отпечатка с тем, что показывает консоль сервера;
- неожиданную смену типа ключа, например был
ed25519, а стал неизвестный вам алгоритм; - подключение к тому же имени, но на другой IP;
- ошибки только из одной сети, VPN или офиса.
Иногда проблема вообще не в атаке, а в том, что имя хоста теперь указывает на другой сервер. После миграции DNS мог обновиться не везде, локальный /etc/hosts мог остаться со старой записью, а балансировщик или jump-host — вести не туда. С точки зрения SSH это всё равно другой хост, и предупреждение будет абсолютно корректным.
Если вы как раз готовите перенос инфраструктуры, полезно заранее продумать план обновления ключей и DNS. На практике это сильно снижает хаос после переключения, о чём мы уже писали в материале про миграцию сайта без простоя.

Сначала проверьте, к чему вы вообще подключаетесь
Перед работой с ключами стоит убедиться, что клиент идёт именно туда, куда вы ожидаете. Начните с разрешения имени:
getent hosts example-server
host example-server
Если вы подключаетесь по нестандартному порту или через алиас в ~/.ssh/config, проверьте фактические параметры подключения:
ssh -G example-server | sed -n '1,80p'
Эта команда полезна тем, что показывает итоговую конфигурацию клиента: какой hostname подставился, какой порт, какой пользователь, применился ли ProxyJump и какие ключи SSH вообще пытается использовать. Очень часто причина находится именно здесь: администратор думает, что подключается напрямую к одному хосту, а реально идёт через алиас на другой адрес.
Если используете нестандартный порт, помните: записи в known_hosts для таких случаев обычно хранятся в формате [host]:port. Поэтому удаление записи по одному только имени может не сработать.
Как безопасно проверить новый отпечаток host key
Правильная проверка — это сравнение отпечатка ключа, который вы видите с клиента, с отпечатком, который получен по независимому доверенному каналу. Лучший вариант для VDS или облачной VM — открыть веб-консоль провайдера и посмотреть ключ прямо на сервере без участия SSH-соединения, которое сейчас вызывает сомнение.
На самом сервере Debian/Ubuntu можно вывести отпечатки так:
sudo ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub
sudo ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
sudo ssh-keygen -lf /etc/ssh/ssh_host_ecdsa_key.pub
Обычно достаточно проверить ed25519, если он используется. Отпечаток будет выглядеть примерно как строка с типом ключа и хэшем SHA256:....
Со стороны клиента можно запросить публичные ключи удалённого хоста через ssh-keyscan:
ssh-keyscan example-server
ssh-keyscan -t ed25519 example-server
ssh-keyscan -p 2222 -t ed25519 example-server
Но здесь есть важный нюанс: ssh-keyscan сам по себе не подтверждает подлинность сервера. Он лишь быстро получает ключ, который сейчас отвечает на сетевом уровне. Использовать его без сверки с консолью, документацией или другим доверенным каналом нельзя. Это инструмент удобства, а не механизм доверия.
ssh-keyscanполезен для сравнения и автоматизации, но не заменяет проверку отпечатка. Если вы не знаете, кому принадлежит полученный ключ, то просто скачали неизвестный ключ из сети.
Как найти проблемную запись в known_hosts
SSH обычно сам пишет, какая строка в known_hosts конфликтует. Например: Offending ECDSA key in /home/user/.ssh/known_hosts:7. Это самый быстрый путь: можно открыть файл и посмотреть, что именно там хранится.
Для поиска записей по имени или IP удобно использовать:
ssh-keygen -F example-server
ssh-keygen -F 203.0.113.10
ssh-keygen -F '[example-server]:2222'
Если в вашей системе включено хеширование known_hosts, записи не будут читаемыми в явном виде, но ssh-keygen -F всё равно поможет их найти.
Типовые места хранения:
~/.ssh/known_hosts— пользовательский файл;/etc/ssh/ssh_known_hosts— системный файл для всех пользователей;- дополнительные файлы, если они указаны в
GlobalKnownHostsFileилиUserKnownHostsFile.
Если предупреждение возникает у одного пользователя, а у другого нет, почти всегда дело именно в пользовательском known_hosts. Если же ошибка воспроизводится у всех, проверьте и системные файлы тоже.
Как правильно удалить старую запись
Самый безопасный и удобный способ — не редактировать файл руками, а использовать ssh-keygen -R. Команда корректно удаляет запись по хосту, IP или адресу с портом и умеет работать с хешированным known_hosts.
ssh-keygen -R example-server
ssh-keygen -R 203.0.113.10
ssh-keygen -R '[example-server]:2222'
После этого можно заново добавить ключ, но только после проверки отпечатка. Если вы просто удалили запись и немедленно подключились, то всё ещё не выполнили главный шаг — не удостоверились, что новый ключ настоящий.
Иногда нужно удалить одновременно запись по имени и по IP, потому что SSH мог сохранить обе:
ssh-keygen -R example-server
ssh-keygen -R 203.0.113.10
Если хотите сначала сделать резервную копию файла перед изменениями, это хорошая привычка:
cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak
Как заново добавить правильный ключ
Когда отпечаток уже подтверждён, есть два рабочих пути. Первый — просто подключиться по SSH и согласиться на сохранение нового ключа. Второй — заранее записать его в known_hosts, что удобнее для автоматизации, CI и массового администрирования.
Ручное добавление через проверенный ssh-keyscan выглядит так:
ssh-keyscan -t ed25519 example-server >> ~/.ssh/known_hosts
Для нестандартного порта:
ssh-keyscan -p 2222 -t ed25519 example-server >> ~/.ssh/known_hosts
После записи полезно ещё раз проверить, что в файл попал именно тот ключ, который вы сверяли по отпечатку:
ssh-keygen -F example-server
ssh-keygen -lf ~/.ssh/known_hosts
В окружениях с автоматизацией иногда удобнее хранить эталонные ключи хостов централизованно и раскатывать их через конфигурационное управление. Тогда проблема ssh remote host identification has changed решается предсказуемо: вы заранее знаете, какой ключ должен быть у какого узла.
Что делать при host key rotation
Плановая ротация host key — хорошая практика, но только если она организована аккуратно. Проблема в том, что клиенты SSH очень чувствительны к внезапной замене ключа. Если просто пересоздать ключи на боевом сервере без подготовки, пользователи и автоматизация получат лавину ошибок host key verification failed.
Более безопасный подход включает несколько шагов:
- заранее зафиксировать новый отпечаток в документации или CMDB;
- уведомить администраторов и владельцев автоматизации;
- по возможности заранее распространить новый ключ на клиенты;
- выполнить смену в согласованное окно;
- после ротации проверить, что старые записи убраны, а новые применились корректно.
Если инфраструктура большая, полезно использовать SSHFP-записи в DNS вместе с DNSSEC, либо централизованное управление known_hosts. Но даже без этого простая дисциплина изменений уже резко снижает риск паники и ошибок при ротации.
Частые сценарии на Debian/Ubuntu
Переустановка сервера на том же IP
Это самый распространённый кейс. Старый экземпляр был удалён, новый установлен с нуля, OpenSSH сгенерировал новый набор ключей. Действия: открыть консоль сервера, снять отпечаток из /etc/ssh/ssh_host_*.pub, сравнить его с тем, что отдаёт сеть, затем удалить старую запись через ssh-keygen -R и сохранить новую.
Миграция на новый VDS
Во время миграции сервисов на новый узел часто сохраняют DNS-имя, а иногда и IP, если провайдер позволяет такой сценарий. С точки зрения клиента это уже другой сервер с другой криптографической идентичностью. Именно поэтому после миграции нужно не просто проверять доступность SSH, а заранее готовить план обновления host keys у администраторов, CI, backup-джобов и deploy-скриптов.
Подключение по имени и по IP как к разным узлам
Иногда в known_hosts уже есть запись для имени, но позже вы один раз подключились по IP, или наоборот. Потом DNS изменился, и начинается путаница: одна запись валидна, вторая нет. В итоге SSH ругается только в части сценариев. В таких случаях проверьте оба варианта и почистите устаревшие записи отдельно.
Нестандартный порт
Если SSH слушает не на 22-м порту, запись будет храниться как [host]:port. Это мелочь, на которой часто теряют время: удаляют example-server, а конфликтующая запись на самом деле сидит под [example-server]:2222.
Если серверы у вас живут на виртуальном хостинге или на нескольких VDS с разными панелями управления, полезно отдельно стандартизировать учёт SSH-ключей и документирование отпечатков. Иначе даже штатная миграция превращается в серию ложных тревог.

Чего делать не стоит
Чтобы исправление было действительно безопасным, избегайте нескольких типичных антишаблонов.
- Не отключайте проверку ключей через
StrictHostKeyChecking noбез крайней необходимости. - Не удаляйте весь файл
known_hosts, если конфликтует один сервер. - Не доверяйте ключу, полученному через
ssh-keyscan, без независимой сверки. - Не игнорируйте внезапную смену ключа на production без change record или подтверждения.
- Не забывайте про системный
ssh_known_hosts, если ошибка воспроизводится у всех пользователей.
Особенно опасно привычное «ну это же мой сервер, сейчас быстро подтвержу». Именно на эту человеческую автоматизацию и рассчитаны реальные MITM-сценарии. SSH предупреждает редко, поэтому каждое такое сообщение стоит разбирать осознанно.
Короткий безопасный runbook
Если нужен практический алгоритм без лишней теории, держите короткую последовательность действий:
- Остановитесь и не подтверждайте новый ключ сразу.
- Проверьте, не было ли переустановки, миграции, смены IP, DNS или host key rotation.
- Уточните, к какому адресу и порту реально идёт SSH-клиент.
- Получите отпечаток ключа с сервера по доверенному каналу: консоль, out-of-band, документация.
- Сравните его с ключом, который отдаёт сеть.
- Удалите старую запись через
ssh-keygen -R. - Добавьте новый ключ и повторите подключение.
- Если отпечаток не совпадает и причин для смены ключа нет, расследуйте как потенциальный инцидент.
Итог
Ошибка ssh remote host identification has changed в Debian/Ubuntu — это не просто помеха при входе на сервер, а встроенный механизм проверки подлинности удалённого хоста. В нормальном процессе администрирования она чаще всего связана с переустановкой, миграцией или ротацией ключей, но относиться к ней как к рутине всё равно нельзя.
Безопасный подход состоит из трёх шагов: понять причину изменения, проверить новый отпечаток по доверенному каналу и только потом обновить known_hosts. Команды ssh-keygen -R и ssh-keyscan действительно помогают, но только в правильной последовательности. Если соблюдать её каждый раз, то и доступ восстановите быстро, и защиту от MITM не сведёте к формальности.


