← Назад к вопросам

Как при подключении по ssh происходит проверка подлинности сервера

2.0 Middle🔥 233 комментариев
#Linux и администрирование#Безопасность

Комментарии (3)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Механизм аутентификации сервера при подключении по SSH

При установке SSH-соединения проверка подлинности сервера — не менее важный процесс, чем аутентификация клиента, поскольку защищает от атак типа «man-in-the-middle» (MITM). Без этого механизма злоумышленник мог бы незаметно подменить целевой сервер и перехватить все передаваемые данные, включая пароли и приватные ключи.

Фазы установления SSH-соединения

Процесс разделен на несколько четких этапов:

  1. Установление TCP-соединения на порт 22 (или другой указанный).
  2. Обмен версиями протокола (Client/Server Hello).
  3. Ключевой обмен (Key Exchange) для установления общих сессионных ключей.
  4. Аутентификация сервета (Server Authentication).
  5. Аутентификация клиента (Client Authentication).
  6. Начало интерактивной сессии.

Критической для нашей темы является четвертая фаза.

Механизм проверки подлинности сервера

В основе лежит модель асимметричной криптографии и инфраструктура открытых ключей в упрощенной форме.

Процесс шаг за шагом:

  1. Передача серверного «host key»: После успешного ключевого обмена сервер отправляет клиенту свой открытый ключ, часто называемый «host key». Этот ключ может быть типа RSA, ECDSA или Ed25519.

  2. Проверка клиентом: Клиент проверяет, есть ли у него уже запись об этом хосте и ключе. Эти данные хранятся локально в файле ~/.ssh/known_hosts (для пользователя) или /etc/ssh/ssh_known_hosts (глобально). Формат записи:

    [хост/IP] [тип_ключа] [открытый_ключ_сервера]
    
  3. Сценарий «знакомого хоста»:

    *   Клиент вычисляет криптографический **хэш (fingerprint)** полученного ключа и сравнивает его с хэшем ключа, сохраненного в `known_hosts` для данного хоста.
    *   Если они **совпадают** — сервер признается подлинным, соединение устанавливается дальше.
    *   Если ключ **не совпадает** — это критическое предупреждение о возможной MITM-атаке или смене ключа на сервере. Клиент разрывает соединение с ошибкой.

  1. Сценарий «незнакомого хоста»:
    *   Если записи о хосте в `known_hosts` нет, клиент (в интерактивном режиме) покажет пользователю **отпечаток (fingerprint)** ключа сервера и запросит подтверждение.
```
The authenticity of host '192.168.1.10 (192.168.1.10)' can't be established.
ECDSA key fingerprint is SHA256:AbCdEf1234567890...xyz.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
```
    *   Пользователь должен **независимо проверить этот отпечаток** (например, спросив у администратора сервера) и подтвердить подключение (`yes`).
    *   После подтверждения открытый ключ сервера будет **сохранен** в локальный файл `known_hosts` для будущих сверок.

Техническая реализация и криптография

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

Пример процесса на псевдокоде:

# На стороне клиента после получения подписанного сообщения от сервера
def verify_server_authenticity(received_public_key, session_data, signature):
    if host in known_hosts:
        stored_public_key = known_hosts[host]
        if stored_public_key != received_public_key:
            raise SecurityWarning("Host key changed! Possible MITM attack!")

    # Проверяем, что сервер владеет соответствующим приватным ключом,
    # подписавшим данные сессии
    is_signature_valid = verify_signature(
        public_key=received_public_key,
        message=session_data,
        signature=signature
    )

    if not is_signature_valid:
        raise AuthenticationFailed("Server signature is invalid.")

    # Если все проверки пройдены и хост новый — сохраняем ключ
    if host not in known_hosts:
        known_hosts.add(host, received_public_key)

Рекомендации по безопасности (Best Practices)

  • Первичная верификация отпечатка (fingerprint): При первом подключении к любому серверу никогда не подтверждайте его автоматически. Отпечаток нужно сверить по доверенному каналу.
  • Отпечаток по SSHFP и DNS: В корпоративных средах можно публиковать отпечатки ключей в DNS-записях типа SSHFP. Клиент может проверить их, если включена опция VerifyHostKeyDNS.
  • Использование централизованного хранилища ключей: В инфраструктуре для управления known_hosts используют конфигурационные системы (Ansible, Puppet) или специализированные решения.
  • Актуальные алгоритмы: Отдавайте предпочтение современным и безопасным алгоритмам (ed25519, ecdsa) вместо устаревшего rsa.

Итог: Проверка подлинности сервера в SSH — это фундаментальный механизм, построенный на доверенном первом контакте и последующей криптографической верификации. Правильное его понимание и использование — основа безопасности любых автоматизированных и ручных операций в распределенных системах.

Как при подключении по ssh происходит проверка подлинности сервера | PrepBro