$ sudo teach IT
Модуль 5 · GitHub · Урок 5.3

SSH-ключ для GitHub

Вы создадите пару SSH-ключей, добавите открытый ключ на GitHub и переведёте репозиторий на вход без токенов и окон.

Теория + практика~25 минутНовичокSSHключи

Что такое SSH-ключ

SSH-ключ — это пара файлов, с помощью которой GitHub узнаёт ваш компьютер без пароля и токена. Чтобы настроить SSH-ключ для GitHub, нужно создать пару ключей командой ssh-keygen, добавить открытый ключ в настройки аккаунта (Settings, SSH and GPG keys), проверить соединение командой ssh -T git@github.com и переключить адрес репозитория на SSH-вариант.

Вход через браузер работает, но привязан к менеджеру учётных данных. SSH-ключ не требует ни окон, ни токенов: настроили один раз и забыли. Этот урок необязателен, но полезен: SSH встретится вам на любом сервере.

Устройство проще представить на примере замка и ключа. Вы создаёте два связанных файла:

  • открытый ключ (public key) — «замок». Его можно показывать кому угодно: вы вешаете этот замок на GitHub;
  • закрытый ключ (private key) — «ключ от замка». Он остаётся на вашем компьютере, и о нём никто не должен узнать.

Когда вы подключаетесь, GitHub проверяет, что у вас есть ключ, подходящий к повешенному замку. Сам закрытый ключ по сети не передаётся. Поэтому украсть доступ, подслушав соединение, нельзя. Аббревиатура SSH — Secure Shell («защищённая оболочка»), это протокол для защищённой работы с удалёнными машинами; Git умеет использовать его как канал.

Закрытый ключ никому не отдавать

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

Создаём ключ

Команда одинакова в Git Bash, Терминале macOS и терминале Linux. Вместо адреса в кавычках подставьте почту вашего аккаунта GitHub:

Терминал
$ ssh-keygen -t ed25519 -C "alex@example.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/alex/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/alex/.ssh/id_ed25519
Your public key has been saved in /Users/alex/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:6N+jeWhDeYZpvg+Wg4jAmFhjpD8ihg71DfagyjXYaFs alex@example.com
The key's randomart image is:
+--[ED25519 256]--+
|  .              |
| o               |
|. = +            |
|=*+= = .         |
|X*+E. + S+       |
|B++o.o .*.o      |
|.+. . o+=+       |
|       o==o      |
|       .=*o.     |
+----[SHA256]-----+

Разбор по строкам

  • ssh-keygen — программа, которая создаёт ключи (key generator).
  • -t ed25519 — тип ключа: Ed25519 — современный и короткий алгоритм. Если система его не поддерживает, документация GitHub предлагает ssh-keygen -t rsa -b 4096 -C "почта".
  • -C "alex@example.com" — комментарий. Он дописывается в ключ как подпись, чтобы потом понимать, чей он. Чаще всего это почта.
  • Enter file in which to save the key — где сохранить. Нажмите Enter: по умолчанию файлы лягут в папку .ssh в вашей домашней папке. В Git Bash на Windows путь выглядит как /c/Users/alex/.ssh/id_ed25519.
  • Enter passphrase — парольная фраза. Её спросят дважды (при вводе символы не отображаются). Это замок на самом закрытом ключе: даже если файл украдут, без фразы им не воспользоваться. Фразу лучше задать; пустая допустима, но менее безопасна.
  • id_ed25519 — закрытый ключ, id_ed25519.pub — открытый. Остальной вывод — отпечаток (fingerprint) и картинка, по которой ключ можно узнать глазами; запоминать их не нужно.

Числа и картинка у вас будут другие. Убедитесь, что файлы появились:

Терминал
$ ls ~/.ssh
id_ed25519  id_ed25519.pub

Если ключ у вас уже есть

Если в папке .ssh уже лежит файл с таким именем, ssh-keygen спросит, перезаписывать ли его. Откажитесь: перезапись уничтожит старый ключ, а он может быть нужен для другого сервера. Укажите для нового ключа другое имя файла.

Добавляем ключ на GitHub

На GitHub нужно отправить открытый ключ, то есть содержимое файла id_ed25519.pub. Скопировать его можно так (команды из документации GitHub):

СистемаКоманда
macOSpbcopy < ~/.ssh/id_ed25519.pub
Windows (Git Bash)clip < ~/.ssh/id_ed25519.pub
Linuxcat ~/.ssh/id_ed25519.pub, затем выделить вывод и скопировать

Команды для Mac и Windows ничего не печатают: они кладут текст в буфер обмена. Содержимое файла — одна строка, она начинается с ssh-ed25519 и заканчивается вашей почтой. Если вы видите -----BEGIN OPENSSH PRIVATE KEY-----, вы открыли закрытый ключ — остановитесь.

Теперь на GitHub:

  1. Нажмите на аватар в правом верхнем углу и выберите Settings.
  2. В боковом меню, в разделе Access, откройте SSH and GPG keys.
  3. Нажмите New SSH key.
  4. В поле Title («название») впишите, откуда ключ: например «Домашний ноутбук».
  5. Тип ключа оставьте для входа (в списке Key type это Authentication Key, «ключ для входа»).
  6. В поле Key вставьте скопированную строку и нажмите Add SSH key.
  7. Если GitHub попросит подтвердить доступ (пароль или код), подтвердите.

Проверка и переключение на SSH

Проверим, что GitHub узнаёт ключ. Команда ничего не меняет, только знакомится с сервером:

Терминал
$ ssh -T git@github.com
The authenticity of host 'github.com (IP ADDRESS)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
Are you sure you want to continue connecting (yes/no)?

Разбор по строкам

  • ssh -T git@github.com — подключиться к серверу github.com под пользователем git. Пользователь всегда git, а не ваш логин: GitHub узнаёт вас по ключу. Флаг -T отключает интерактивный терминал: GitHub не даёт управлять сервером, нужна лишь проверка.
  • The authenticity of host ... can't be established — «подлинность сервера не подтверждена»: компьютер видит этот сервер впервые.
  • ED25519 key fingerprint is SHA256:... — «отпечаток» сервера. Сверьте его с отпечатком, опубликованным GitHub: он указан на странице отпечатки SSH-ключей GitHub. Должно совпасть до последнего символа.
  • Are you sure you want to continue connecting — «продолжить?». Если отпечаток совпал, напечатайте yes и Enter. Если нет, ответьте no и не продолжайте: возможно, вы подключаетесь не к настоящему GitHub.

После yes вы увидите успех (если нужно, введите парольную фразу):

Вывод
Hi alex-ivanov! You've successfully authenticated, but GitHub does not provide shell access.

«Привет, alex-ivanov! Вы успешно вошли, но GitHub не даёт доступа к консоли». Это и есть победа, хотя звучит как отказ. Команда при этом завершается с кодом 1, и это нормально. Главное, что в приветствии ваш логин.

Переключаем репозиторий на SSH

Репозиторий пока ходит на GitHub по HTTPS-адресу. Заменим адрес на SSH-вариант:

Терминал
$ git remote set-url origin git@github.com:alex-ivanov/portfolio.git
$ git remote -v
origin  git@github.com:alex-ivanov/portfolio.git (fetch)
origin  git@github.com:alex-ivanov/portfolio.git (push)
$ git push
Everything up-to-date

Разбор по строкам

  • git remote set-url origin <новый адрес> — заменить адрес у имени origin. История и связь main с origin/main не пострадают.
  • git@github.com:alex-ivanov/portfolio.git — SSH-адрес: пользователь git, затем @, сервер github.com, двоеточие и логин/репозиторий.git.
  • Everything up-to-date — отправлять нечего: всё уже на GitHub. Вход по ключу сработал, раз запрос дошёл.

ssh-agent: чтобы не вводить фразу каждый раз

