Использование ssh-agent от SSH1 и OpenSSH

  Автор: © Jose Nazario
Перевод: © Иван Песин.


 


От переводчика: в тексте часто встречается слово authentication (идентификация, отождествление). Я его перевожу как "аутентификация" дабы подчеркнуть отличие от обычной идентификации.

Недавно я обсуждал с другом, как, используя SSH, добиться безопасной, беспарольной аутентификации. Он искал способ для автоматизации передачи некоторых файлов и хотел использовать для этого expect-скрипт (для указания пароля). Я посоветовал использовать 'ssh-agent', но в тот момент я не знал точно, как правильно его настроить. Теперь, изучив необходимую документацию, могу сказать, что это весьма просто.

Использование посредников для аутентификации, основанной на ключах - представляет путь, для упрощения межмашинных коммуникаций. Вы можете использовать такую аутентификацию и без посредника, просто нужно будет снимать блокировку с ключа каждый раз, когда вы хотите им воспользоваться. Заметим, что по умолчанию, клиент ssh будет пробовать аутентифицироваться при помощи ключей до парольной регистрации. Агент просто облегчает управление всем этим.

Существует несколько реализаций протокола ssh, каждая со своими особенностями использования и поведения. Две наиболее распространенные версии - это от openssh.org и ssh.com. OpenSSH был создан для OpenBSD и, таким образом, представляет собой свободное ПО. Ssh от ssh.com - это коммерческий продукт, бесплатный для ОС с открытыми исходными текстами (для других ОС - бесплатный для ознакомительных, некоммерческих и образовательных целей). Каждая реализация ssh таит в себе незначительные особенности.

Как будто не хватало различных реализаций, существуют, кроме того, две версии протокола ssh - SSH1 и SSH2. Эта статья ориентирована на протокол SSH1, который незначительно отличается от SSH2. Предыдущие статьи в Linux Gazette продемонстрировали применение ssh-agent для ssh2. Заметим, что по-умолчанию ssh2 использует ключи DSA, другие каталоги и имена файлов. Несмотря на это совместимость с ssh1 может быть реализована. В связи с тем, что большинство людей используют протокол SSH1 (последние данные от Альбертского университета, полученные при помощи 'scan-ssh'), мы сосредоточим внимание на этой версии. OpenSSH следует, в большинстве случаев - идеально, синтаксису программы ssh1 от ssh.com для управления ключами, основанного на посредниках. Помните, что это отличается от обработки для ssh2 (здесь не обсуждается).

Преимущества аутентификации, основанной на RSA-ключах, широко известны, и включают в себя:

Взаимную аутентификацию
При RSA-аутентификации, каждая сторона должна проверить, что другая сторона является действительно тем, о чем она сама объявляет. Клиент проверяет сервер на основе открытых ключей (хранящихся в ~/.ssh/known_hosts), а сервер проверяет клиента при помощи RSA-ключа. Это используется для защиты от атак изнутри, основанных на ошибке в проверке достоверности серверных ключей.

Мощная парольно-фразовая защита
Ключи RSA могут быть защищены с помощью парольной фразы (не пароля!), результатом чего является необходимость перебора большего количества возможностей при прямой атаке перебором. Так, например, вместо "п@р0ль" можно использовать "Томми Бетс делит комнату с Дэвидом Монком, начиная с F0xT4il." (Вы должны использовать что-то значительно более сложное и трудно разгадываемое, чем оба вышеприведенных примера.)

Мощная аутентификация
Применение для аутентификации пар RSA ключей влечет высокую надежность. Шифрование методом RSA известно, как стойкое и неподдающееся грубым атакам. Не могу сказать этого в отношении паролей.

Простота для пользователя
Надоело часто вводить пароли? Мне тоже. После некоторых моментов настройки системы (которые примерно одинаковы по количеству введенных символов с паролем), все становиться намного проще, просто подсоединяйтесь к хосту, а аутентификация будет проведена автоматически.

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

Компоненты

Для начала, давайте познакомимся с главными героями моего рассказа. Это компоненты, которые составляют всю эту штуку, ssh. Итак, знакомьтесь:

ssh
ssh-клиент. Мы считаем, что работаем с программой ssh1 от ssh.com (т.е. ssh-1.2.30) или OpenSSH (т.е. openssh-2.5.2).

sshd
Программа-сервер, снова же - версия 1, либо сервер OpenSSH.

ssh-agent
Программа-посредник, которая обеспечивает взаимодействие клиента ssh и вашим открытым ключом.

ssh-add
Утилита для загрузки (выгрузки) личных RSA-ключей в кэш ssh-agent. Они общаются при помощи сокета на клиентской машине.

