Справочник · Терминал и система
SSH-ключи: создать, добавить, пользоваться
Как сделать ключ ed25519, защитить его паролем, подключить ssh-agent, разложить настройки по ~/.ssh/config и понять, что означает предупреждение об изменившемся ключе сервера.
Вход по ключу удобнее и надёжнее пароля: ключ не подобрать перебором, а вводить ничего не нужно. Ниже порядок действий от создания ключа до аккуратного ~/.ssh/config.
Как это устроено
Ключ состоит из двух файлов. Закрытый остаётся только у вас и никуда не копируется. Открытый (с расширением .pub) можно спокойно отдавать: его кладут на сервер или в настройки Git-хостинга. При входе сервер проверяет, что вы владеете закрытым ключом, который соответствует открытому, а сам закрытый ключ по сети не передаётся.
| Файл | Что это | Права |
|---|---|---|
~/.ssh/id_ed25519 | закрытый ключ | 600 |
~/.ssh/id_ed25519.pub | открытый ключ | 644 |
~/.ssh/config | настройки клиента | 600 |
~/.ssh/known_hosts | ключи серверов, к которым вы уже подключались | 644 |
~/.ssh/authorized_keys | на сервере: открытые ключи, которым разрешён вход | 600 |
~/.ssh/ | сам каталог | 700 |
Создание ключа
ssh-keygen -t ed25519 -C "laptop-2026"-t ed25519выбирает современный тип ключа: короткий, быстрый и надёжный. Поддерживается OpenSSH с версии 6.5, то есть практически везде.-Cзадаёт комментарий. Он попадает в конец открытого ключа и помогает потом понять, какой ключ откуда. Удобно писать имя устройства.- Программа спросит, куда сохранить. Если ключ для отдельной цели, дайте ему своё имя:
-f ~/.ssh/id_work. - Затем она попросит парольную фразу. Её стоит задать: если файл ключа украдут, без фразы им не воспользоваться.
Если какая-то старая система не понимает ed25519, используйте RSA длиной не меньше 3072 бит: ssh-keygen -t rsa -b 4096.
Поменять парольную фразу существующего ключа можно без пересоздания: ssh-keygen -p -f ~/.ssh/id_ed25519.
Как добавить ключ на сервер
Самый простой способ, если вход по паролю пока работает:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@serverКоманда допишет открытый ключ в ~/.ssh/authorized_keys нужного пользователя и сама поправит права. Вручную то же самое:
cat ~/.ssh/id_ed25519.pub | ssh user@server 'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'Для Git-хостинга открытый ключ вставляется в настройках профиля в разделе SSH-ключей. Показать его, чтобы скопировать:
cat ~/.ssh/id_ed25519.pubПроверить, что ключ принят, можно командой ssh -T git@адрес-хостинга: обычно в ответ приходит приветствие с вашим именем.
ssh-agent: пароль ключа один раз
Чтобы не вводить парольную фразу при каждом подключении, ключ загружают в агент. Он держит расшифрованный ключ в памяти до конца сеанса.
eval "$(ssh-agent -s)" # запустить агент, если он ещё не запущен
ssh-add ~/.ssh/id_ed25519 # добавить ключ, спросит фразу один раз
ssh-add -l # какие ключи загружены
ssh-add -D # выгрузить все
ssh-add -t 4h ~/.ssh/id_ed25519 # загрузить на 4 часаВ большинстве графических окружений Linux и в macOS агент уже запущен. На macOS добавьте в конфиг UseKeychain yes и AddKeysToAgent yes, тогда фраза сохранится в связке ключей.
~/.ssh/config
В конфиге клиента описывают серверы, чтобы вместо длинной команды набирать короткое имя.
Host *
AddKeysToAgent yes
IdentitiesOnly yes
ServerAliveInterval 60
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/id_ed25519
Host git-work
HostName git.company.test
User git
IdentityFile ~/.ssh/id_workТеперь ssh prod заменяет ssh -p 2222 -i ~/.ssh/id_ed25519 deploy@203.0.113.10, а имя работает и в scp, rsync и git.
| Параметр | Что задаёт |
|---|---|
Host | короткое имя или шаблон, к которому относится блок |
HostName | настоящий адрес или доменное имя |
User | пользователь на сервере |
Port | порт, если не 22 |
IdentityFile | какой ключ использовать |
IdentitiesOnly yes | пробовать только указанные ключи, а не все из агента |
ServerAliveInterval | раз в N секунд проверять, что соединение живо |
Порядок блоков важен: для каждого параметра берётся первое найденное значение. Поэтому общий блок Host * с значениями по умолчанию лучше ставить в конец файла, а если он стоит первым, в нём не должно быть того, что вы хотите переопределять ниже.
Два аккаунта на одном Git-хостинге
Частая задача: личный и рабочий аккаунт, у каждого свой ключ. Делается через два имени в конфиге, как git-work выше, и адрес репозитория с этим именем:
git clone git-work:team/project.git
git remote set-url origin git-work:team/project.gitIdentitiesOnly yes здесь обязателен: без него клиент может первым предложить личный ключ, хостинг его примет, и вы окажетесь не в том аккаунте.
known_hosts и отпечатки
При первом подключении клиент показывает отпечаток ключа сервера и спрашивает, доверять ли ему:
The authenticity of host 'prod (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:3Q1h0m6...
Are you sure you want to continue connecting (yes/no/[fingerprint])?Правильный ответ: сверить отпечаток с тем, что показывает сам сервер. На сервере это делается так:
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pubПосле согласия ключ сервера записывается в known_hosts. Если потом ключ поменяется, клиент откажется подключаться с крупным предупреждением REMOTE HOST IDENTIFICATION HAS CHANGED. Обычная причина безобидна: сервер переустановили. Но это может быть и подмена, поэтому сначала выясните, что произошло, и только потом удаляйте старую запись:
ssh-keygen -R prod # удалить запись о сервере
ssh-keygen -R '[203.0.113.10]:2222' # для нестандартного портаОтпечаток своего ключа показывает ssh-keygen -lf ~/.ssh/id_ed25519.pub. Это SHA-256 от содержимого ключа в Base64; что такое хеш и почему по нему нельзя восстановить ключ, рассказано в статье про хеширование.
Когда вход не работает
Подробный вывод клиента почти всегда показывает причину:
ssh -v prod # -vv и -vvv ещё подробнее| Сообщение | Что проверить |
|---|---|
Permission denied (publickey) | тот ли ключ предлагается (Offering public key в выводе -v), есть ли он в authorized_keys нужного пользователя |
Bad permissions или UNPROTECTED PRIVATE KEY FILE | права на закрытый ключ: chmod 600 |
Too many authentication failures | агент перебрал слишком много ключей; добавьте IdentitiesOnly yes и укажите IdentityFile |
Connection refused | служба SSH не запущена или слушает другой порт |
Connection timed out | сервер недоступен по сети или порт закрыт межсетевым экраном |
На стороне сервера смотрите журнал: journalctl -u ssh -f (на некоторых системах служба называется sshd). Самая частая серверная причина — слишком открытые права на домашний каталог, ~/.ssh или authorized_keys: в этом случае сервер молча игнорирует ключ. Правильные права перечислены в таблице в начале статьи, а как их выставить, описано в статье про chmod.
Хорошие привычки
- Один ключ на устройство, понятный комментарий в каждом ключе.
- Парольная фраза на закрытом ключе плюс агент, чтобы не вводить её постоянно.
- Раз в год пересматривайте
authorized_keysна серверах и удаляйте ключи устройств, которых больше нет. - Резервная копия закрытого ключа, если она нужна, хранится в менеджере паролей, а не в облачной папке рядом с фотографиями.
- После того как вход по ключу проверен, вход по паролю на сервере лучше отключить:
PasswordAuthentication noв настройках службы SSH.