Если вы задали парольную фразу, при каждом соединении компьютер будет спрашивать её. Чтобы не вводить её по десять раз, придумали ssh-agent — фоновую программу, которая держит расшифрованный ключ в памяти, пока вы работаете. Настройка зависит от системы (по документации GitHub):

  • Linux: запустите агент и добавьте ключ: eval "$(ssh-agent -s)", затем ssh-add ~/.ssh/id_ed25519. Агент напечатает Agent pid с номером процесса.
  • macOS: те же eval "$(ssh-agent -s)", а ключ добавляется с хранением фразы в связке ключей: ssh-add --apple-use-keychain ~/.ssh/id_ed25519. Чтобы так происходило всегда, в файле ~/.ssh/config описывают блок Host github.com с настройками AddKeysToAgent yes, UseKeychain yes и IdentityFile ~/.ssh/id_ed25519. Если система пожалуется на Bad configuration option: usekeychain, добавьте под Host строку IgnoreUnknown UseKeychain.
  • Windows: в PowerShell, открытом от имени администратора, выполните Get-Service -Name ssh-agent | Set-Service -StartupType Manual и Start-Service ssh-agent. Затем в обычном терминале ssh-add c:/Users/ВАШЕ_ИМЯ/.ssh/id_ed25519. Если Git for Windows всё равно спрашивает фразу, GitHub советует git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe".

Агент необязателен: без него всё работает, просто фразу придётся вводить. А если фразу вы не задавали, он и не нужен.

Практика у себя

  1. Создайте ключ: ssh-keygen -t ed25519 -C "ваша_почта". Нажмите Enter на вопросе о файле и задайте парольную фразу.
  2. Проверьте файлы: ls ~/.ssh должен показать id_ed25519 и id_ed25519.pub.
  3. Скопируйте открытый ключ командой для вашей системы.
  4. Добавьте его на GitHub: Settings, SSH and GPG keys, New SSH key, Title, Key, Add SSH key.
  5. Выполните ssh -T git@github.com, сверьте отпечаток с документацией GitHub и ответьте yes. Должно появиться «Hi ваш-логин! You've successfully authenticated...».
  6. Переключите репозиторий: git remote set-url origin git@github.com:ваш-логин/portfolio.git, проверьте git remote -v.
  7. Убедитесь, что вход работает: git push должен сказать Everything up-to-date.

Проверьте себя

  • ls ~/.ssh показывает два файла, один из них оканчивается на .pub.
  • В SSH and GPG keys на GitHub есть ключ с вашим названием.
  • ssh -T git@github.com приветствует вас по логину.
  • git remote -v показывает адреса, начинающиеся с git@github.com:.

Частые ошибки

Permission denied (publickey)

Вывод
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Что видно: GitHub не узнал ваш ключ. По чек-листу из документации GitHub проверьте по порядку:

  • вы подключаетесь как git@github.com, а не как ваш-логин@github.com, и без sudo;
  • агент знает ключ: ssh-add -l -E sha256 должен вывести его отпечаток; если пусто — запустите агент и сделайте ssh-add;
  • ключ добавлен именно в тот аккаунт, в который вы входите;
  • для подробностей запустите ssh -vT git@github.com и поищите строку Offering public key.

Полный разбор — в документации GitHub.

Закрытый ключ попал не в те руки

Если вы случайно отправили файл без .pub в чат, на сайт или в репозиторий, действуйте сразу: на GitHub откройте SSH and GPG keys и удалите этот ключ, затем создайте новую пару. Удалить файл из чата мало, считайте ключ скомпрометированным.

Remote всё ещё на HTTPS

Вы настроили ключ, а Git по-прежнему просит вход через браузер. Посмотрите git remote -v: если адрес начинается с https://, переключите его на git@github.com:... командой git remote set-url. Ключ работает только с SSH-адресом.

Вопрос про отпечаток при первом входе

Это не ошибка. Ответ yes даётся только после сверки отпечатка с тем, что указан на официальной странице GitHub. Если не совпало, отвечайте no.

Общий обзор — подключение к GitHub по SSH.

Что важно запомнить

  • SSH-ключ — пара файлов: открытый (.pub, «замок») отдаём GitHub, закрытый («ключ») храним у себя.
  • Создаётся командой ssh-keygen -t ed25519 -C "почта"; файлы лежат в ~/.ssh.
  • На GitHub открытый ключ добавляют в Settings, SSH and GPG keys, New SSH key.
  • ssh -T git@github.com проверяет вход; в приветствии должен быть ваш логин.
  • После git remote set-url origin git@github.com:логин/репозиторий.git Git ходит на GitHub по ключу.

Теперь у вас есть надёжный вход, и проект лежит на GitHub. Остаётся научиться работать с этой копией в обе стороны: скачивать чужие и свои проекты, узнавать об изменениях на сервере и подтягивать их. Этим мы и займёмся дальше: командами clone, fetch и pull.

На следующий урок