SSH-ключи нужны, чтобы входить на сервер и в GitHub без пароля: вы создаёте пару ключей командой ssh-keygen, закрытый оставляете у себя, а открытый кладёте на сервер. Команды даны для Linux, macOS и Windows (PowerShell и Git Bash), вывод взят из нашего прогона: OpenSSH 10.5p1 в Git Bash и OpenSSH_for_Windows 9.5p1, который в Windows 10 лежит в папке C:\Windows\System32\OpenSSH.

- Что такое SSH-ключи и чем они лучше пароля
- Какой тип ключа выбрать: ed25519 или RSA
- Создание SSH-ключа с помощью ssh-keygen
- Где хранятся SSH-ключи и какие нужны права
- Кодовая фраза и ssh-agent
- Как добавить открытый ключ на сервер
- Как отключить вход по паролю
- Файл ~/.ssh/config: использование нескольких ключей
- SSH-ключ для GitHub и GitLab
- Ошибки: Permission denied (publickey) и другие
- Частые вопросы
- Можно ли использовать один SSH-ключ для нескольких серверов?
- Что делать, если закрытый ключ потерян?
- Где хранятся SSH-ключи в Ubuntu?
- Нужно ли создавать ключ заново для Windows и Git Bash?
Что такое SSH-ключи и чем они лучше пароля
Пара SSH-ключей состоит из двух файлов. Закрытый (приватный, секретный) ключ лежит только на вашем компьютере и заменяет пароль: кто получит файл ключа без кодовой фразы, получит и доступ под вашим именем к любому серверу, где лежит пара к нему. Открытый (публичный) ключ можно показывать кому угодно. Его дописывают отдельной строкой в файл ~/.ssh/authorized_keys на сервере, и при подключении сервер проверяет, что у клиента есть закрытый ключ, парный этой строке.
Пароль к удалённому серверу можно подбирать перебором, а при аутентификации по ключу угадывать нечего. Как устроена сама математика пары, разобрано в статье про RSA шифрование.

Какой тип ключа выбрать: ed25519 или RSA
Для нового ключа выбирайте алгоритм ed25519. Обе версии OpenSSH на нашей машине создали именно его даже без параметра -t, а открытый ключ у него в несколько раз короче. RSA нужен, если сервер или старая система не поддерживает ed25519. Открытый RSA-ключ начинается с ssh-rsa, ключ ed25519 с ssh-ed25519.
| Тип | Команда | Длина (ssh-keygen -l) | Размер .pub в прогоне |
|---|---|---|---|
| ed25519 | ssh-keygen -t ed25519 | 256 | 98 байт |
| RSA | ssh-keygen -t rsa | 3072 по умолчанию | 562 байта |
| RSA 4096 | ssh-keygen -t rsa -b 4096 | 4096 | — |
| DSA | ssh-keygen -t dsa | в 10.5p1: unknown key type dsa | — |
Минимальная длина RSA 1024 бит: на -b 1023 команда отвечает Invalid RSA key length: minimum is 1024 bits. Если всё же берёте RSA, задайте -b 4096. Ключи DSA GitHub не принимает с 15 марта 2022 года.
Создание SSH-ключа с помощью ssh-keygen
В Linux, macOS и Git Bash команда одна (что такое Git Bash и как его поставить, есть отдельная статья). Параметр -C записывает комментарий в конец открытого ключа, обычно туда пишут почту, иначе ssh-keygen подставит имя пользователя и компьютера.
ssh-keygen -t ed25519 -C "ivan@example.com"
Вывод в Git Bash (имя пользователя заменено на user):
Generating public/private ed25519 key pair.
Enter file in which to save the key (/c/Users/user/.ssh/id_ed25519):
Enter passphrase for "/c/Users/user/.ssh/id_ed25519" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/user/.ssh/id_ed25519
Your public key has been saved in /c/Users/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:2O3c1Mx/tRUEXjijCwrGPWsAKbH/JyqHt8OZGr9aHeg ivan@example.com
На первый вопрос нажмите Enter, и ключ ляжет по пути по умолчанию, или введите свой путь. Если такой файл уже есть, программа напишет already exists и спросит Overwrite (y/n)?. Отвечайте n: старый ключ мог быть добавлен на серверы. Введите другое имя, например ~/.ssh/github_key. Дальше программа попросит кодовую фразу и её повтор. После строк про отпечаток ssh-keygen рисует randomart, рамку из символов: так отпечаток показан картинкой.

