Аутентификация Git с помощью SSH ключей
Аутентификация SSH происходит с помощью асимметричного шифрования. В отличие от симметричного, в котором всё шифруется и расшифровывается одним и тем же ключом, ассиметричное устроено сложнее. В нем уже два ключа, и один из них можно показывать всем (private key и public key). Ассиметричное шифрование используется, например, в протоколах SSL/TLS для безопасной передачи данных по сети (вроде HTTPS для HTTP). Ниже видео с простым объяснением работы ассиметричного шифрования на английском языке.
Для аутентификации в Git используются два основных способа: с помощью логина и пароля HTTP и с помощью SSH ключей. Использование SSH ключей имеет ряд преимуществ. Они проще в эксплуатации и более безопасны.
Генерируем ключи
Чтобы сгенерировать пару SSH ключей нам понадобиться утилита ssh-keygen
. В Linux она идет в поставке с пакетом openssh, в Windows ставится при установке Git.
Git Bash
, идущий в поставке со стандартным пакетом установки Git.
|
|
На 3 строке ssh-keygen
запросит куда сохранить ключи. Здесь просто жмем (если только вы не генерируете ключи для нестандартного использования). На 4 и 5 строках можно ввести кодовое слово для доступа к закрытому (private) ключу. Советую это сделать для дополнительной безопасности (если вдруг у вас “уведут” ключи).
Все, ключи готовы. Как видим ssh-keygen
сохранил их в /home/zhanibek/.ssh/id_ed25519
(закрытый ключ) и /home/zhanibek/.ssh/id_ed25519.pub
(открытый ключ). Закрытый ключ нельзя никому передавать (храните его как зеницу ока), а открытый можно свободно распростанять (хоть на странице в инстаграм выкладывать 😉).
Добавляем открытый ключ на удаленном (remote) репозитории
Теперь нам нужно сообщить наш открытый ключ серверу, центральному репозиторию. Обычно это делается на странице настроек профиля. Мы, для примера, посмотрим как это делается в GitLab и GitHub.
Сначала скопируем открытый ключ,
❯ cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEgMoq+Ih17NXY5t+tzHs3sZPb4R7NfE/LfFB1Uqml87 zhanibek@arch-t580
Для удобства можно сразу скопировать ключ в буфер обмена воспользовавшись утилитами xsel, xclip или wl-copy (если Wayland):
❯ xsel -ib < ~/.ssh/id_ed25519.pub
… или …
❯ xclip -i < ~/.ssh/id_ed25519.pub
… или …
❯ wl-copy < ~/.ssh/id_ed25519.pub
GitHub
Settings
→ SSH and GPG keys
→ New SSH key
→ вставляем, ранее скопированный, открытый ключ в поле Key
→ Add SSH Key.
GitLab
Settings
→ SSH Keys
→ вставляем, ранее скопированный, открытый ключ в поле Key
→ Add key.
Клонируем репозиторий
Отлично, мы сгенерировали и добавили ключи. Теперь клонируем репозиторий с помощью SSH ссылки.
❯ git clone [email protected]:onetech/anthill/api/arm-api.git
Cloning into 'arm-api'...
###############################################################
# Welcome to forte.bank #
# All connections are monitored and recorded #
# Disconnect IMMEDIATELY if you are not an authorized user! #
###############################################################
Enter passphrase for key '/home/zhanibek/.ssh/id_ed25519':
remote: Enumerating objects: 101, done.
remote: Counting objects: 100% (101/101), done.
remote: Compressing objects: 100% (79/79), done.
remote: Total 7520 (delta 36), reused 21 (delta 4), pack-reused 7419
Receiving objects: 100% (7520/7520), 817.81 KiB | 3.35 MiB/s, done.
Resolving deltas: 100% (3207/3207), done.
На строке 9 git
запрашивает кодовое слово, которое вы задавали при генерации ключей. Если git
запрашивает ввод кодового слова при каждой команде, взаимодействующей с удаленным репозиторием (git clone
, git fetch
, git push
, …), значит у вас в системе не установлен и/или не запущен сервис ssh-agent
.
Для существующих репозиториев (если вы до этого клонировали репозиторий с помощью HTTPS адреса, а не SSH) можно поменять URL удаленного репозитория:
❯ git remote set-url origin [email protected]:onetech/anthill/api/arm-api.git
ssh-agent
ssh-agent – программа для хранения (кэширования) закрытых ключей на время работы. Другими словами вы расшифровываете закрытый ключ кодовым словом, добавляете его в агент, и пока агент запущен вам не нужно расшифровывать ключ (вводить кодовое слово).
Добавить ключ можно командой:
❯ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/zhanibek/.ssh/id_ed25519:
Identity added: /home/zhanibek/.ssh/id_ed25519 (zhanibek@arch-t580)
Если в ответ вы получили сообщение “Could not open a connection to your authentication agent.
”, значит агент не запущен.
Запустить агент можно командой:
❯ eval "$(ssh-agent)"
Agent pid 501070
… и снова попробовать ssh-add
.
Чтобы агент запускался при старте системы добавьте в файл ~/.bashrc:
if ! pgrep -u "$USER" ssh-agent > /dev/null; then
ssh-agent -t 1h > "$XDG_RUNTIME_DIR/ssh-agent.env"
fi
if [[ ! "$SSH_AUTH_SOCK" ]]; then
source "$XDG_RUNTIME_DIR/ssh-agent.env" >/dev/null
fi
Теперь после добавления ключа в агент вам не нужно будет вводить кодовое слово (passphrase).
Автоматическое добавление ключа в агент
SSH можно настроить так, чтобы при первой попытке авторизации ключом, SSH клиенты, включая git, автоматически добавляли ключ в агент. Таким образом, вам не нужно вручную добавлять ключ командой ssh-add
, а при первом git pull
, команда запросит кодовое слово и сама добавит ключ в агент. Все последующие команды не будут требовать ввода кодового слова.
Для этого добавьте в файл ~/.ssh/config
строку AddKeysToAgent yes
:
AddKeysToAgent yes
Отлично, теперь работать с Git стало гораздо проще и безопаснее 😉
Для тех, кому не нужна безопасность
Если вы, по каким-то причинам, не хотитене можете использовать SSH, можно сделать HTTPS аутентификацию немного удобнее.
Чтобы не вводить каждый раз логин и пароль включите в настройках Git хранилище учетных данных:
git config --global credential.helper cache
Хранилище запоминает логин и пароль в оперативной памяти на некоторое время, по умолчанию 15 минут. Кроме cache есть варианты:
cache
– хранит учетные данные в памяти на определенное время, можно настроить (предпочтительно для Linux)store
– хранит учетные данные в файле в открытом ввиде, не истекает (не безопасно)osxkeychain
– хранит учетные данные в системном keychain (предпочтительно для macOS
… но лучше используйте SSH аутентификацию ☝.