Открытая криптография. Использование SSH во FreeBSD


Dru Lavigne
перевод Станислава Лапшанского
Впервые опубликован: http://www.computerra.ru.


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

Если вы используете FreeBSD 4.0 или выше, то ваша система уже содержит пакет OpenSSH, готовый к использованию. Как нетрудно догадаться из названия, OpenSSH - это реализация криптосистемы SSH на базе открытых исходных текстов. Подробнее о нем вы можете узнать на официальном сайте OpenSSH (см. http://www.openssh.org).

В одной из предыдущих статей (см. статью "IP packet revealed" http://www.onlamp.com/pub/a/bsd/2001/03/26/FreeBSD_Basics.html) я продемонстрировала использование утилиты telnet для удаленного доступа к компьютерам. После регистрации на удаленной системе, пользователь может делать все тоже самое, как если бы он сидел прямо за консолью удаленного компьютера. Таким образом, любая строка символов, набранная с клавиатуры вашего компьютера, посылается на удаленный компьютер и интерпретируется там, как будто она была набрана на его клавиатуре (несмотря на то, что на самом деле набранные символы перед этим путешествовали по сети). Кроме того, в той же статье мы выяснили, что и клавиатурный ввод и ответные сообщения пересылаются открытым текстом и, следовательно, легко перехватываются снифферами (анализаторами сетевого трафика).

Любая реализация криптосистемы SSH позволяет пользователю, зарегистрировавшись на удаленной машине, работать так же, как если бы он сидел за ее консолью. Однако перед тем как пользователь увидит приглашение для ввода имени и пароля, SSH сгенерирует ключ, при помощи которого будут зашифрованы все данные, которыми будут обмениваться компьютеры во время SSH-сессии. Таким образом, за кулисами незаметно проводится большая работа.

Поскольку SSH используется для удаленного доступа, на компьютере, к которому осуществляется доступ, должен присутствовать соответствующий пользовательский аккаунт. Кроме того, на удаленном компьютере должен быть запущен демон SSH, который делает из компьютера SSH-сервер. SSH-демон обычно "слушает" 22 TCP-порт. Машина, за которой сидите вы и с которой будет осуществляться подключение к SSH-демону удаленного компьютера, называется "SSH-клиент".

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

Я буду использовать два компьютера. На первом, с адресом 10.0.0.1, будет запущен SSH-демон, к нему я буду удаленно подключаться, а второй, с адресом 10.0.0.2, будет SSH-клиентом, непосредственно за ним буду сидеть я. На обеих машинах я создала пользовательский аккаунт "genisis". Используемая реализация криптосистемы называется "OpenSSH". Она использует протокол, который обычно пишут заглавными буквами: "SSH", однако, команды, которые вам придется набирать на клавиатуре, традиционно пишутся строчными: "ssh" и "sshd". Обратите внимание, что параметром для команды ssh может быть как IP-адрес, так и символическое имя хоста. В этой статье я намеренно буду использовать для обращения IP-адреса. В следующей части я подробно расскажу о проблемах, встречающихся на пути совместного использования SSH и символических имен.

Во-первых, я должна удостовериться, что на компьютере, который будет выступать в роли сервера, созданы файлы ключей. Для этого на машине с IP-адресом 10.0.0.1 я выполню следующую команду:
ls /etc/ssh

Если ее вывод подобен этому:
moduli ssh_host_dsa_key.pub ssh_host_rsa_key
ssh_config ssh_host_key ssh_host_rsa_key.pub
ssh_host_dsa_key ssh_host_key.pub sshd_config

То необходимые ключи уже созданы, однако, если я получу вывод подобный следующему:
moduli ssh_config sshd_config

То сразу становится ясно, что ключей нет и перед тем, как запустить SSH-демона, мне придется заняться их созданием. Если я проявлю нетерпение и попробую запустить демона перед тем, как будут созданы ключи, я получу отказ, сопровождающийся следующим сообщением об ошибке:
sshd
Could not load host key: /etc/ssh/ssh_host_key
Could not load host key: /etc/ssh/ssh_host_dsa_key
Disabling protocol version 1. Could not load host key
Disabling protocol version 2. Could not load host key
sshd: no hostkeys available -- exiting.

Существуют разные способы генерации необходимых ключей. Если вы продвинутый пользователь и не испытываете проблем при чтении загрузочных сценариев, то поищите в файле /etc/rc.network строки, относящиеся к ssh. Там можно найти команды, генерирующие файлы ключей. Я продемонстрирую лишь результат работы этого сценария. Самым простым способом сгенерировать ключи при их отсутствии, будет добавление следующей строки в файл /etc/rc.conf:
sshd_enable="YES"

Кроме того, наличие этой строки обеспечит запуск демона sshd при каждой перезагрузке. После сохранения внесенных изменений, я напечатала:
shutdown now

После того, как на экране опять появилось приглашение к вводу команд, я напечатала слово "exit". Поскольку при этом реинициализируются загрузочные сценарии, среди прочего на экране я вижу следующие сообщения:
Starting final network daemons: creating ssh1 RSA host key
Generating public/private rsa1 key pair.
Your identification has been saved in /etc/ssh/ssh_host_key.
Your public key has been saved in /etc/ ssh/ssh_host_key.pub.
The key fingerprint is:
12:d9:3d:f3:95:92:0e:e7:6b:54:09:80:77:a0:3e:cf root@hostname
creating ssh2 RSA host key
Generating public/private rsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_rsa_key.
Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub.
The key fingerprint is:
4b:cf:7e:af:f1:a8:01:08:64:1b:c0:79:e3:a2:58:78 root@hostname
creating ssh2 DSA host key
Generating public/private dsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_dsa_key.
Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub.
The key fingerprint is:
22:69:d7:05:23:c6:db:d9:55:2a:20:a3:34:bd:f4:ef root@hostname

(Запуск оставшихся сетевых демонов: создание хостового RSA-ключа ssh1
Генерирование открытого/секретного rsa1 ключа
Идентификационные данные будут сохранены в файле /etc/ssh/ssh_host_key
Ваш открытый ключ будет сохранен в файле /etc/ssh/ssh_host_key.pub
Отпечаток ключа:
12:d9:3d:f3:95:92:0e:e7:6b:54:09:80:77:a0:3e:cf root@hostname
создание хостового RSA-ключа ssh2
Генерирование открытого/секретного rsa ключа
Идентификационные данные будут сохранены в файле
/etc/ssh/ssh_host_rsa_key
Ваш открытый ключ будет сохранен в файле
/etc/ssh/ssh_host_rsa_key.pub
Отпечаток ключа:
4b:cf:7e:af:f1:a8:01:08:64:1b:c0:79:e3:a2:58:78 root@hostname
создание хостового DSA-ключа ssh2
Генерирование открытого/секретного rsa ключа
Идентификационные данные будут сохранены в файле
/etc/ssh/ssh_host_dsa_key
Ваш открытый ключ будет сохранен в файле
/etc/ssh/ssh_host_dsa_key.pub
Отпечаток ключа:
22:69:d7:05:23:c6:db:d9:55:2a:20:a3:34:bd:f4:ef root@hostname)

Давайте посмотрим, что тут написано. Видно, что созданы три пары ключей: для rsa1, для rsa2 и для dsa. Если вы читали предыдущую часть статьи, то вам уже знакомы аббревиатуры RSA и DSA. Но для чего так много ключей? Дело в том, что существуют две версии SSH и обе их поддерживает OpenSSH. Неудивительно, что пара ключей rsa1 используется для SSH версии 1. Из сообщений загрузочного сценария можно понять, что ssh2 (SSH версии 2) поддерживает RSA и DSA.

Каждый ключ хранится в отдельном файле. Вы легко можете узнать, где находятся открытые ключи - расширение таких файлов ".pub". Каждый открытый ключ имеет свой уникальный отпечаток. Далее мы еще встретимся с отпечатками ключей.

Кроме генерации ключей, был запущен демон sshd. Проверим это при помощи утилиты sockstat:
sockstat |grep ssh

root sshd 69820 3 tcp4 *:22 *:*
root sshd 69820 3 tcp46 *:22 *:*

Отлично, теперь хост 10.0.0.1 "слушает" 22 порт, давайте посмотрим, что произойдет, если на машине 10.0.0.2 я запущу команду ssh от имени пользователя genisis:
ssh 10.0.0.1
The authenticity of host '10.0.0.1 (10.0.0.1)' can't be established.
DSA key fingerprint is 22:69:d7:05:23:c6:db:d9:55:2a:20:a3:34:bd:f4:ef.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.0.0.1' (DSA) to the list of known hosts.
Password:

(аутентичность хоста 10.0.0.1 не может быть установлена.
Отпечаток ключа DSA: 22:69:d7:05:23:c6:db:d9:55:2a:20:a3:34:bd:f4:ef.
Вы уверены что хотите продолжить соединение? Да
Предупреждение: хост "10.0.0.1" (ключ DSA) внесен в список известных хостов.
Введите пароль:)

Сразу после того, как я введу верный пароль пользователя genisis, я получу приглашение командного интерпретатора. Для того что бы завершить сессию, я наберу "exit":
exit
logout
Connection to 10.0.0.1 closed.

Теперь второй раз:
ssh 10.0.0.1
Password:

Давайте поглядим, что же произошло. В первый раз, когда я воспользовалась SSH, меня попросили сверить отпечаток DSA ключа нашего сервера. Как только я, убедившись что прелагаемый отпечаток совпадает с первоначальным, выданным при генерации, напечатала на клавиатуре "yes", копия открытого ключа нашего сервера была скопирована на клиент, с которого производилось обращение (хост 10.0.0.2):
more ~genisis/.ssh/known_hosts
10.0.0.1 ssh-dss AAAAB3NzaC1kc3MAAACBAPiOFgV4PpsbXfkaxGD+hCr02Cv9P3OJDKfaXge059
cSohLN/n/kd2Nz/E1mDvT4Y8nSAQL7M667iMeqJ0WTpcdI59ktuPtvOsYBc7SNoJ6aPqqoKo682mAfC
NpUFZ3jirbWGFnaF3WpJsWFyeOY6vyD4hVT6CkunL2ovoYSJND7AAAAFQDjZ2TNBixZByXB+h00wxCN
tHZ8zQAAAIEAl4lePs+e5v9f1H93l2GLXtxXhXyasr+X42HnKgKQTMR+iLgxhtD0Eb/ftTMK+n2ECn9
3MwCNTgx5tdGX06dyBdK5xEfjV4tJnmnP42UweBwOHKpRkNLiMBN4onh7KKXjhXWmH0MpO5fhaHy6k0
f+yTTLckCKd2IO/TgGJitjlo4AAACBAM+3JMr8M+MQoa6D7BU0pNJVGoTmGdxrLotMNLmUdqM0xIFKr
3dBrgqY+gsDciQEG1CSqDDhusrkz3LRBmnuG68tE7WPPjzGZrT46ZYCmMeZume67xVN0dDd57BuxmhK
B7iKvmlM0v+EkvJ0XTlNCwBTWuU3cdTdhkWT7swxGhvf

Когда я в следующий раз обращаюсь к серверу по SSH, открытый ключ севера сравнивается с копией находящейся на клиенте и, поскольку они одинаковы, клиент считает, что я обращаюсь к аутентичному серверу (т.е. сервер не подменен злоумышленником - прим. переводчика ) и не предлагает мне проверить отпечаток ключа. Таким образом, я просто получаю запрос на ввод пароля.

Итак, давайте кратко подведем итог - что же происходит у нас за кулисами:
ssh клиент подключается к ssh серверу, используя 22 порт.
ssh сервер, для подтверждения своей подлинности, посылает ssh клиенту свой открытый ключ.
ssh клиент сравнивает полученный ключ со своей копией. Если копии ключа у клиента нет, то выдается отпечаток серверного ключа для того, чтобы пользователь мог подтвердить его достоверность.
Как только подлинность сервера подтверждена, создается секретный ключ, который используется для шифрования и дешифрования всех данных, которыми обмениваются клиент и сервер.
Теперь наступает очередь подтвердить "достоверность" пользователя. По умолчанию выдается приглашение для ввода пользовательского пароля, который будет передан в зашифрованном виде.
Как только пользователь успешно доказал свою аутентичность, он получает приглашение интерпретатора команд на удаленной системе. Все данные, передаваемые между клиентом и сервером во время этой сессии, будут зашифрованы.

OpenSSH поддерживает и другие методы аутентификации, однако мы описали то, что произойдет при использовании стандартной конфигурации, присутствующей на вашей FreeBSD. Вы, вероятно, заметили, что сервер послал открытый ключ DSA, что означает использование им SSH версии 2. Это хорошее "умолчание", поскольку вторая версия SSH куда безопаснее, чем первая.

Вы могли заметить, что по умолчанию, для аутентификации пользователю не требуется пара ключей, ему необходимо только ввести корректный пароль. Попробуем изменить такое поведение. Во-первых, при помощи программы ssh-keygen, я сгенерирую пару ключей для пользователя genisis на машине 10.0.0.2:
ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/genisis/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/genisis/.ssh/id_rsa.
Your public key has been saved in /home/genisis/.ssh/id_rsa.pub.
The key fingerprint is:
fd:5a:cc:cf:a9:f0:ea:9c:93:ea:1a:04:48:b1:47:14 genisis@hostname

(Генерирование открытого/секретного rsa ключа.
Введите имя файла ключа (/home/genisis/.ssh/id_rsa):
Введите секретную фразу (нажмите Enter для выбора пустой фразы):
Введите секретную фразу еще раз:
Секретный ключ сохранен в файл /home/genisis/.ssh/id_rsa.
Открытый ключ сохранен в файл /home/genisis/.ssh/id_rsa.pub.
Отпечаток ключа:
fd:5a:cc:cf:a9:f0:ea:9c:93:ea:1a:04:48:b1:47:14 genisis@hostname)

При использовании утилиты ssh-keygen, при помощи ключа "-t", укажите необходимый способ генерации пары ключей. Я выбрала генерацию пары ключей по алгоритму RSA для SSH версии 2, поскольку использование SSH версии 2 более безопасно, чем использование первой версии и, кроме того, алгоритм RSA более криптостоек, чем DSA. В процессе генерирования пары ключей, мне пришлось ввести секретную фразу, которая может быть использована для удостоверения в том, что я являюсь владельцем сгенерированной пары ключей, или, что более важно, секретного ключа. Секретная фраза функционально эквивалентна паролю, однако она должна быть запоминающаяся и более длинная (подразумевается, что пароли везде разные и поэтому ценность их ниже, чем ценность пары ключей, которая "одна на всех" и удостоверяет вас, в идеале, повсеместно - прим. переводчика ). Как только мне потребуется использование секретного ключа, мне обязательно предложат ввести секретную фразу. Если я забуду секретную фразу, то мне придется сгенерировать новую пару ключей.

Помните, что в паре ключей открытый ключ может быть открыт (например опубликован у вас на веб-странице - прим. переводчика ), а секретный - должен быть строго засекречен.

Взгляните на права доступа, присвоенные файлам ключей по умолчанию:
ls ~/genisis/.ssh
total 4
-rw------- 1 genisis genisis 951 Nov 9 15:00 id_rsa
-rw-r--r-- 1 genisis genisis 247 Nov 9 15:00 id_rsa.pub

Секретный ключ, id_rsa, доступен для чтения только пользователю genisis, а файл открытого ключа, id_rsa.pub, может прочитать любой желающий. Если для выяснения типа этих файлов я воспользуюсь утилитой file, я обнаружу, что это просто текстовые ASCII-файлы, которые можно поглядеть командой more:
file ~genisis/.ssh/*
id_rsa: ASCII text
id_rsa.pub: ASCII text

more id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA1gfc4NRnq9K17TLqhhKT3L6feKUttHTJvM054k+WhjI
vsdt4YoeNa3m6lplnOxwOh2w6o+xu+xuiHa/CQkvkAdxFU1ZGtnxtQWV06QJdodUEk55U/0y417TaDF
H1aYjsgPPSpjulKCLQv263C9KOSpjDrjZ74ZLOlQHtsJINY2c= genisis@hostname

Заметьте, что я показала вам только мой открытый ключ, оставив секретный в тайне.

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

Для безопасной передачи открытого ключа на сервер я воспользуюсь утилитой scp. Эта утилита входит в комплект OpenSSH и позволяет вам копировать файлы через защищенное соединение. Ее синтаксис очень похож на синтаксис старой доброй команды cp, различие только в том, что перед указанием целевого файла на удаленной машине, указывается ее IP-адрес, а затем, через двоеточие, путь к файлу.

Итак, сидя за машиной 10.0.0.2, я воспользуюсь этой командой для передачи моего открытого ключа на сервер:
scp ~/.ssh/id_rsa.pub 10.0.0.1:~/.ssh/authorized_keys
Password:
id_rsa.pub: 100% |***************************| 247 00:00

Обратите внимание, что при копировании я проявила осмотрительность и послала на сервер именно мой открытый ключ, а не секретный - для этого я выбрала файл с расширением ".pub". Кроме того я поменяла название целевого файла на ~/.ssh/authorized_keys. Перед тем, как началось собственно копирование, мне пришлось ввести мой пароль на удаленной системе.

Теперь, когда мой открытый ключ скопирован, я попробую опять воспользоваться SSH:
ssh 10.0.0.1

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

Используя ssh, вы можете "зайти" на удаленную машину от имени любого пользователя. Например, если в данный момент я зарегистрирована в системе как пользователь biko, но хочу подключиться к серверу под именем genisis, то для этого я могу воспользоваться ключом "-l":
ssh -l genisis 10.0.0.1

Я могу воспользоваться и другим, аналогичным по функциональности синтаксисом:
ssh genisis@10.0.0.1

Поскольку в домашнем каталоге пользователя biko нет открытого ключа пользователя genisis, мне придется ввести пароль. Я должна ввести пароль пользователя genisis, а не biko. Несмотря на то, что запомнить "кто я" на каждой системе может быть трудновато, зато мне не обязательно создавать пользователя genisis на обеих машинах.

Давайте посмотрим, что произойдет, если я попробую воспользоваться SSH под суперпользователем:
ssh 10.0.0.1
Password:
Password:
Password:
root@10.0.0.1's password:
Permission denied. Please try again.
root@10.0.0.1's password:
^c

Доступ был закрыт, даже если я вводил правильный пароль суперпользователя. Это очень правильный подход. Так же как вы не должны локально регистрироваться под суперпользователем, вы тем более не должны это делать на удаленных системах, используя ssh. Если вам требуются права суперпользователя на удаленной системе, зайдите туда при помощи ssh под аккаунтом обычного пользователя, имеющего право становиться суперпользователем (имеется в виду, что следует зайти на удаленную машину под пользователем входящим в группу wheel, а затем, воспользовавшись командой su, "превратиться" в суперпользователя - прим. переводчика ).

Для того что бы изменить поведение криптосистемы SSH, мы должны разобраться с соответствующими конфигурационными файлами. Давайте оставим это для следующего раза. Меж тем, в ознакомительных целях, вы можете почитать страницы руководства man по темам ssh_config и sshd_config. Кроме того, вас может заинтересовать список часто задаваемых вопросов и ответов на них, посвященный ssh (см. http://www.employees.org/~satch/ssh/faq/ssh-faq.html).

http://www.onlamp.com/pub/a/bsd/2002/11/14/FreeBSD_Basics.html.

Обновлено: 12.03.2015