В Windows запустите PowerShell и выполните встроенный ssh-keygen. Ключ ляжет в C:\Users\<имя>\.ssh. Git Bash по умолчанию предлагает ту же папку, только пишет её как /c/Users/<имя>/.ssh, так что обе среды работают с одними файлами.
# PowerShell, встроенный OpenSSH
ssh-keygen -t ed25519 -C "ivan@example.com"
Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub
После генерации ключа вторая команда печатает содержимое открытого ключа: тип, сам ключ в base64 и комментарий (в Linux и Git Bash то же делает cat). Его вы и копируете на сервер:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAq47Boubxu/Wh3WMIaF51LbDNmJzCD5fCzeYVyhGqP6 ivan@example.com
Параметры ssh-keygen в командной строке, которые пригодятся:
-tтип ключа (алгоритм):ed25519,rsa,ecdsa;-bдлина в битах, для RSA;-Cкомментарий;-fимя файла, тогда вопрос о пути не задаётся;-l -f файл.pubпоказать отпечаток;-y -f закрытый_ключзаново вывести открытый ключ, если файл.pubпотерялся;-p -f закрытый_ключсменить кодовую фразу.
Где хранятся SSH-ключи и какие нужны права
В Linux и macOS ключи пользователя лежат в директории ~/.ssh, то есть /home/<имя>/.ssh в Linux. Закрытый файл без расширения (id_ed25519, id_rsa), открытый с .pub. Ключи самого сервера, по которым клиент узнаёт хост, лежат отдельно: /etc/ssh/ssh_host_ed25519_key и соседние файлы.
| Что | Права | Почему |
|---|---|---|
~/.ssh | 700 | папка доступна только владельцу |
~/.ssh/id_ed25519 | 600 | закрытый ключ не должен читать никто, кроме владельца |
~/.ssh/id_ed25519.pub | без требований | открытый ключ не секрет |
~/.ssh/authorized_keys на сервере | 600 | чтение и запись только владельцу |
~/.ssh/config | 600 или 644 | писать в него может только владелец |

Если права сбились, верните их:
# на своём компьютере (Linux, macOS)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
# на сервере
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
В Windows ключи лежат в C:\Users\<имя>\.ssh. У закрытого ключа, который создал ssh-keygen в нашем прогоне, icacls показал доступ только у администраторов, системы и самого пользователя. Если сервер тоже на Windows, открытый ключ обычного пользователя кладут в C:\Users\<имя>\.ssh\authorized_keys, а для учётной записи администратора в C:\ProgramData\ssh\administrators_authorized_keys, и к этому файлу доступ оставляют только администраторам и системе.
Кодовая фраза и ssh-agent
Кодовая фраза (passphrase) служит паролем к самому ключу: она шифрует закрытый ключ на диске, и для входа нужны и файл, и фраза. Пустую фразу оставляйте только ключам для автоматических задач. Хорошая фраза длиной 10-30 символов и не похожа на простое предложение, которое легко угадать. Забытую фразу восстановить нельзя, остаётся создать новую пару.
Сменить или добавить фразу можно без новой пары. Открытый ключ при этом не меняется: в нашем прогоне ssh-keygen -y до и после смены фразы выдал одну и ту же строку. Команда такая:
ssh-keygen -p -f ~/.ssh/id_ed25519
Если фраза уже была, программа спросит старую (Enter old passphrase:), затем новую с повтором. При успехе пишет Your identification has been saved with the new passphrase. Неверная старая фраза даёт Failed to load key ...: incorrect passphrase supplied to decrypt private key, и файл не меняется: хеш SHA-256 до и после неудачной попытки в прогоне совпал.

