Содержание статьи

Файл known_hosts хранит ключи публичных серверов, с которыми пользователь уже устанавливал соединение через SSH. Каждый ключ привязан к конкретному хосту, что позволяет SSH проверять подлинность сервера при повторных подключениях и предотвращать атаки типа «man-in-the-middle».
Записи в known_hosts имеют строгий формат: имя хоста или IP, зашифрованный ключ и тип ключа (например, ssh-rsa или ecdsa-sha2-nistp256). Этот формат позволяет SSH автоматически сверять текущий ключ сервера с сохранённым и блокировать соединение при расхождении данных.
При добавлении нового сервера SSH обычно предлагает автоматически записать его ключ в known_hosts. В администрировании часто используется ручное добавление или обновление записей через команды ssh-keyscan и редактирование файла для предотвращения ошибок при массовых подключениях.
Файл может содержать хэшированные имена хостов для защиты конфиденциальности списка подключений. Использование хэширования снижает риск утечки данных о серверах, особенно в публичных или совместно используемых системах. Администраторы должны проверять целостность записей и своевременно удалять устаревшие ключи.
Как SSH использует файл known_hosts для проверки подлинности серверов

При подключении к серверу через SSH клиент проверяет его публичный ключ в файле known_hosts. Если ключ совпадает с сохранённым, соединение продолжается. Если ключ изменился, SSH выдаёт предупреждение и блокирует соединение до подтверждения пользователем, что предотвращает подмену сервера.
Файл хранит записи в формате: хост, ключ, тип ключа. Для систем с большим количеством серверов рекомендуется использовать хэшированные имена хостов, чтобы скрыть реальные адреса.
Пример формата записи:
| Хост | Тип ключа | Публичный ключ |
|---|---|---|
| server.example.com | ssh-rsa | AAAAB3NzaC1yc2EAAAADAQABAAABAQC… |
SSH сравнивает ключ сервера с записью в файле по алгоритму хэширования и типу ключа. Если совпадение отсутствует, соединение прерывается. Для обновления ключа используется команда ssh-keygen -R hostname или ручное редактирование файла.
Рекомендуется регулярно проверять целостность known_hosts и удалять устаревшие ключи для предотвращения ошибок при подключении и защиты от потенциальных атак.
Структура записей в файле known_hosts и их формат

Файл known_hosts содержит одну запись на каждый сервер, с которым устанавливалось SSH-соединение. Каждая запись состоит из трёх обязательных компонентов:
- Хост или IP-адрес – имя сервера или его IP. Для повышения безопасности можно использовать хэшированные имена с помощью команды ssh-keygen -H.
- Тип ключа – алгоритм, используемый для идентификации сервера. Наиболее распространённые: ssh-rsa, ecdsa-sha2-nistp256, ed25519.
- Публичный ключ – длинная строка в формате Base64, уникальная для конкретного сервера и типа ключа.
Пример записи в файле:
- server.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC…
- [192.168.1.10]:2222 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY…
Для нескольких ключей одного сервера можно создавать отдельные записи, чтобы SSH корректно проверял все возможные алгоритмы. Хэшированные имена хостов защищают список серверов от просмотра третьими лицами, но требуют использования команды ssh-keygen -F для поиска ключа по имени.
При редактировании файла важно сохранять точный формат записи и избегать лишних пробелов, иначе SSH не сможет корректно сопоставить ключи.
Добавление новых серверов в known_hosts вручную и через SSH

Для автоматического добавления сервера в файл known_hosts достаточно выполнить команду ssh к новому хосту. При первом подключении SSH предложит подтвердить ключ сервера и сохранит его в файле после согласия пользователя:
ssh user@server.example.com
В ручном режиме запись можно добавить напрямую, используя формат: хост тип_ключа публичный_ключ. Это особенно полезно при массовом управлении серверами или подготовке предварительного списка доверенных ключей:
server.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC…
ssh-keyscan -H server.example.com >> ~/.ssh/known_hosts
При ручном добавлении важно проверять, что ключ соответствует серверу, чтобы избежать подстановки чужого ключа. Хэшированные имена хостов можно создавать с помощью ssh-keygen -H, что повышает конфиденциальность списка серверов.
Как удалить или обновить устаревшие записи в known_hosts
Удаление или обновление можно выполнить несколькими способами:
- Команда ssh-keygen – удаляет запись по имени хоста или IP:
ssh-keygen -R server.example.com
- Редактирование файла вручную – открыть ~/.ssh/known_hosts и удалить или заменить строку с устаревшим ключом.
- Обновление ключа через ssh-keyscan – получить новый ключ и добавить в файл:
ssh-keyscan -H server.example.com >> ~/.ssh/known_hosts
Рекомендуется сохранять резервную копию файла перед массовым редактированием. После удаления устаревшей записи SSH при следующем подключении предложит добавить новый ключ, что обеспечивает корректную проверку подлинности сервера.
Использование хэширования имен хостов для безопасности

Файл known_hosts может содержать хэшированные имена хостов, чтобы скрыть реальные адреса серверов. Хэширование выполняется с помощью алгоритма HMAC-SHA1 и добавляет префикс |1| к каждой записи, что делает невозможным прямое чтение хостов без ключа.
Для создания хэшированных записей используется команда:
ssh-keygen -H -f ~/.ssh/known_hosts
При поиске ключа по имени, SSH использует внутреннюю проверку хэша, поэтому подключение к серверу остаётся прозрачным для пользователя. Для администрирования и поиска конкретного хоста применяют команду:
ssh-keygen -F server.example.com
Хэширование особенно важно в средах с публичным доступом к файловой системе или при совместном использовании учетных записей, так как предотвращает раскрытие списка серверов третьим лицам.
Как обойти проверку known_hosts при подключении к новому серверу