ssh-keygen
Утилита для генерации вашей пары RSA-ключей, используемых при аутентификации.

~/.ssh/identity
Файл, содержащий ваш личный ключ. Следите за его защищенностью!
-rw-------   1 jose     users         530 Feb  8 12:14 identity

~/.ssh/identity.pub
Файл, содержащий открытую часть вашей RSA-пары ключей.
-rw-------   1 jose     users         334 Feb  8 12:14 identity.pub

~/.ssh/authorized_keys
Файл, содержащий список открытых ключей, которые соответствуют вашим личным ключам. Это то, что используется для вашей аутентификации.

Основные постулаты об аутентификации, основанной на посреднике

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

Перед тем, как начать, давайте убедимся, что целевой сервер поддерживает RSA аутентификацию:

$ grep RSA /etc/sshd_config
RSAAuthentication yes

Если же там написано 'no' (нет), то все ниже описанное, для вас представляет чисто академический интерес. Быть может, стоит поговорить с вашим системным администратором.

Сначала выполним ssh-keygen для генерации пары ключей. Типичная сессия выглядит следующим образом:

$ ssh-keygen
Initializing random number generator...
Generating p: ............................++ (distance 446)
Generating q: ...............++ (distance 168)
Computing the keys...
Testing the keys...
Key generation complete.
Enter file in which to save the key (/home/jose/.ssh/identity):
Enter passphrase:
(Здесь нужно ввести парольную фразу. Она отображаться не будет)
Enter the same passphrase again:
(Повторите парольную фразу. Она отображаться не будет)
Your identification has been saved in /home/jose/.ssh/identity.
Your public key is:
1024 37
1381742407287909702550799142685822876412502877754788376289642432595975854876231349873103003510
71105712187641659384690637621876213570981581119645923186045356271883326851730641652865341406978
00110207412449607393488437570247411920664869426605834174366309317794215856900173541953917001003
859838421924037121230161484169444067380979
jose@biocserver
Your public key has been saved in /home/jose/.ssh/identity.pub

Теперь у нас есть две необходимые части ключа: открытая и личная части. Теперь мы можем распространять открытый ключ. Это аналогично PGP, следовательно, вы можете передать его (открытый ключ) на любую машину, и тогда сможете подключаться безо всяких проблем. Воспользуемся командой 'scp' для копирования:

$ scp .ssh/identity.pub jon2@li:~/.ssh/biocserver.pub
jon2@li's password:
(не отображается)
identity.pub | 0 KB | 0.3 kB/s | ETA: 00:00:00 | 100%

Скопировав файл, я подсоединяюсь к целевой машине ( в нашем случае - 'li')и добавляю его в список ключей, которые принимаются:

li$ cat biocserver.pub >> authorized_keys

Так, теперь "li" полностью настроен для моей аутентификации при помощи личного RSA-ключа, сгенерированного выше. Теперь вернемся обратно на мой клиент и настроим ssh-agent. Перед тем, как запустить посредника, посмотрим некоторые переменные моего командного интерпретатора:

$ env | grep -i SSH
SSH_TTY=/dev/ttyp3
SSH_CLIENT=129.22.241.148 785 22
( Эти переменные определены только в том случае, если вы подсоединены к текущей машине при помощи ssh-клиента - Прим пер.)

Давайте запустим должным образом ssh-agent. Он запускает еще один командный процессор, так что вы должны указать, какой процессор запускать, чтобы агент мог верно его настроить.

$ ssh-agent /bin/bash

Вот теперь мое окружение определено как надо:

$ env | grep -i SSH
SSH_TTY=/dev/ttyp3
SSH_AGENT_PID=3012
SSH_AUTH_SOCK=/tmp/ssh-jose/ssh-3011-agent
SSH_CLIENT=129.22.241.148 785 22

Появились две новых переменных - SSH_AGENT_PID и SSH_AUTH_SOCK, которые позволят посреднику и вспомогательным программам (а именно: клиенту ssh, утилите загрузки кэша ssh-add, и т.п.). Сокеты - это просто обычные файлы в каталоге /tmp (не совсем так: сокеты - это отдельный специальный тип файлов в *NIX системах - Прим.пер):

$ ls -l /tmp/ssh-jose/

total 0
srwx------   1 jose     users           0 Apr 24 13:36 ssh-3012-agent

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

$ ssh-add1
Need passphrase for /home/jose/.ssh/identity (jose@biocserver).
Enter passphrase:
(Здесь нужно ввести парольную фразу. Она отображаться не будет)
Identity added: /home/jose/.ssh/identity (jose@biocserver)