Чтобы не вводить фразу при каждом подключении к серверу, ключ отдают ssh-agent: агент держит закрытые ключи в памяти, и фразу вы вводите один раз при добавлении. В Git Bash агента запускает ssh-agent -s, а eval применяет переменные, которые он напечатал:
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
ssh-add -l
Наш прогон:
Agent pid 8776
Identity added: /c/Users/user/.ssh/id_ed25519 (ivan@example.com)
256 SHA256:2O3c1Mx/tRUEXjijCwrGPWsAKbH/JyqHt8OZGr9aHeg ivan@example.com (ED25519)
Для ключа с фразой ssh-add перед Identity added спросит её: Enter passphrase for ...:.
В Windows агент работает как служба «OpenSSH Authentication Agent», и по умолчанию она отключена: на нашей машине Get-Service ssh-agent показал Status: Stopped и StartType: Disabled. Включите её в PowerShell от имени администратора:
# PowerShell от администратора
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
Если ключ добавлен в службу Windows, а git push всё равно спрашивает фразу, направьте Git на системный клиент: git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe".
Как добавить открытый ключ на сервер
Быстрее всего это делает ssh-copy-id. В Ubuntu он входит в пакет openssh-client, в Git Bash тоже есть, а во встроенном OpenSSH для Windows его нет. Команда подключается к серверу, спрашивает пароль и дописывает ключ в ~/.ssh/authorized_keys нужного пользователя на сервере. После @ стоит IP-адрес или имя сервера:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@203.0.113.10
Параметр -i лучше не пропускать: без него ssh-copy-id берёт самый свежий по дате изменения файл id*.pub из ~/.ssh, а это не всегда нужный ключ. Для нестандартного порта добавьте -p 2222. В конце скрипт пишет Number of key(s) added: 1 и предлагает подключиться для проверки.
При первом подключении к новому серверу клиент спросит, доверять ли ключу хоста (строки по исходникам OpenSSH 10.x; у встроенного клиента Windows 9.5p1 строка с отпечатком выглядит как ED25519 key fingerprint is SHA256:....):
The authenticity of host '203.0.113.10 (203.0.113.10)' can't be established.
ED25519 key fingerprint is: SHA256:...
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Ответ yes сохраняет ключ хоста в ~/.ssh/known_hosts. Если ключ этого сервера потом сменится, клиент выведет предупреждение REMOTE HOST IDENTIFICATION HAS CHANGED и с настройками по умолчанию прервёт подключение (Host key verification failed.). Сначала узнайте у администратора или в панели хостинга, меняли ли ключ. Если смена ожидаемая, удалите старую запись и подключитесь заново, клиент спросит о ключе, как в первый раз:
ssh-keygen -R 203.0.113.10
В прогоне на копии known_hosts команда ответила так (путь заменён):
# Host 203.0.113.10 found: line 1
/c/Users/user/.ssh/known_hosts updated.
Original contents retained as /c/Users/user/.ssh/known_hosts.old
Вручную ключ добавляют, когда ssh-copy-id нет, например из PowerShell. Скопируйте содержимое файла .pub, зайдите на сервер по паролю и выполните на нём:
# на Linux-сервере
mkdir -p ~/.ssh && chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
В редакторе вставьте ключ в конец файла, каждый ключ с новой строки, и сохраните изменения. Подойдёт и vim, если вы с ним знакомы: основные команды Vim собраны отдельно. У некоторых хостингов открытый ключ можно вставить в панели управления при создании виртуального сервера, тогда файл заполнят за вас.
Как отключить вход по паролю
Когда вход по ключу проверен, пароль можно отключить. Откройте файл настроек сервера командой sudo nano /etc/ssh/sshd_config и поставьте:
PasswordAuthentication no
По умолчанию у sshd стоит yes, то есть вход по паролю разрешён. В Ubuntu основной файл подключает /etc/ssh/sshd_config.d/*.conf, а sshd берёт первое найденное значение, поэтому настройка из такого файла перебьёт вашу. Посмотрите, нет ли там строки PasswordAuthentication yes: уберите её или поставьте PasswordAuthentication no в файле внутри /etc/ssh/sshd_config.d/. Проверьте конфигурацию командой sudo sshd -t и перезапустите службу: в Ubuntu это sudo systemctl restart ssh.service. Текущую сессию не закрывайте: откройте новое окно терминала и подключитесь к серверу по ключу. Если не пускает, верните настройку из старой сессии.

Файл ~/.ssh/config: использование нескольких ключей
Когда ключей несколько (сервер, GitHub, рабочий GitLab), удобно описать их в ~/.ssh/config. Для встроенного клиента Windows это %userprofile%\.ssh\config. Если файла нет, создайте его.
Host myserver
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/server_key
IdentitiesOnly yes
Host github.com
User git
IdentityFile ~/.ssh/github_key
IdentitiesOnly yes
Теперь, чтобы подключиться к серверу, вместо ssh -p 2222 -i ~/.ssh/server_key deploy@203.0.113.10 достаточно набрать ssh myserver. Строку IdentitiesOnly yes ставьте всегда. Без неё клиент предлагает серверу ещё и ключи из агента, а сервер по умолчанию разрешает 6 попыток аутентификации на одно соединение. Если ключей в агенте много, попытки могут кончиться раньше, чем очередь дойдёт до нужного, и сервер закроет соединение. С этой строкой в ход идут только файлы из конфига.
Проверить, что клиент понял конфигурацию, можно без подключения: команда ssh -G печатает итоговые настройки для хоста.
ssh -G myserver | grep -E "^(hostname|user|port|identityfile|identitiesonly) "
user deploy
hostname 203.0.113.10
port 2222
identitiesonly yes
identityfile ~/.ssh/server_key
SSH-ключ для GitHub и GitLab

На GitHub открытый ключ добавляют в настройках аккаунта. В Git Bash скопируйте его в буфер командой clip < ~/.ssh/id_ed25519.pub, затем:
- Нажмите на фото профиля в правом верхнем углу и выберите Settings.
- В разделе Access откройте SSH and GPG keys.
- Нажмите New SSH key.
- В поле Title напишите, с какого компьютера ключ, тип выберите authentication (аутентификация).
- Вставьте ключ в поле Key и нажмите Add SSH key.
Проверка подключения:
ssh -T git@github.com
При успехе появится сообщение Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access. Пользователь в адресе всегда git, а не ваш логин.
В GitLab путь такой: аватар, Edit profile, в левом меню Access и SSH keys, кнопка Add new key. Проверка ssh -T git@gitlab.com, ответ начинается с Welcome to GitLab.
Ошибки: Permission denied (publickey) и другие
Permission denied (publickey) значит, что сервер разрешает только аутентификацию по ключу и ни один из ключей, предложенных серверу, не подошёл. Мы получили эту ошибку, подключившись к GitHub с новым ключом, который не добавлен в аккаунт. Флаг -v показывает, какой ключ клиент предложил:
debug1: Will attempt key: /c/Users/user/.ssh/test_key ED25519 SHA256:4WreBMS4x0G4vUMyYijl0mth2RE81DPFP8bDxCEHW8M explicit
debug1: Offering public key: /c/Users/user/.ssh/test_key ED25519 SHA256:4WreBMS4x0G4vUMyYijl0mth2RE81DPFP8bDxCEHW8M explicit
debug1: Authentications that can continue: publickey
git@github.com: Permission denied (publickey).
После Offering public key сервер снова перечислил способы входа, то есть ключ не принят. Что проверить по порядку:
- тот ли ключ: сравните отпечаток из
ssh-add -l -E sha256илиssh-keygen -l -f ~/.ssh/id_ed25519.pubс отпечатком в настройках GitHub или с ключами вauthorized_keysна сервере; - тот ли пользователь: для GitHub и GitLab это
git, для сервера пользователь, в чейauthorized_keysдобавлен ключ; - права на сервере: если домашняя папка,
~/.sshилиauthorized_keysдоступны на запись другим, sshd файл не использует, а клиент видит ту же ошибку; sudoс Git не запускайте, git и ssh выполняйте от своего пользователя.

Если закрытый ключ в Linux или macOS доступен группе или всем, клиент его не берёт и пишет (текст по исходникам OpenSSH, путь для примера):
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/user/.ssh/id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Лечится командой chmod 600 ~/.ssh/id_ed25519. Если потерялся только файл .pub, восстановите его из закрытого ключа: ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pub. Для ключа с фразой команда спросит её (Enter passphrase for ...), а с неверной фразой выдаст incorrect passphrase supplied to decrypt private key.
Частые вопросы
Можно ли использовать один SSH-ключ для нескольких серверов?
Можно: один открытый ключ добавляют в authorized_keys на любом числе серверов. Но если закрытый ключ утечёт, доступ откроется ко всем этим серверам сразу, поэтому для рабочих и личных систем лучше держать разные пары и разводить их в ~/.ssh/config.
Что делать, если закрытый ключ потерян?
Закрытый ключ не восстановить. Создайте новую пару, разложите новый открытый ключ по всем серверам и сервисам, а старый ключ удалите из authorized_keys и из настроек GitHub.
Где хранятся SSH-ключи в Ubuntu?
Ключи пользователя лежат в его домашней папке, в /home/<имя>/.ssh. Ключи самого сервера лежат в /etc/ssh, это файлы ssh_host_*_key.
Нужно ли создавать ключ заново для Windows и Git Bash?
Нет: в нашем прогоне ssh-keygen из Git Bash по умолчанию предлагал ту же папку C:\Users\<имя>\.ssh, что и встроенный ssh-keygen Windows.








