by Brian Hatch
Перевод: Сгибнев Михаил
Никто не любит вводить пароли. Если бы компьютеры, как люди, четко представляли
себе, кто они такие и к чему они могут получить доступ, а к чему нет и не заставляли бы
каждый раз напрягать клавиатуру...
В моей последней
статье я показал Вам, как создать SSH Identities/Pubkeys,
который может использоваться как альтернатива вводу пароля.
Однако, поскольку мы используем кодовую фразу для защиты, то получается, что мы просто поменяли один
пароль на другой.
Сейчас мы разберем следующую ситуацию: мы возьмем доверительные отношения между хостами, данные нам
Identity/Pubkey и для управления ключами будем использовать ssh-agent.
Запуск ssh-agent
Для запуска ssh-agent необходимо просто дать команду:
$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-OqdW7921/agent.7921; export SSH_AUTH_SOCK;
SSH_AGENT_PID=7922; export SSH_AGENT_PID;
echo Agent pid 7922;
При запуске агента он выведет на консоль некоторую информацию, которую Вы можете
использовать для установки переменных среды. В настоящем примере используется синтаксис
Bourne shell. Если Вы используете C-shell, такой как /bin/csh или /bin/tcsh, то
переменные отобразились бы по другому. Если ssh-agent не может определить, какую оболочку Вы используете,
Вы можете использовать ключи -s или -c соответственно для Bourne shell/C-shell.
Программа /usr/bin/ssh использует переменную среды SSH_AUTH_SOCK, чтобы знать, как войти в контакт с запущеным Вами ssh-агентом.
Эту переменную необходимо определить. Самый простой способ сделать это - использовать функцию оболочки eval,
# Note: no ssh agent related variables yet
$ set | grep SSH_
# Run it inside backticks, which will capture the output and
# pass it to 'eval' which will run it in your current shell.
$ eval `ssh-agent`
Agent pid 7943
# And now those variables are in your shell, ready to use.
$ set | grep SSH_
SSH_AUTH_SOCK=/tmp/ssh-xoGi7942/agent.7942
SSH_AGENT_PID=7943
Если Вам известна переменная SSH_AGENT_PID, то Вы можете завершить работу агента с помощью команды ssh-agent -k,
хотя и команда kill по прежнему неплохо работает.
Загрузка ключей в агент
Сам по себе агент не очень полезен, пока в него не загружены ключи.
Все управление ключами происходит через команду ssh-add, если Вы запустите ее без аргументов,
то она загрузит "стандартные ключи" из $HOME/.ssh/identity, $HOME/.ssh/id_rsa и $HOME/.ssh/id_dsa.
Если Ваши ключи защищены кодовой фразой (по другому и быть не может!), то ее потребуется ввести
для декодирования ключей. Если кодовая фраза одинакова для всех ключей, то и ввести ее необходимо
только один раз.
Итак:
$ ps -fp $SSH_AGENT_PID
UID PID PPID C STIME TTY TIME CMD
lainee 7943 1 0 15:52 ? 00:00:00 ssh-agent
# Are there any keys in there currently?
# 'ssh-add -l' (list) will show us.
$ ssh-add -l
The agent has no identities.
# Let's import the default keys. In our case, we have
# each key protected with the same passphrase, which is
# why it only asks once.
$ ssh-add
Enter passphrase for /home/lainee/.ssh/id_rsa:
Identity added: /home/lainee/.ssh/id_rsa (/home/lainee/.ssh/id_rsa)
Identity added: /home/lainee/.ssh/id_dsa (/home/lainee/.ssh/id_dsa)
Identity added: /home/lainee/.ssh/identity (lainee@desktop)
# What's in our agent now?
$ ssh-add -l
1024 79:e9:6f:99:a3:2d:ae:f3:bd:3a:87:6c:ed:4e:bb:ad lainee@desktop (RSA1)
1024 23:d5:2b:20:02:a4:1a:c2:d0:d8:66:8f:a9:67:db:c0 id_dsa (DSA)
1024 e8:17:67:cf:9c:24:2b:59:ad:48:1d:e6:ea:d6:d9:3d id_rsa(RSA)
# And let's add a few one-off keys also
$ ssh-add ssh-keys/id*
Enter passphrase for id_dsa.webrooters:
Identity added: id_dsa.webrooters (id_dsa.webrooters)
Enter passphrase for identity.webrooters:
Identity added: identity.webrooters (webrooters@my_company.com)
# What's in our agent now?
$ ssh-add -l
1024 79:e9:6f:99:a3:2d:ae:f3:bd:3a:87:6c:ed:4e:bb:ad lainee@desktop (RSA1)
1024 23:d5:2b:20:02:a4:1a:a9:67:db:c0:c2:d0:d8:66:8f id_dsa (DSA)
1024 e8:17:67:cf:9c:24:2b:59:ad:48:1d:e6:ea:d6:d9:3d id_rsa(RSA)
1024 1a:c2:d0:d8:66:23:d5:2b:20:02:a4:8f:a9:67:db:c0 id_dsa.webrooters (DSA)
1024 ae:f3:bd:3a:87:79:e9:6f:99:4e:bb:ad:a3:2d:6c:ed webrooters@my_company.com (RSA1)
Итак, мы использовали ssh-add для добавления ключей по умолчанию, просмотра списка ключей и
задания выборочных ключей. Обратим взор к следующему параграфу:
Удаление ключей из агента
Вы можете использовать команду ssh-agent -d для удаления ключей:
# List keys
$ ssh-add -l
1024 79:e9:6f:99:a3:2d:ae:f3:bd:3a:87:6c:ed:4e:bb:ad lainee@desktop (RSA1)
1024 23:d5:2b:20:02:a4:1a:a9:67:db:c0:c2:d0:d8:66:8f id_dsa (DSA)
1024 e8:17:67:cf:9c:24:2b:59:ad:48:1d:e6:ea:d6:d9:3d id_rsa(RSA)
1024 1a:c2:d0:d8:66:23:d5:2b:20:02:a4:8f:a9:67:db:c0 id_dsa.webrooters (DSA)
1024 ae:f3:bd:3a:87:79:e9:6f:99:4e:bb:ad:a3:2d:6c:ed webrooters@my_company.com (RSA1)
# Remove the key that came from the file ~/.ssh/id_dsa.webrooters
# from the agent. (Does not remove the file from the directory.)
$ ssh-add -d ~/.ssh/id_dsa.webrooters
Identity removed: id_dsa.webrooters (id_dsa.webrooters.pub)
# List keys again
$ ssh-add -l
1024 79:e9:6f:99:a3:2d:ae:f3:bd:3a:87:6c:ed:4e:bb:ad lainee@desktop (RSA1)
1024 23:d5:2b:20:02:a4:1a:a9:67:db:c0:c2:d0:d8:66:8f id_dsa (DSA)
1024 e8:17:67:cf:9c:24:2b:59:ad:48:1d:e6:ea:d6:d9:3d id_rsa(RSA)
1024 ae:f3:bd:3a:87:79:e9:6f:99:4e:bb:ad:a3:2d:6c:ed webrooters@my_company.com (RSA1
Зачем удалять ключи из агента? Может быть несколько причин:
- Вы добавляете временный ключ, который будет действовать в течение блиайшего часа и хотите
удалить его после работы из-за приступа паранойи.
- Вы перешли на протокол SSHv2, и ваши ключи RSA1 больше не нужны.
- У вас в агенте содержится слишком много ключей и Вы удаляете наименее часто
используемые. Почему это может понадобиться - смотрите ниже.
Слишком много ключей?
Серверы SSH позволяют Вам подтверждать свою подлинность конечное число раз.
Каждая неудачная попытка увеличивает значение счетчика и при некотором критическом значении
числа ключей, Вас вообще может перестать пускать на сервер из-за превышения числа попыток авторизации.
Есть несколько способов решения данной проблемы:
Или Вы можете внести необходимые опции в ~/.ssh/options, а затем выполнить команду:
# Using the configuration file:
$ head ~/.ssh/config
Host myserver
# Allow SSHv1 Identity authentication?
RSAAuthentication no
# Allow SSHv2 Pubkey authentication?
PubkeyAuthentication no
$ ssh myserver
или
# Put it all on the command line.
# Or better yet, put it in a shell script or an alias...
$ ssh -o'RSAAuthentication=no' -o 'PubkeyAuthentication=no' user@myserver ...
Если Вы хотите использовать авторизацию по ключу, но он находится слишком далеко в списке и сервер SSH не пускает Вас,
то Вам не повезло. Если у кого-либо есть идеи относительно этой проблемы, то прошу поделиться.
Мероприятия по защите агента
ssh-agent создает unix domain socket и затем слушает все подключения от /usr/bin/ssh на этом сокете.
В принципе Ваши ключи могут оказаться доступны любому, кто подключится к этому сокету.
При запуске агента, создается временный каталог /tmp/, с установленными правами доступа (0700) и уже внутри него
создается сокет с правами (0600). Однако пользователь root по преженму имеет доступ к этому сокету, также он
может произвольным образом поменять права доступа к сокету.
root# set | grep SSH_
root# ssh-add -l
Cannot connect to your agent.
root# ls -l /tmp/ssh-*/*
srwx------ 1 lainee alandra 0 Jan 21 11:51 /tmp/ssh-OqdW7921/agent.7921
root# SSH_AUTH_SOCK=/tmp/ssh-OqdW7921/agent.7921
root# export SSH_AUTH_SOCK
root# ssh-add -l
1024 79:e9:6f:99:a3:2d:ae:f3:bd:3a:87:6c:ed:4e:bb:ad lainee@desktop (RSA1)
1024 23:d5:2b:20:02:a4:1a:a9:67:db:c0:c2:d0:d8:66:8f id_dsa (DSA)
1024 e8:17:67:cf:9c:24:2b:59:ad:48:1d:e6:ea:d6:d9:3d id_rsa(RSA)
1024 ae:f3:bd:3a:87:79:e9:6f:99:4e:bb:ad:a3:2d:6c:ed webrooters@my_company.com (RSA1)
Это плохая новость. Хорошая новость состоит в том, что ключи пригодны для использования только при запущеном агенте,
root мог бы использовать агент для авторизации на других системах, но нельзя получить доступ к ключам непосредственно.
Это значит, что нельзя вот так просто взять ключи и использовать их на другой машине.
Можем ли мы воспрепятствовать root получить доступ к нашему агенту, даже с учетом того, что он не обращает внимания на
права доступа? Да, можем, если будем использовать опцию -c при импорте ключей в агента. В этом случае будет
сделан запрос на подтверждение при каждой попытке авторизации на сервере с помощью программы ssh-askpass.
Эта программа выскочит на вашем X11 рабочем столе и будет просить о подтверждении каждый раз перед использованием ключа.
Примерно в этой точке Вы должны понять, что мы заведомо проиграли.
root может обратиться к Вашему X11 рабочему столу и вообще ко всем Вашим процессам.
Если Вы не доверяете root, то аше положение не завидно.
Перенаправление агента
Одна из хороших особенностей агента заключается в том, что он может следовать за Вами с машины на машину.
Значение по умолчанию в более новых версиях OpenSSH должно отключить форвардинг агента по умолчанию, так что
Вы должны сами для себя решить, хотите ли Вы этого или нет.
Как фактически работает форвардинг пакетов?
Короче говоря, агент выполняется на одной машине, и каждый раз Вы, соединяясь с
SSH сервером с форвардингом агента, сервер создает 'туннель' назад
через SSH подключение с агентом, так что он становится доступен для любых дальнейших SSH подключений.
Скажем, мы находимся на нашем рабочем столе, мы соединяемся по SSH с сервером управления с
возможностью форвардинга агента, и с сервера управления идем по SSH на наш почтовый сервер. Что получается:
-
/usr/bin/ssh с Вашей машины соединяется с сервером управления, аутентифицируется и запрашивает форвардинг агента.
-
/usr/sbin/sshd на сервере управления открывает сокет /tmp/ssh-XXXXXXX/agent.##### и устанавливает переменную
SSH_AUTH_SOCK
-
Стартует демон SSH и вы начинаете работу в шелле на сервере управления.
-
Когда Вы решаете соединиться по SSH к почтовому серверу, программа/usr/bin/ssh (на сервере управления)
видит переменную среды SSH_AUTH_SOCK и соединяется с локальным сокетом.
-
SSH демон, который является другим концом сокета /tmp/ssh-XXXXXXX/agent.#####, просто перегоняет данные
от/usr/bin/ssh на сервере управления к и от ssh-agent, выполняющегося на вашем рабочем столе.
Все операции с ключами выполняются на агенте, который выполняется на Вашем рабочем столе.
-
Агент аутентифицируется на сервере.
Используя форвардинг агента Вы сохраните время и клавиатуру.
Также обратите внимание, что, так как ваш агент доступен любой машине, с которой Вы соединяетесь. Соответственно
и пользователю root этой машины. Будьте бдительны!
Глобальное отключение перенаправления
Если у Вас нет серьезных причин разрешать перенаправление, то проверьте соответствующий параметр в
глобальном файле конфигурации ssh_config, который обычно расположен в /etc/ или /etc/ssh/ . Должно быть:
Host *
ForwardAgent no
Перенаправление агента из командной строки
Для перенаправлении агента из командной строки, используйте опцию -A:
desktop$ ssh -A user@remotehost
Опция -a отключает форвардинг, что является значением по умолчанию.
Перенаправление агента из файла конфигурации
Если у Вас есть хост, на котором Вы всегда используете перенаправление и Вы не хотите постоянно использовать
флаг -A, то Вы можете сделать для этих хостов записи в ~/.ssh/config:
$ cat ~/.ssh/config
Host shellserver
ForwardAgent yes
Host management-server
ForwardAgent yes
Host *
ForwardAgent no
Хотя запись Host * должна иметься в глобальном файле конфигурации, я предпочитаю иметь ее и в локальном файле.
Прочие возможности
Есть еще несколько дополнительных флагов для ssh-add и ssh-agent:
ssh-add -L
Выведет не заголовок, а ключ полностью. Может быть полезным при обьединении их в одном файле ~/.ssh/authorized_keys
ssh-add -D
Удаляет ВСЕ ключи из агента
ssh-add -x
Блокирует агента до ввода пароля. Заблокированный агент не пригоден для использования.
Хороший способ обезопасить агента, когда Вы на ночь уходите с работы домой. Для разблокировки
используйте ssh-add -X.
ssh-add -t seconds filename
Указывает агенту отказываться от ключа после указанного периода времени. Хороший путь хранения временных ключей.
ssh-agent -t seconds
Определяет время жизни ключей после запуска агента.