При подключении к новому серверу SSH проверяет файл known_hosts для сверки ключей. В некоторых ситуациях может потребоваться временно обойти эту проверку, например, при автоматизированных скриптах или тестовых окружениях.
Для этого используется опция -o StrictHostKeyChecking=no в команде SSH:
ssh -o StrictHostKeyChecking=no user@server.example.com
Эта опция позволяет подключиться без запроса подтверждения ключа и автоматически добавляет новый ключ в known_hosts. Если не требуется сохранять ключ, можно дополнительно использовать -o UserKnownHostsFile=/dev/null, чтобы не менять файл:
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@server.example.com
Следует использовать обход проверки только в контролируемых средах, так как отключение проверки увеличивает риск атак типа «man-in-the-middle».
Ошибки SSH, связанные с конфликтами в known_hosts, и способы их исправления
Наиболее распространённая ошибка возникает при смене ключа сервера. SSH выдаёт сообщение вида:
| Сообщение | Причина |
|---|---|
| WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! | Ключ сервера не совпадает с записью в known_hosts. |
Чтобы исправить конфликт, нужно удалить устаревшую запись. Используется команда:
ssh-keygen -R server.example.com
После удаления можно заново подключиться к серверу, подтвердив новый ключ. Для поиска всех записей по хосту применяют:
ssh-keygen -F server.example.com
В случае нескольких ключей для одного сервера рекомендуется проверить тип ключа и при необходимости вручную скорректировать known_hosts, чтобы SSH корректно сверял ключи всех алгоритмов.
Для массового исправления конфликтов в скриптах используется комбинация ssh-keyscan и редактирования файла:
ssh-keyscan -H server.example.com >> ~/.ssh/known_hosts
Регулярная проверка и очистка устаревших записей предотвращает повторение конфликтов и обеспечивает корректную проверку подлинности серверов.
Автоматизация управления known_hosts для нескольких серверов
При работе с большим количеством серверов ручное обновление файла known_hosts становится неудобным. Автоматизация позволяет синхронизировать ключи и предотвращать ошибки при подключениях.
for host in server1.example.com server2.example.com server3.example.com; do ssh-keyscan -H $host >> ~/.ssh/known_hosts; done
Регулярное удаление устаревших ключей можно автоматизировать через ssh-keygen -R в скриптах, проверяя каждый сервер по списку:
for host in $(cat server_list.txt); do ssh-keygen -R $host; ssh-keyscan -H $host >> ~/.ssh/known_hosts; done
Для централизованного управления в организациях применяют инструменты конфигурации, такие как Ansible или Puppet, которые автоматически распределяют актуальные ключи на все клиентские системы.
Использование хэшированных имен хостов вместе с автоматизацией защищает информацию о серверах и снижает риск конфликтов ключей при массовых обновлениях.
Вопрос-ответ:
Зачем SSH хранит ключи серверов в файле known_hosts?
Файл known_hosts используется для проверки подлинности сервера при подключении через SSH. Когда клиент соединяется с сервером, он сверяет публичный ключ сервера с записью в файле. Если ключ совпадает, соединение продолжается. Если ключ изменился, SSH предупреждает о потенциальной угрозе безопасности и блокирует соединение до подтверждения пользователя. Это помогает предотвратить подмену сервера и атаки типа «man-in-the-middle».
Как вручную добавить сервер в known_hosts?
Для ручного добавления нового сервера в файл known_hosts нужно знать публичный ключ сервера и формат записи: хост тип_ключа публичный_ключ. Например, запись может выглядеть так: server.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC…. Также можно использовать команду ssh-keyscan -H server.example.com >> ~/.ssh/known_hosts, которая автоматически получает публичный ключ и добавляет запись в файл.
Что делать, если SSH выдаёт сообщение о конфликте ключей?
Конфликт возникает, когда ключ сервера изменился или отличается от сохранённого в known_hosts. Исправить это можно, удалив старую запись командой ssh-keygen -R server.example.com и затем подключившись заново, чтобы добавить актуальный ключ. Для поиска записей по конкретному хосту используется ssh-keygen -F server.example.com. В случае нескольких ключей нужно проверить типы ключей и при необходимости вручную обновить файл.
Как работает хэширование имён хостов в known_hosts?
Хэширование заменяет имя сервера на защищённый хэш, чтобы скрыть адреса серверов в файле. Оно выполняется командой ssh-keygen -H -f ~/.ssh/known_hosts. SSH при подключении автоматически проверяет хэш. Для поиска конкретного хоста используют ssh-keygen -F server.example.com. Этот метод защищает список серверов от просмотра третьими лицами, особенно в общих или публичных системах.
Можно ли обойти проверку known_hosts и безопасно ли это?
Проверку можно временно отключить с помощью опции -o StrictHostKeyChecking=no при подключении: ssh -o StrictHostKeyChecking=no user@server.example.com. Чтобы не изменять файл, добавляют -o UserKnownHostsFile=/dev/null. Это позволяет подключаться без подтверждения ключа. Однако такой метод повышает риск атак «man-in-the-middle» и подходит только для контролируемых тестовых или автоматизированных сценариев.
