Это первая статья о SSH. Начнем мы с разбора
процесса верификации ключей, это одна из
важный задач, которая может уберечь вас от
атак. Статья применима к бесплатной версии
OpenSSH, поставляемой со многими Unix системами и
не относится к коммерческим версиям SSH.

SSH Host Keys как защита от MiM

SSH - один из самых распространенных
протоколов, обеспечивающий безопасное
зашифрованное соединение, например для
подключения к удаленным машинам, обмена
файлами, организации защищенных туннелей,
удаленного управления без ручной
авторизации и так далее. Он был создан для
замены многих нешифрованных протоколов,
таких как telnet, FTP, RSH и подобных. Ведь
известно, что одна из проблем этих старых
протоколов (помимо того, что они все данные
передают в открытом виде) - возможность
организации man-in-the-middle атак. Хакер с
доступом во внутреннюю сеть может
перехватывать пакеты, записывать их и лишь
потом передавать по назначению. Более того,
нападающий может изменять информацию в
пакетах - например написать rm -r вместо ls -l,
или передать трояна в ходе FTP скачки.

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

  1. Клиент (броузер) соединяется с сервером (HTTPS-сервер
    на порту 443).
  2. Сервер отдает публичный ключ (X509
    сертификат).
  3. Клиент определяет, имеет ли сервер
    доступ к приватному ключу,
    ассоциированному с публичным.
  4. Броузер проверяет подпись ключа сервер
    через так называемый Certificate Authority (Verisign,
    Thawte или другие).
  5. Броузер проверяет, что сертификат
    относится именно к тому серверу, к
    которому вы коннектитесь (CN параметр). 

Все эти шаги делает и SSH, за исключением
соединения м Центром Сертификации в пункте
4, в нем применяется несколько другая схема.

SSH Host Keys в действии

Посмотрим как работает SSH при
присоединении к машине, ранее невиданной
нашим компьютером.

$ ssh ssh-server.example.com
The authenticity of host 'ssh-server.example.com (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?

Скажем "Да" и установка связи
продолжится:

$ ssh ssh-server.example.com
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'ssh-server.example.com,12.18.429.21' (RSA) to the list of known hosts.
Password: (enter password)
ssh-server.example.com $

Сервер предоставил клиенту host key в
процессе установки связи. Так как мы
никогда не соединялись с этой машиной и SSH
не имеет стороннего Центра Сертификации,
придется с ключами управляться вручную.
Клиент показывает "отпечаток" ключа ,
легко читаемую строчку из цифр - как с ней оперировать
мы рассмотрим дальше. Если
указать, что fingerprint ключа правильный, тогда
клиент SSH продолжит соединения, позволит
ввести пароль и войти в систему.

В нашем примере мы ответили "Да" и
клиент сохранил ключ удаленной машины в $HOME/.ssh/known_hosts.
В дальнейшем именно этот файл и будет
служить вашим персональным Центром
Авторизации - в нем хранится список SSH
серверов, которые вы признали правильными.
Посмотрим на последнюю строчку в этом файле:

$ tail -1 $HOME/.ssh/known_hosts
ssh-server.example.com,12.18.429.21 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA0
6jFqviLMMJ/GaJNhGx/P6Z7+4aJIfUqcVjTGQ
asS1daDYejcfOAWK0juoD+zS3BsGKKYKPA
5Gc5M8v+3NHLbPn1yTpDBgl6UzA0iiMPCbw
nOLx61MrBTk+/qJI9kyDaJf4LEY6Chx4IJP0ZN
5NmAlCtXQsca3jwFAF72mqPbF8=

(Не обращайте внимание на переносы :))

Каждая запись в known_hosts это одна строчка с
тремя или больше пробелами, отделяющими
поля:

  1. Один или больше имен серверов или IP
    серверов (в нашем случае записался адрес
    и имя, так что можно будет коннектится по
    тому и по другому).
  2. Тип ключа.
  3. Сам публичный ключ.
  4. Некие комментарии (в данном примере не
    присутствуют).

В следующий раз, когда вы будете
соединяться с машиной, SSH клиент пройдет все
стандартные шаги верификации и позволит
зайти на нее:

$ ssh ssh-server.example.com
Password: (enter password)

Очевидно, что в этот раз клиент не просил
подтверждения ключа, так как тот уже
хранится в $HOME/.ssh/known_hosts. Отмечу, что SSH
проверяет его наличие в нескольких местах:

  1. Глобальный файл известных хостов,
    обычно /etc/ssh/ssh_known_hosts. Его положение
    можно изменить через GlobalKnownHostsFile в /etc/ssh/ssh_config.
  2. Юзерский файл $HOME/.ssh/known_hosts, можно
    менять через UserKnownHostsFile.

Верификация ключа хоста

Выше я показал как коннектится к хосту и
принимать его ключ. Однако, откуда узнать
правильный ли ключ попал к нам в руки? Если
вы соединились с сервером, а атакующий
перехватил и перенаправил через себя SSH
соединение (естественно это возможно
только на стадии установки первого
соединения), он может подставить свой ключ.
Лучший путь верифицировать ключ -
прибегнуть к сторонней информации.
Например, владелец ключа может выложить его
отпечаток на защищенной SSL странице. В одном
месте где я работал, ключ распространялся
на пластиковой карточке с экстренными
телефонами, так что достаточно было просто
открыть бумажник сидя в инет-кафе. Если
невозможно проверить ключ из внешних
источников, то его можно проверить
залогинившись. Публичный ключ обычно лежит
в /etc/ssh/, так что зайдя на сервер можно
просмотреть его контрольную сумму
(используя ssh-keygen).

Вернемся к нашему соединению и посмотрим
как это делается:

$ ssh ssh-server.example.com
The authenticity of host 'ssh-server.example.com (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added 'ssh-server.example.com,12.18.429.21' (RSA) to the list of known hosts.

Password: (enter password)

ssh-server.example.com $ cd /etc/ssh
ssh-server.example.com $ ls *.pub
ssh_host_dsa_key.pub ssh_host_rsa_key.pub ssh_host_key.pub

ssh-server.example.com $ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
1024 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d ssh_host_rsa_key.pub

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

(Продолжение следует)

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии