Как эффективно работать с несколькими SSH-ключами
Как эффективно работать с несколькими SSH-ключами
Перевод статьи «How to Manage Multiple SSH Keys».
Можно смело утверждать, что большинство разработчиков рано или поздно знакомятся с SSH. Это один из самых используемых протоколов для безопасного обмена данными. Вы можете использовать SSH для подключения к удаленным серверам, в том числе для управления кодом при помощи Git и синхронизации с удаленными репозиториями.
Несмотря на то, что хорошей практикой считается иметь одну пару ключей (закрытый и открытый) для каждого устройства, иногда возникает потребность использовать несколько ключей. Также эти ключи могут иметь необычные имена.
Например, вы можете использовать одну пару SSH-ключей для работы над внутренними проектами вашей компании, но при этом пользоваться другими ключами для доступа к серверам корпоративных клиентов. Вы можете даже завести отдельную пару ключей для доступа к вашему собственному (частному) серверу.
С того момента как у вас возникает потребность добавить второй ключ, управление ключами может стать обременительным делом. Надеюсь, эта статья поможет всем, у кого возникают проблемы с SSH-ключами.
Я буду исходить из того, что мои читатели уже имеют базовые знания Git и SSH. В большинстве примеров в этой статье мы будем использовать Git, но, разумеется, все сказанное будет касаться и любых других SSH-коммуникаций. Впрочем, кое-какие приемы работы, специфические для Git, я тоже упомяну.
Пристегните ремни и полетели!
Работа с одним SSH-ключом
Для начала, давайте рассмотрим, как может выглядеть работа с SSH до того, как у вас появляется несколько ключей.
У вас есть один закрытый ключ, хранящийся в файле
/.ssh/id_rsa, и соответствующий открытый ключ в файле
Давайте представим, что вы хотите отправлять изменения в коде на удаленный Git-сервер, допустим, на GitHub (почему бы и нет). Для этого вам нужно сначала добавить на GitHub ваш открытый ключ. Я не буду останавливаться на этом шаге, найти информацию по этой теме довольно легко.
Предположим, что вас зовут Стив (англ. Steve) и вы работаете над очень секретным проектом с использованием Raspberry Pies для прослушивания сетевого трафика.
Чтобы начать работу, вам нужно клонировать git-репозиторий, используя SSH:
На этом этапе GitHub «думает»: «О, приватный репозиторий! Нам нужно зашифровать трафик при помощи имеющегося у меня открытого ключа и вашего закрытого ключа».
Открытый ключ вы добавили в свой профайл на GitHub, но SSH должен как-то понять, где находится соответствующий закрытый ключ.
Не имея ни малейшего представления, какой закрытый ключ должен использоваться при SSH-соединении с git@github.com, SSH-клиент пытается найти ключ в стандартном месте —
/.ssh/id_rsa (это лучшее, что он может предположить). Если по этому адресу не будет соответствующего файла, вы получите ошибку:
Если у вас все же хранится какой-то ключ в
/.ssh/id_rsa, SSH-клиент использует этот закрытый ключ для шифрования соединения. Если ключ защищен паролем (как это и должно быть), вам будет предложено ввести этот пароль:
Если вы введете правильный пароль и если выбранный SSH-клиентом ключ составляет пару с открытым ключом в вашем профайле, все пройдет хорошо и репозиторий будет успешно клонирован.
Но что, если вы дали своему файлу с закрытым ключом нестандартное имя (например,
/.ssh/_id_rsa)? SSH-клиент не сможет определить, где хранится закрытый ключ. Вы получите ту же самую ошибку Permission denied …, что и раньше.
Если вы хотите использовать закрытый ключ с нестандартным именем, его нужно добавить вручную:
После ввода пароля вы при помощи команды 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 нужно добавить следующие строки:
Выполните команду ssh-add -D, чтобы убедиться, что вашего файла
/.ssh/_id_rsa нет в ssh-agent. Эта команда удалит все ключи из текущей сессии ssh-agent. Сессия сбрасывается при каждом вашем выходе из системы или перезагрузке компьютера (или когда вы вручную убиваете процесс ssh-agent). При помощи команды ssh-add -D мы можем смоделировать перезагрузку.
Если вы попробуете клонировать ваш GitHub-репозиторий сейчас, все будет происходить так же, как если бы мы добавили ключ вручную (как мы делали раньше). Вам будет предложено ввести пароль:
Обратите внимание, что ключ, пароль от которого у нас спрашивают, это именно тот ключ, который мы указали в файле 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-ключами решены. Вот несколько полезных примеров конфигурации:
Теперь вы можете использовать git clone git@bitbucket-corporate:company/project.git
Теперь вы можете использовать git clone git@bitbucket-personal:steve/other-pi-project.git
А сейчас вы можете подключаться по SSH к собственному серверу, используя ssh myserver. Круто? Больше не нужно каждый раз, запуская ssh, вручную вводить номер порта и имя пользователя.
Бонус: настройки для каждого отдельного репозитория
Вы также можете указать, какой именно ключ нужно использовать для каждого репозитория, переопределив значения в конфигурации SSH.
Можно прописать специальную SSH-команду, задав ее в качестве значения sshCommand под core в <project>/.git/config. Например:
Это возможно для git 2.10 или более новых версий. Чтобы избежать редактирования файла вручную, можно воспользоваться следующей командой:
Управление паролями
Последняя часть головоломки — управление паролями. Нам хотелось бы избежать введения пароля при каждой инициации SSH-соединения. Для этого мы можем использовать специальное программное обеспечение для управления связками ключей. Оно поставляется в MacOS и различных дистрибутивах Linux.
Начните с добавления вашего ключа в связку (keychain). Для этого к команде ssh-add нужно добавить опцию -K:
Теперь вы можете видеть ваш SSH-ключ в связке. На MacOS это выглядит примерно так:
Если вы удалите ключи из ssh-agent при помощи команды ssh-add -D (как я уже говорил, это также происходит при перезагрузке компьютера) и попытаетесь установить SSH-соединение, вам будет предложено ввести пароль. Почему? Мы только что добавили ключ в связку. Если вы снова проверите Keychain Access, вы заметите, что добавленный при помощи команды ssh-add -K ключ по-прежнему находится в связке. Странно, правда?
Оказывается, нужно сделать еще один шаг. Откройте ваш конфигурационный файл SSH и добавьте в него следующие строки:
Теперь SSH будет искать ключ в связке, и если найдет, то вам не нужно будет вводить пароль. Ключ также будет добавлен в ssh-agent.
Для MacOS это будет работать в версии MacOS Sierra 10.12.2 и в более поздних версиях. Для Linux можно использовать что-то вроде gnome-keyring и это может сработать даже без последней модификации SSH-конфига. Что касается Windows — кто знает.
Надеюсь, эта статья будет вам полезной. А теперь — вперед, приступайте к работе над SSH-конфигом!
Установка модуля OpenSSH для PowerShell
- Войдите на компьютер Windows с учетной записью уровня администратора и запустите PowerShell с правами администратора.
- Чтобы установить модуль OpenSSH, введите следующий командлет. Если вы впервые устанавливаете модуль на устройство, вам может быть предложено загрузить и установить некоторые дополнительные инструменты. Введите «Y», чтобы разрешить установку инструментов.
- Модуль установки — Force OpenSSHUtils
- Затем введите командлет, чтобы запустить службу ssh-agent для безопасного хранения сгенерированных частным образом ключей SSH.
- Запуск службы ssh-agent
- Наконец, введите командлет, чтобы запустить службу sshd, которая автоматически генерирует первую пару ключей хоста.
- Запуск службы sshd
Как добавить SSH ключ на сервер
Если вы уже создали облачный сервер, то добавить SSH-ключ можно только на самом сервере, через подключение по SSH.
Чтобы добавить созданный SSH-ключ на существующий сервер, выберите операционную систему, которая установлена на вашем компьютере, и следуйте инструкции:
- 1.
- в Unity (Ubuntu): «Главное меню» — в поисковой строке введите слово «Терминал», либо просто нажмите комбинацию клавиш: Ctrl+Alt+T;
- в Xfce (Xubuntu): «Главное меню» — «Приложения» — «Система» — «Терминал»;
- в KDE (Kubuntu): «Главное меню» — «Приложения» — «Система» — «Терминал».
Введите команду: ssh-copy-id root@123.123.123.123 ,
где root — логин вашего сервера,
123.123.123.123 — IP-адрес сервера. Его можно узнать в информационном письме, которое было отправлено вам после создания сервера.
Нажмите Enter и введите пароль от вашего сервера.
После успешного подключения ваш ключ будет добавлен на сервер и вы сможете подключаться к серверу без обязательного ввода пароля.
Все действия нужно выполнять на сервере через подключение по SSH с помощью SSH-клиента PuTTY.
- 1.
Создайте файл с вашим публичным ключом при помощи команды echo your_public_key authorized_keys .
Добавьте ваш приватный ключ в PuTTY:
- 1.
Введите команду: ssh-copy-id user@123.123.123.123 ,
- user — имя пользователя;
- 123.123.123.123 — IP-адрес сервера. Его можно узнать в информационном письме, которое было отправлено вам после создания сервера.
Нажмите Enter и введите пароль от вашего сервера. После успешного подключения ваш ключ будет добавлен на сервер и вы сможете подключаться к серверу без обязательного ввода пароля.
После добавления SSH-ключа вы можете подключиться к вашему серверу по SSH без ввода пароля.
Шаг 2. Скопировать открытый ключ на удаленный хост
Как всегда в unix есть множество вариантов для этого.
Долгий путь
В macOS можно скопировать содержимое файла в буфер обмена с помощью pbcopy
Подключаемся к удаленному серверу, переходим в директорию .ssh и открываем (или создаем) файл authorized_keys.
Добавляем ключ из буфера обмена.
Кстати каждый ключ должен быть на отдельной строке. И никаких пустых строк между ключами.
ssh-copy-id
Начиная с Sierra утилита уже есть в составе системы и не нужно ставить с github или через homebrew.
или с указанием имени ключа
cat + ssh
Монтирование по ssh
Использование ssh не заканчивается выполнением команд на удаленном сервере. На основе протокола ssh базируются другие программы. Например sshfs — программа монтирования удаленной файловой системы с помощью ssh.
Создадим на сервере в домашней директории root тестовый файл:
Далее надо установить программу sshfs на клиенте:
Создадим тестовую директорию:
А теперь примонтируем домашнюю директорию root с сервера в нашу тестовую директорию на клиенте:
Монтирование по ssh
Чтобы размонтировать воспользуйтесь командой umount:
Установите модуль OpenSSH (для PowerShell)
1. Войдите на компьютер Windows с учетной записью уровня администратора и запустите PowerShell с правами администратора.
2. Введите следующий командлет для установки модуля OpenSSH. Если это первый раз, когда модуль был устанавливается на устройстве, вам может быть предложено загрузить и установить некоторые дополнительные инструменты. Введите «Y», чтобы разрешить установку инструментов.
Install-Module -Force OpenSSHUtils
3. Затем введите командлет, чтобы запустить службу ssh-agent для безопасного хранения сгенерированных частным образом ключей SSH.
4. Наконец, введите командлет, чтобы запустить службу sshd, которая автоматически сгенерирует первую пару ключей хоста.
Примечание. По умолчанию приложение OpenSSH Server не установлено, поэтому сначала его необходимо установить. Кроме того, служба ssh-agent имеет значение Disabled и должна быть изменена до того, как сработают указанные выше командлеты. Ключи хоста хранятся в каталоге: % HOMEDRIVE% ProgramData ssh.
Вход на серверную машину с помощью SSH без пароля
Теперь открытый ключ существует как на клиентских, так и на серверных машинах. Когда клиентский компьютер отправляет запрос на соединение серверу с помощью команды ssh, сервер сопоставляет открытый ключ клиента с открытым ключом сервера. Если совпадения найдены, то соединение будет установлено от клиента к серверу. Вы можете подключиться к серверу или удаленному хосту, используя имя хоста или IP-адрес. Локальный сервер использовал это руководство, чтобы показать использование авторизованных ключей для установления SSH-соединения с клиентского компьютера на серверный. Одна учетная запись использовалась как серверная машина, на которой установлен сервер OpenSSH, а другая учетная запись использовалась здесь как клиентская машина. Выполните следующую команду на клиентском компьютере, чтобы установить соединение с сервером.
Следующий вывод появится после выполнения указанной выше команды. Выходные данные показывают, что имя пользователя клиентской машины — «yesmin». Имя пользователя серверной машины — fahmida. SSH-соединение установлено правильно, поскольку имя пользователя изменилось на «fahmida» с «yesmin». Теперь можно легко получить доступ к содержимому серверной машины. Если пользователь сейчас выполняет какую-либо команду, вывод будет сгенерирован на основе сервера.