Работа с SSH ключами

SSH – незаменимое средство для автоматизации в мире Linux-устройств. Нужно только, чтобы на удалённом устройстве был SSH-сервер. Чтобы подключиться, просто используем ssh для подключения как user на host.

$ ssh user@host

В таком же виде удобно использовать подключение и в рамках скриптов. И да, имя пользователя можно опустить, если оно совпадает с именем локального пользователя, от которого выполняется команда.

Конечно, при соединении с удалённым хостом нужно подтвердить свою личность. Делается это (чаще всего) либо паролем для пользователя, либо использованием SSH-ключей.

Считается, что SSH-ключи (как и другие криптосистемы с открытым ключём) имеют большую степень безопасности в использовании т.к. не требуют раскрытия удалённому хосту всей информации и не страдают от недостатка сложности.

Кроме того, SSH-ключи не нужно интерактивно вводить как пароль или держать в голове. Этот плюс и используется для автоматизации действий.

Для использования таких ключей генерируется их пара. Один из ключей в паре будет приватным, а другой публичным. Удалённому хосту нужно знать только публичный ключ, а приватный должен быть известен только Вам!

Как пример, сгенерирую новую пару ключей на своей виртуальной машине Debian.

vm@debian:~$ ssh-keygen -t ed25519

Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/vm/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/vm/.ssh/id_ed25519
Your public key has been saved in /home/vm/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:k/GVrkNbmDuryEPoe/8VBAei4IT9T19dlQjU23DjIxQ vm@debian
The key's randomart image is:
+--[ED25519 256]--+
|   oo   . +++Eo +|
|  .o.. . . o * +.|
|    ... .   =.*..|
|      . .+ *.o.+ |
|     . oS.=.+ . .|
|    . . .o.= .   |
|   . .    * .    |
|    ..o.   =     |
|    .oooooo      |
+----[SHA256]-----+

Как видно, единственная опция, которую я передаю – -t ed25519. Она нужна, чтобы сгенерировать ключи типа EdDSA, а не RSA. EdDSA считается более безопасным алгоритмом. Поэтому некоторые SSH серверы просто отказываются принимать ключи с типом RSA.

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

В случае интерактивной сессии может иметь смысл установить пароль. В случае работы с несколькими удалёнными устройствами может иметь смысл использование разных пар ключей.

Всё это открытые вопросы, которые остаются на усмотрение конкретного пользователя и его подходу к политикам безопасности. Это слишком неоднозначные и сложные темы для обсуждения в рамках практической заметки.

Обратно к вопросам генерации. В простейшем случае достаточно нажимать Enter и оставить параметры по умолчанию. В данном случае видим, что сгенерировались 2 файла.

Файл /home/vm/.ssh/id_ed25519приватный ключ в папке .ssh у пользователя vm. Находящийся рядом с ним файл id_ed25519.pubпубличный ключ, о чём говорит суффикс .pub.

Заглянем в сгенерированные файлы. Вот приватный ключ.

vm@debian:~$ cat ~/.ssh/id_ed25519

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACCsymlmvGSG1YZv5OcYMDh5xvUbPJprLnNW5KUG5nSOQQAAAJBn2U9fZ9lP
XwAAAAtzc2gtZWQyNTUxOQAAACCsymlmvGSG1YZv5OcYMDh5xvUbPJprLnNW5KUG5nSOQQ
AAAEAJvrk1wlOKqXeC9dOTHGUUrqgdSgHNyxF2pnyrrh1xP6zKaWa8ZIbVhm/k5xgwOHnG
9Rs8mmsuc1bkpQbmdI5BAAAACXZtQGRlYmlhbgECAwQ=
-----END OPENSSH PRIVATE KEY-----

Как видим, тут присутствует блок OPENSSH PRIVATE KEY. Он явно даёт понять – такой ключ не должен видеть никто кроме Вас!

Теперь посмотрим на публичный ключ.

vm@debian:~$ cat ~/.ssh/id_ed25519.pub

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzKaWa8ZIbVhm/k5xgwOHnG9Rs8mmsuc1bkpQbmdI5B vm@debian

Ага, видим указание типа ключа, сам ключ (который значительно меньше приватного) и комментарий. Здесь vm@debian – простое указание комментария по-умолчанию. vm – пользователь, а debian – хост, на котором генерировался ключ.

Если Вы хотите изменить комментарий, то его можно указать с помощью опции -C для ssh-keygen. Например, вот так можно сгенерировать ключ с комментарием name.surname@example.corp.com.

$ ssh-keygen -t ed25519 -C 'name.surname@example.corp.com'

Подобная форма бывает полезна в корпоративных окружениях, где требуется различать публичные ключи по адресам корпоративных почтовых ящиков.

Возвращаемся к содержимому публичного ключа. Именно его нужно передавать в удалённую систему. Сервисы типа GitHub принимают такие публичные ключи только в Web-UI. В таком случае можно скопировать вывод команды cat и вставить в форму.

Как альтернативу могу предложить утилиту wl-copy из пакета wl-clipboard. Это простой инструмент для помещения данных в буфер обмена сессий Wayland.

vm@debian:~$ cat ~/.ssh/id_ed25519.pub | wl-copy

Для помещения публичного SSH ключа на удалённый сервер требуется другой подход. Самый простой – использовать ssh-copy-id. Воспользуюсь для добавления ключа на свою виртуальную машину с Arch.

vm@debian:~$ ssh-copy-id vm@arch.local

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/vm/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
vm@arch.local's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'vm@arch.local'"
and check to make sure that only the key(s) you wanted were added.

Всё, что делает утилита – добавляет строчку из Вашего публичного ключа в файл ~/.ssh/authorized_keys у пользователя на удалённом хосте. Сервер SSH сможет аутентифицировать пользователя по его авторизованным публичным ключам.

К примеру, так может выглядеть ~/.ssh/authorized_keys на удалённом хосте. Ранее я добавил ключ для другой VM с Mint. Это хорошо демонстрирует, что можно использовать множество разных ключей для подключения на удалённый сервер.

vm@arch:~$ cat .ssh/authorized_keys

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDbdtccUbu0QvYyo6Zn8V3ZfZXOhvBHLeFvblAMfatjL vm@mint
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKzKaWa8ZIbVhm/k5xgwOHnG9Rs8mmsuc1bkpQbmdI5B vm@debian

Последующее использование ssh vm@arch.local будет автоматически использовать сгенерированную пару ключей типа Ed25519.

Дополнительно отмечу, что SSH крайне аккуратно относится к правам доступа для папки .ssh и файлам в ней. В общем случае привести права к виду по-умолчанию можно следующими командами.

$ sudo chown $USER: ~/.ssh/
$ chmod 700 ~/.ssh/
$ chmod 600 ~/.ssh/*
$ chmod 644 ~/.ssh/*.pub

Опишу словами. Владельцем папки .ssh должен быть тот пользователь, у которого находится эта папка. Получать к ней доступ может только сам этот пользователь. Все файлы в папке доступны на чтение и запись только для владельца. Исключение сделано только для файлов с публичными ключам .pub, они доступны на чтение всем.

Эти правила хорошо передают семантику использования ключей с точки зрения прав доступа в файловой системе.

P.S.: если Вам интересно, что именно делает SSH-клиент при подключении к серверу, то всегда можно воспользоваться опцией -v для SSH.

Журнал изменений

29 июня 2024 г.: убрал дубликаты предложений по смыслу.

Если Вы хотите обсудить содержание заметки, задать вопросы или предложить изменения, то со мной можно связаться в Telegram