Парольная фраза здесь необходима, что бы сказать: "да, это я и уменя есть право использовать этот ключ", и это так же парольная фраза, которую вы указывали после запуска утилиты ssh-keygen. Теперь ключ загружен, посмотрим, что в кэше при помощи параметра -l (сокращение 'list' [список]) ssh-add:

$ ssh-add -l
1024 37
1137558865696328451571189354697621649150131484876212929871995861553162729709874182866289762398712097874
7144865157469714395736112700558601876305400606604871996923286317135102021232606807975642627653113389875
3252147573933486285331381036388807156594523912524820998135476426250025089371381810113154118003306125324
01318392577
jose@biocserver

Теперь, когда вы будете подсоединяться к другому хосту при помощи ssh, вас не спросят про пароль. Личный ключ будет использован как идентификатор при помощи ssh-agent!

$ ssh -l jon2 li
Last login: Tue Apr 24 14:53:39 2001 from biocserver.bioc.
You have mail.
bash-2.03$

"Смотри, ма, и пароля не надо!!!"

Заметим, что можно изменить некоторые пункты в вышеописанном процессе и, в результате, несколько увеличить гибкость системы. Например, можно использовать вывод программы ssh-agent (когда она запускается без параметров), что бы изменить текущий командный процессор и настроить сокет агента для работы:

$ eval `ssh-agent`
Agent pid 19353;

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

Второе, что вы можете сделать - это запустить ваши X'ы, например GNOME или KDE, как параметр посредника ssh-agent. В результате каждый клиент, запущенный на локальной машине, будет знать, как связаться с посредником, что позволит упростить регистрацию, когда ваши терминалы регистрируются в других системах.

Важное замечание

Перед тем, как закончить со всем этим, хочу сказать одну важную вещь: пусть ключ загружен в кэш и вы аутентифицировались для использования этого ключа. Это остается в памяти. Что же делать, если вам необходимо отойти от рабочей станции? Кто угодно будет иметь доступ к вашей машине, которая уже аутентифицирована при помощи RSA-ключей.

Потому стоит сказать, что можно выгрузить ключи при помощи параметра '-d' программы ssh-add, либы выгрузить вообще все ключи, указав параметр '-D':

$ ssh-add -D
All identities removed. // все ключи удалены.

Хорошо бы выполнять такую команду, когда идете погулять. Неплохо бы прикрутить эту фишку к какой-нибудь программке, которая срабатывает при непродолжительном вашем бездействии, или прикрутить к вашему хранителю экрана, а можно, вообще - к системе APM.
(Можно использовать и другие средства, например выполнять команду "vlock" - Прим.пер.)

Неверный способ

Запуск ssh-agent без параметров, что, вообще говоря, неверно, порождает шелл (командный интерпретатор), но не устанавливает верные переменные. Будет выведено на экран, что переменные определены, но это не так (Это связанно с наследованием окружения процессами. Не совсем корректная формулировка, но она правильно отражает суть - Прим.пер):

$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-jose/ssh-3019-agent; export SSH_AUTH_SOCK;
SSH_AGENT_PID=3020; export SSH_AGENT_PID;
echo Agent pid 3020;

Посмотрим, определены ли переменные окружения в нашем шелле. Но эти переменные необходимы, чтобы посредник работал должным образом, как мы видели выше:

$ env | grep -i ssh
SSH_TTY=/dev/ttyp3
SSH_CLIENT=129.22.241.148 785 22

Последствия этого очевидны, когда вы попробуете добавить ключи в кэш:

$ ssh-add
Need passphrase for /home/jose/.ssh/identity (jose@biocserver).
Enter passphrase:
(Здесь нужно ввести парольную фразу. Она отображаться не будет)
Could not open a connection to your authentication agent.

Как видите, программа не может найти сокет или процесс, которые указанны в переменных. А потому, ключи в кэш не добавлены.

Заключение

Это было элементарное введение в использование ssh-agent для высоконадежной аутентификации. Вам нужно будет экспериментировать, если вы хотите знать больше, например о добавлении дополнительных ключей. И прочитайте замечательную документацию с пакетом OpenSSH. Книга О'Рейли для ленивых людей, под названием "SSH: Secure Shell, The Definitive Guide" (SSH: Защищенный шелл, полное руководство), действительно великолепное издание о SSH, и я очень его рекомендую.

Предыдущие статьи о пакете ssh

Jose Nazario

Жозе (José) является докторантом на факультете биохимии университета Case Western Reserve в Кливлэнде, штат Огайо. Пользуется UNIX около 10 лет, а Линуксом, начиная с ядер версии 1.2.

 


Copyright © 2001, Jose Nazario.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 67 of Linux Gazette, June 2001

Вернуться на главную страницу