Создание SSH ключей и настройка доступа по SSH-ключу в Debian 11

Серия - Проект на Django + DRF + Nuxt с нуля до деплоя
Замечание
Последний раз данная статья обновлялась 08.12.2022, информация может быть устаревшей.

SSH или Secure Shell (безопасная оболочка) - это зашифрованный протокол, используемый для администрирования и связи с серверами. Настроив доступ по SSH ключу, мы получим более простой и безопасный способ входа на сервер, чем вход по паролю. В отличие от пароля, взломать SSH-ключ гораздо сложнее.1

SSH поддерживает несколько алгоритмов. К ним относятся:

rsa (аббревиатура от фамилий Rivest, Shamir и Adleman) - старый алгоритм, основывающийся на вычислительной сложности задачи факторизации больших простых чисел. Для RSA рекомендуется использовать размер ключа не менее 2048 бит. На сайте SSH пишут, что вероятнее всего в ближайшем будущем он будет полностью взламываемым, и от него придется отказаться. Возможно, целесообразно выбрать другой алгоритм уже сейчас. Однако его преимущество в том, что все SSH-клиенты его поддерживают.2

dsa (Digital Signature Algorithm) - старый алгоритм цифровой подписи (но не шифрования). Основан на вычислительной сложности взятия логарифмов в конечных полях. DSA в его первоначальном виде больше не рекомендуется к использованию.3

ecdsa (Elliptic Curve Digital Signature Algorithm) - новый алгоритм цифровой подписи с использованием криптографии на эллиптических кривых. Это хороший алгоритм, используется в биткойне и эфириуме. Поддерживаются три размера ключа: 256, 384 и 521 бит. Рекомендуется всегда использовать его с 521 битом. Большинство SSH-клиентов его поддерживают.4

ed25519 - схема подписи EdDSA (Edwards-curve Digital Signature Algorithm), использующая SHA-512 и Curve25519 (что бы это ни значило…). Проще говоря - это новый алгоритм, который работает быстрее без ущерба для безопасности. Поддерживается не всеми SSH-клиентами, поэтому используйте его на свое усмотрение.5

Я, естественно, буду использовать RSA, потому что являюсь динозавром сначала сделал, а потом углубился и узнал, что алгоритм говно устарел (╯°益°)╯彡┻━┻

  • -t (Тип) - определяет алгоритм создаваемого ключа;
  • -b (Биты) - определяет количество бит в ключе;
  • -f (Файл) - имя файла, в котором будет храниться созданный ключ;
  • -c (Комментарий) - комментарий для файла ключа.6

Первый шаг - создать пару ключей на клиенте (наш компьютер). В целом, 2048 бит считается достаточным для ключей RSA, но я буду использовать 4096.

Почему 4096 бит?
В 2010 году группе учёных при помощи общего метода решета числового поля удалось успешно вычислить данные, зашифрованные при помощи криптографического ключа стандарта RSA длиной 768 бит. С 31 декабря 2013 года браузеры Mozilla перестали поддерживать сертификаты удостоверяющих центров с ключами RSA меньше 2048 бит. C того времени вычислительные мощности возросли на порядок, поэтому 4096, чтоб мамкины хацкеры не взломали нас решетом так безопаснее =)
ssh-keygen -t rsa -b 4096

После ввода команды нужно следовать инструкции

// Output
Generating public/private rsa key pair.
Enter file in which to save the key (/your_home/.ssh/id_rsa):

Нажмите Enter, чтобы сохранить пару ключей в папке .ssh/, или укажите альтернативный путь.

Если пара ключей id_rsa ранее уже была сгенерирована, то будет получено предложение перезаписать существующие ключи:

/home/your_home/.ssh/id_rsa already exists.
Overwrite (y/n)?
Перезапись - это необратимый процесс
Если вы решите перезаписать ключ на диске, вы больше не сможете авторизоваться с помощью предыдущего ключа.

Нажмите на клавишу Enter. Далее система предложит ввести кодовую фразу для дополнительной защиты SSH-подключения:

Enter passphrase (empty for no passphrase):
  • вводим кодовую фразу (и не забываем ее)
  • ничего не вводим - тогда не придется вводить кодовую фразу при подключении (не рекомендуется, это менее безопасно)

Жмем Enter.

После этого ключ будет создан, а на консоль будет выведено следующее сообщение:

Your identification has been saved in /your_home/.ssh/id_rsa.
Your public key has been saved in /your_home/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:5E2BtTN9FHPBNoRXAB/EdjtHNYOHzTBzG5qUv7S3hyM user@localhost
The key's randomart image is:
+---[RSA 4096]----+
|         oo .O^XB|
|        .  +.BO%B|
|        . = .+B+o|
|       o o o . =.|
|        S .   . =|
|               o.|
|               .o|
|            E o..|
|             . ..|
+----[SHA256]-----+

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

Для копирования путличного ключа есть несколько вариантов.

Самый простой - при помощи утилиты ssh-copy-id:

ssh-copy-id www@remote_host_ip

Если это первое подключение к серверу, вы можете увидеть примерно такое сообщение:

The authenticity of host '203.23.13.15 (203.23.13.15)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

Введите yes и нажмите ENTER, чтобы продолжить.

Затем утилита просканирует вашу локальную учетную запись на наличие ключа id_rsa.pub, который мы создали ранее. Когда ключ будет найден, вас попросят ввести пароль учетной записи удаленного пользователя:

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed:
"/your_home/.ssh/id_rsa.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
www@remote_host_ip's password:

Вводим пароль, и ключ копируется на удаленный сервер, о чем мы и получаем подтверждение:

Number of key(s) added:        1

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

Если нет ssh-copy-id, но есть SSH-доступ по паролю, можно загрузить ключи с помощью него:

  • При помощи команды cat, читаем содержимое открытого SSH-ключа на нашем локальном компьютере и прокидываем его через SSH на сервер.
  • Дополнительно нужно убедиться, что каталог ~/.ssh существует и имеет нужные права.
  • Используя символ перенаправления >>, добавляем контент в файл с именем authorized_keys вместо того, чтобы перезаписывать его. Это позволит нам добавлять ключи, не удаляя ранее добавленные.
cat ~/.ssh/id_rsa.pub | ssh username@remote_host "mkdir -p ~/.ssh && touch ~/.ssh/authorized_keys && chmod -R go= ~/.ssh && cat >> ~/.ssh/authorized_keys"

Скопируем содержимое публичного ключа:

vim ~/.ssh/config

Подключаемся к серверу любым доступным методом и создаем катлог ~/.ssh/:

mkdir -p ~/.ssh

Создаем в этом каталоге файл authorized_keys и записываем в него наш публичный ключ:

echo public_key_string >> ~/.ssh/authorized_keys

public_key_string - это и есть скопированый ключ. Строка должна начинаться с ssh-rsa AAAA....

Так же, нужно убедиться, что каталог и файл имеют нужные права. Для этого рекурсивно удаляем все group и other права для каталога ~/.ssh/:

chmod -R go= ~/.ssh

Если все предыдущие действия делались под root, важно проследить, чтобы каталог ~/.ssh принадлежал пользователю, а не root:

chown -R www:www ~/.ssh

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

The authenticity of host 'xxx.xxx.xxx.xxx (xxx.xxx.xxx.xxx)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes

Вводим yes и жмем Enter.

Файлы конфигурации OpenSSH делятся на клиентские и серверные:

  • /etc/ssh/sshd_config: относится к серверной части. Сервер OpenSSH читает этот файл при запуске. Мы будем править его на следующем шаге.
  • К клиентским конфигам OpenSSH относятся два файла на локальной машине: общесистемный - /etc/ssh/ssh_config и пользовательский - ~/.ssh/config. Общесистемный имеет приоритет над пользовательским.

Если мы задали passphrase при генерации ключа, то на Mac она будет запрашиваться при каждом подключении. Удобнее хранить ее в keychain. Для этого нужно отредактировать локальный клиентский файл конфигурации SSH ~/.ssh/config:

vim ~/.ssh/config
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Host *
  # Разрешаем использовать keychain
  UseKeychain yes
  # Устанавливаем интервал проверки соединения
  ServerAliveInterval 10

# Кстати, можно сразу добавить алиас для вашего сервера
# После добавления алиаса можно подключиться командой ssh myserver
Host myserver
  HostName 194.67.87.158  # ip сервера
  User www

Теперь мы можем подключаться к серверу без пароля, однако, сам механизм аутентификации на основе пароля все еще активен. Чтобы избежать возможности подбора пароля брутфорсом, можно полностью отключить этот вид аутентификации. Заодно отключим и вход под root юзером.

Внимание!
Перед отключением аутентификации по паролю и входа под рутом следует убедиться, что аутентификация по ключу корректно настроена для юзера www с правами sudo!

Чтобы отключить вход по паролю нужно поправить файл серверной конфигурации OpenSSH - /etc/ssh/sshd_config.7

Логинимся на сервер под юзером www:

ssh www@111.23.111.22

Открываем файл в редакторе vim:

sudo vim /etc/ssh/sshd_config

При использовании sudo система попросит ввести пароль пользователя:

www@localhost:~$ sudo vim /etc/ssh/sshd_config
[sudo] password for www:
Отключение пароля для sudo

Чтобы в дальнейшем не вводить пароль при каждой команде sudo можно отключить запрос пароля. Для этого выполним:

sudo visudo
  • Находим нужную строку и меняем %sudo ALL=(ALL:ALL) ALL на %sudo ALL=(ALL:ALL) NOPASSWD:ALL
  • Жмем Ctrl+X -> Y -> Enter чтоб сохранить изменения.
Поиск в vim
Чтоб найти строку в Vim, можно воспользоваться поиском: вводим /PermitRootLogin -> Enter. Прерходить к следующему/предыдущему результату можно при помощи клавиш n и p.

Нас интересуют следующие строки:

  • PermitRootLogin yes - найдя нужную строчку переходим в режим редактирования нажав клавишу i и меняем значение на no.
  • AllowUsers www - если такой строки нет, добавляем в любое место. Разрешаем подключаться только юзеру www.
  • PasswordAuthentication yes - если эта строка закомментирована, ее нужно раскомментить и изменить значение на no.

Выходим из режима редактирования нажав Esc, и выходим из vim с сохранением изменений: :wq.

Перезапускаем службу sshd:

sudo systemctl restart sshd

Готово. Можно отключиться и попробовать зайти под рутом, чтобы убедиться, что конфиг работает. Результат должен быть примерно таким:

❯ ssh root@95.163.237.144
root@95.163.237.144: Permission denied (publickey).

Использованы материалы статьи How to Set Up SSH Keys on Debian 11