Как эффективно работать с несколькими SSH-ключами

Перевод статьи «How to Manage Multiple SSH Keys».

Можно смело утверждать, что большинство разработчиков рано или поздно знакомятся с SSH. Это один из самых используемых протоколов для безопасного обмена данными. Вы можете использовать SSH для подключения к удаленным серверам, в том числе для управления кодом при помощи Git и синхронизации с удаленными репозиториями.

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

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

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

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

Пристегните ремни и полетели!

Работа с одним SSH-ключом

Для начала, давайте рассмотрим, как может выглядеть работа с SSH до того, как у вас появляется несколько ключей.

У вас есть один закрытый ключ, хранящийся в файле ~/.ssh/id_rsa, и соответствующий открытый ключ в файле ~/.ssh/id_rsa.pub.

Давайте представим, что вы хотите отправлять изменения в коде на удаленный Git-сервер, допустим, на GitHub (почему бы и нет). Для этого вам нужно сначала добавить на GitHub ваш открытый ключ. Я не буду останавливаться на этом шаге, найти информацию по этой теме довольно легко.

Предположим, что вас зовут Стив (англ. Steve) и вы работаете над очень секретным проектом с использованием Raspberry Pies для прослушивания сетевого трафика.

Чтобы начать работу, вам нужно клонировать git-репозиторий, используя SSH:

git clone git@github.com:steve/raspberry-spy.git

На этом этапе GitHub «думает»: «О, приватный репозиторий! Нам нужно зашифровать трафик при помощи имеющегося у меня открытого ключа и вашего закрытого ключа».

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

Не имея ни малейшего представления, какой закрытый ключ должен использоваться при SSH-соединении с git@github.com, SSH-клиент пытается найти ключ в стандартном месте — ~/.ssh/id_rsa (это лучшее, что он может предположить). Если по этому адресу не будет соответствующего файла, вы получите ошибку:

Cloning into 'raspberry-spy'…
Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.

Если у вас все же хранится какой-то ключ в ~/.ssh/id_rsa, SSH-клиент использует этот закрытый ключ для шифрования соединения. Если ключ защищен паролем (как это и должно быть), вам будет предложено ввести этот пароль:

Enter passphrase for key '/Users/steve/.ssh/id_rsa':

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

Но что, если вы дали своему файлу с закрытым ключом нестандартное имя (например, ~/.ssh/_id_rsa)? SSH-клиент не сможет определить, где хранится закрытый ключ. Вы получите ту же самую ошибку Permission denied …, что и раньше.

Если вы хотите использовать закрытый ключ с нестандартным именем, его нужно добавить вручную:

ssh-add ~/.ssh/_id_rsa

После ввода пароля вы при помощи команды ssh-add -l сможете проверить, добавился ли ключ в ssh-agent (SSH -клиент). Эта команда выведет все ключи, доступные на данный момент SSH-клиенту.

Если вы теперь попробуете клонировать репозиторий, вы сможете это сделать.

Пока все хорошо, не так ли?

Внимательный читатель мог заметить несколько потенциальных проблем.

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

Можно ли автоматизировать добавление ключей или как-то указать, какие ключи для каких серверов использовать?

Можно ли каким-то образом сохранить пароли, чтобы не вводить их каждый раз? Если бы только существовало что-то вроде keychain («связка ключей») для хранения SSH-ключей, защищенных паролями!

Можете быть спокойны: на все эти вопросы есть ответы.

Знакомьтесь: SSH config

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

Создайте новый файл ~/.ssh/config и откройте его для редактирования.

Управление SSH-ключами с нестандартными именами

Первое, что мы хотим сделать при помощи файла config, это избавиться от необходимости постоянно добавлять SSH-ключи с нестандартными именами при помощи ssh-add.

Предположим, ваш ключ имеет имя ~/.ssh/_id_rsa. В файл config нужно добавить следующие строки:

Host github.com
   HostName github.com
   User git
   IdentityFile ~/.ssh/_id_rsa
   IdentitiesOnly yes

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

