Содержание

Аутентификация Git с помощью SSH ключей

Аутентификация SSH происходит с помощью асимметричного шифрования. В отличие от симметричного, в котором всё шифруется и расшифровывается одним и тем же ключом, ассиметричное устроено сложнее. В нем уже два ключа, и один из них можно показывать всем (private key и public key). Ассиметричное шифрование используется, например, в протоколах SSL/TLS для безопасной передачи данных по сети (вроде HTTPS для HTTP). Ниже видео с простым объяснением работы ассиметричного шифрования на английском языке.

Для аутентификации в Git используются два основных способа: с помощью логина и пароля HTTP и с помощью SSH ключей. Использование SSH ключей имеет ряд преимуществ. Они проще в эксплуатации и более безопасны.

Генерируем ключи

Чтобы сгенерировать пару SSH ключей нам понадобиться утилита ssh-keygen. В Linux она идет в поставке с пакетом openssh, в Windows ставится при установке Git.

Совет
Для пользователей Windows: настоятельно рекомендую использовать Git Bash, идущий в поставке со стандартным пакетом установки Git.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
❯ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/zhanibek/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/zhanibek/.ssh/id_ed25519
Your public key has been saved in /home/zhanibek/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:uT6SJIRk7gDV5LB5FntXAYA9Nu/yP93yqa0hSflhT3w zhanibek@arch-t580
The key's randomart image is:
+--[ED25519 256]--+
| .oooo....o.     |
|. o=oo=  .       |
|.+o.=..+.        |
|. oo.. ... . .   |
| o .   .S o o o E|
|  . . o .o + + . |
|     o +. o.o..  |
|      o.o ..oo.. |
|       ..o..o=+  |
+----[SHA256]-----+

На 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

SettingsSSH and GPG keysNew SSH key → вставляем, ранее скопированный, открытый ключ в поле KeyAdd SSH Key.

GitLab

SettingsSSH Keys → вставляем, ранее скопированный, открытый ключ в поле KeyAdd key.

Клонируем репозиторий

Отлично, мы сгенерировали и добавили ключи. Теперь клонируем репозиторий с помощью SSH ссылки.

/posts/git-auth-with-ssh-keys/image2020-12-30_17-12-31.png

❯ 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
Совет
У Microsoft есть кросс-платформенное приложение Git Credential Manager Core, которое облегчает и расширяет настройку хранилища

… но лучше используйте SSH аутентификацию ☝.