Если вы попробуете клонировать ваш GitHub-репозиторий сейчас, все будет происходить так же, как если бы мы добавили ключ вручную (как мы делали раньше). Вам будет предложено ввести пароль:

git clone git@github.com:steve/raspberry-spy.git
Cloning into 'raspberry-spy'…
Enter passphrase for key '/Users/steve/.ssh/_id_rsa':

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

Примечание: если после успешного клонирования вы попытаетесь выполнить git pull, вам опять предложат ввести пароль. С этим мы разберемся дальше.

Важно, чтобы значение Host (github.com) в файле config и адрес в URI git@github.com:steve/raspberry-spy.git совпадали. Вы также можете изменить значение Host в конфигурационном файле на mygithub и клонировать репозиторий, используя URI git@mygithub:steve/raspberry-spy.git.

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

Host bitbucket-corporate
         HostName bitbucket.org
         User git
         IdentityFile ~/.ssh/id_rsa_corp
         IdentitiesOnly yes

Теперь вы можете использовать git clone git@bitbucket-corporate:company/project.git

Host bitbucket-personal
         HostName bitbucket.org
         User git
         IdentityFile ~/.ssh/id_rsa_personal
         IdentitiesOnly yes

Теперь вы можете использовать git clone git@bitbucket-personal:steve/other-pi-project.git

Host myserver
         HostName ssh.steve.com
         Port 1111
         IdentityFile ~/.ssh/id_rsa_personal
         IdentitiesOnly yes
         User steve
         IdentitiesOnly yes

А сейчас вы можете подключаться по SSH к собственному серверу, используя ssh myserver. Круто? Больше не нужно каждый раз, запуская ssh, вручную вводить номер порта и имя пользователя.

Бонус: настройки для каждого отдельного репозитория

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

Можно прописать специальную SSH-команду, задав ее в качестве значения sshCommand под core в <project>/.git/config. Например:

[core]
         sshCommand = ssh -i ~/.ssh/id_rsa_corp

Это возможно для git 2.10 или более новых версий. Чтобы избежать редактирования файла вручную, можно воспользоваться следующей командой:

git config core.sshCommand 'ssh -i ~/.ssh/id_rsa_corp'

Управление паролями

Последняя часть головоломки — управление паролями. Нам хотелось бы избежать введения пароля при каждой инициации SSH-соединения. Для этого мы можем использовать специальное программное обеспечение для управления связками ключей. Оно поставляется в MacOS и различных дистрибутивах Linux.

Начните с добавления вашего ключа в связку (keychain). Для этого к команде ssh-add нужно добавить опцию -K:

ssh-add -K ~/.ssh/id_rsa_whatever

Теперь вы можете видеть ваш SSH-ключ в связке. На MacOS это выглядит примерно так:

Если вы удалите ключи из ssh-agent при помощи команды ssh-add -D (как я уже говорил, это также происходит при перезагрузке компьютера) и попытаетесь установить SSH-соединение, вам будет предложено ввести пароль. Почему? Мы только что добавили ключ в связку. Если вы снова проверите Keychain Access, вы заметите, что добавленный при помощи команды ssh-add -K ключ по-прежнему находится в связке. Странно, правда?

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

Host *
   AddKeysToAgent yes
   UseKeychain yes

Теперь SSH будет искать ключ в связке, и если найдет, то вам не нужно будет вводить пароль. Ключ также будет добавлен в ssh-agent.

Для MacOS это будет работать в версии MacOS Sierra 10.12.2 и в более поздних версиях. Для Linux можно использовать что-то вроде gnome-keyring и это может сработать даже без последней модификации SSH-конфига. Что касается Windows — кто знает?..

Надеюсь, эта статья будет вам полезной. А теперь — вперед, приступайте к работе над SSH-конфигом!

[customscript]techrocks_custom_after_post_html[/customscript]

[customscript]techrocks_custom_script[/customscript]

1 комментарий к “Как эффективно работать с несколькими SSH-ключами”

  1. Николай М

    Хорошая статья. Еще нужно помнить, что для файла ~/.ssh/config нужно задать права 600, иначе магии не случится.

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх