SSH по верхам для программистов

Что я хотел бы знать об SSH при первом знакомстве. Минимум команд и настроек для комфортной работы или строчки в резюме.

рашн аксэнт

Что такое SSH и зачем SSH

Представьте, что используете телеграмм-бот. Вы нажали кнопку или отправили боту сообщение, и что-то получаете в ответ. Под капотом вы посылаете команду, она исполняется, а потом вам присылается ответ. Важно, что команда исполняется «где-то там», а не на вашем телефоне или компьютере. Ваше устройство лишь показывает результат. Это типичная ситуация общения по модели «клиент-сервер»: вы (client) просите оказать услугу (service) из списка доступных, а сервер её оказывает.

Технически, здесь три составляющие: телеграмм-клиент (ваше приложение), сервер (на нём исполняется бот) и инфраструктура, которую даёт Telegram (протоколы общения). Фактически, вы управляете сервером, используя мобильник.

Более общим является удалённый доступ (от слова «далеко»). Это когда вы со своего компьютера исполняете команды на другом компьютере. Ваш компьютер вот он, перед глазами: стационарник, ноутбук, телефон... локальная машина. А другой компьютер «где-то там»: сервер, кластер, телевизор, чайник, роутер... удалённая машина.

Так вот...

SSH (secure shell) позволяет безопасно с одной машины управлять другой. Как протокол, SSH предоставляет инфраструктуру. А чтобы ей воспользоваться, реализация SSH предоставляет набор программ, например, ssh, scp и ssh-keygen.

До SSH были популярны Telnet и rsh. Они также предназначены для удалённого управления чем-нибудь, но не безопасны сегодня, особенно при выходе в глобальную сеть: их трафик не шифруется.

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

Подключение

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

В обоих случаях команда подключения одинакова.

ssh pupkin@192.168.0.1

Саму команду можно прочитать так: «подключиться к аккаунту pupkin на сервере с адресом 192.168.0.1». И имя аккаунта, и адрес сервера вам должен кто-то дать.

После команды вы увидите сообщение типа «добавить ли сервер в список и подключиться», тут вводим y (yes). Потом возможно несколько ситуаций.

  1. Просят пароль: вводите пароль от аккаунта pupkin на сервере.
  2. No matching key exchange found. Это хорошо: доступ по паролю закрыт, просто у вас ещё не сгенерирован ключ. Об этом ниже.
  3. Просто подключаетесь: вы увидите приветствие и промпт командной оболочки на сервере, например, $ pupkin@super-server:~. Вы внутри.

После первого успешного подключения у вас ещё появится файл ~/.ssh/known_hosts. Это список серверов и их ключей/подписей. По ним ваш ssh клиент проверяет подлинность входящих сообщений.

Ключи

В протоколе SSH для шифрования трафика используются ключи. Ваш пэ-ка использует пару ключей, и сервер использует пару ключей. Ключи нужны, чтобы подписывать каждое сообщение, которыми два компа обмениваются. Так они распознают (authenticate) друг друга и, в конце концов, доверяют. (Вы когда-нибудь просили записать кружок, когда друг попросил скинуть тыщу? Ну вот это оно.)

Чтобы подключаться по ключу, нужно два действия.

  1. Создать пару ключей на своей машине.
  2. Положить публичный ключ на удалённую машину.

Создаём ключи

Создаются ключи утилитой ssh-keygen.

ssh-keygen -t ed25519 -C 'pupkin desktop'
  • Enter file in which to save the key. Жмите Enter, пусть ключи сохраняются в стандартное место.
  • Enter passphrase. Просто жмите Enter.
  • Enter same passphrase again. Enter!

Что мы тут ввели?

  • -t ed25519. Используемый алгоритм шифрования. Ed25519 рекомендуется в 2025-ом, можете чекнуть, что рекомендует github. Ну или спросите админа: иногда сервер какие-то типы ключей не принимает.
  • -C 'pupkin desktop'. Это комментарий для человеков, он помещается в конец файла с публичным ключ. Нужен вам, чтобы отличать машины, с которых вы подключаетесь к серверу. Нужен админу, чтобы понимать, чей ключ лежит на сервере.

В итоге, в папке ~/.ssh/ появятся два файла.

  • ~/.ssh/id_ed25519. Это приватный ключ. Его вообще никому нельзя показывать, даже своему терминалу. Если у вас скоммуниздят или капитализируют приватный ключ, то смогут подключаться от вашего имени. Баг или фича 🤔
  • ~/.ssh/id_ed25519.pub. А это публичный ключ. Можно всем хвастаться его длиной.
cat ~/.ssh/id_ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJdD9cOqjBt+TIhWFEk+dNUtx0rsxV9uGE7S6+O1YnU3 pupkin desktop

Заметили комментарий? ☝️

Кладём публичный ключ на сервер

Чтобы сервер вас узнал (узнал ваш компьютер), нужно покласть ваш публичный ключ на сервер. Это должен делать админ: нужно ему скинуть файл ~/.ssh/id_чё-то-там.pub. (И надеяться, что он не покласт на вашу просьбу.)

Но, допустим, что у вас есть доступ по паролю, и вы хотите положить ключ сами. Тогда вы делаете так.

Закидываете файл с ключом на сервер (scp разберём позже).

scp ~/.ssh/id_ed25519.pub pupkin@192.168.0.1:~

Подключаетесь по паролю

ssh pupkin@192.168.0.1

Кладёте ключ в ~/.ssh/authorized_keys

# На сервере

mkdir -p ~/.ssh
cat ~/id_ed25519.pub >> ~/.ssh/authorized_keys
cat ~/.ssh/authorized_keys
rm ~/id_ed25519.pub

Что произошло?

  1. Создали папку ~/.ssh, если её ещё нет.
  2. Дописали публичный ключ в файл ~/.ssh/authorized_keys. Это список ключей, которым сервер доверяет для подключения к аккаунту pupkin. (Ну или вообще к тому, в чьём хоуме это лежит.) В списке может быть много ключей, так вы можете подключаться с разных устройств.
  3. Проверили, что ключ записался.
  4. Удалили ключ, чтоб больше не мешался.

Готово.

Ваша машина            Сервер
---------------------  ---------------------------------
~/.ssh/id_ed25519      /etc/ssh/ssh_host_ed25519
~/.ssh/id_ed25519.pub  /etc/ssh/ssh_host_ed25519.pub
~/.ssh/known_hosts     /home/pupkin/.ssh/authorized_keys

~/.ssh/config          /etc/ssh/ssh_config
                       /etc/ssh/sshd_config

Permission denied id_ed25519.pub

Если при подключении вы видите сообщение о том, что для какого-то ssh файла (например, ключа) нет доступа, то что-то не так с правами на этот файл. Чтоб всё работало, на локальной машине вы должны иметь права на чтение и запись всего, что лежит в ~/.ssh, а на сервере такие права должны быть у юзера pupkin. У меня такой косяк вспыл, когда я из-под рута положил себе ключ (владелец root, а не pupkin) плюс до меня на локальной машине что-то не моё было в ~/.ssh.

Перекидываем файлы

SCP (secure copy) это утилита для передачи файлов по ssh. Она обычно устанавливается вместе с ssh клиентом.

Синтаксис scp мимикрирует синтаксис cp.

scp ~/documents/some-data.tar pupkin@192.68.0.1:~/temporary/

Так локальный файл ~/documents/some-data.tar отправляется (копируется) на удалённую машину. В итоге на сервере появится файл /home/pupkin/temporary/some-data.tar.

Всё отличие от cp только во втором аргументе: прежде чем указать путь, необходимо указать адрес машины и поставить двоеточие.
  • После того, как вы ввели pupkin@192.68.0.1:~/ пожмакайте Tab. По-хорошему, должна сработать подсказка для пути.
  • С опцией -r вы можете отправлять целые папки.

Если вы не используете подключение по ключу, то scp будет на каждый чих требовать пароль. Используйте ключи!

Конфиг

Host mlcluster
  HostName 192.168.0.1
  User pupkin

Некст левел для упрощения жизни после настройки ключей это настройка конфига. Базовый конфиг вверху, его стандартное место это ~/.ssh/config.

Теперь pupkin может подключаться к серверу такой командой.

ssh mlcluster

А отправлять файлы вот так.

scp some-data.tar mlcluster:~/temporary/

Можно считать mlcluster shorthand-ом для pupkin@192.168.0.1: не надо запоминать юзернэйм и адрес сервера.

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

Клиенты

SSH-клиент (ssh client) это программа, которой вы пользуетесь, чтобы работать по SSH. Клиенты бывают разные, я пользовался только стандартным OpenSSH, из командной строки. На Windows его можно получить при установке git, на MacOS и Ubuntu он предустановлен. Но есть и графические клиенты, я слышал про PuTTY для Windows.

X11

X Window System (она же X, X11 или «иксы») позволяет работать с графическими программами: вы видите морду приложения, жмакаете кнопки, а реально она исполняется на сервере. Например, на сервере установлен gnuplot, и вы хотите построить график прям с сервера, не перекидывая его (или данные) на свою машину. Gnuplot поддерживает X11, но чтобы увидеть график, нужно подключиться к серверу с опцией -X.

ssh -X mlcluster
  • Если вы хотите всегда подключаться с X11, можно дописать строчку в конфиг. Но бывает и так, что на сервере по умолчанию включена поддержка X11.
  • Более громоздкие программы тоже умеют работать поверх X11, например, COMSOL Multiphysics.
  • Чтобы проверить, что X11 подключение поддерживается, запустите на сервере что-нибудь простое: xeyes или xclock. Появилось окошко? Значит всё ок.
  • Поддерживать иксы должен уметь и сервер, и ваш терминал. Например, Windows Terminal так не умеет (по крайней мере, из коробки).

Jupyter Notebook

Можно исполнять код через jupyter на сервере, а работать в своём браузере. Для этого...

На сервере запускаете jupyter в no-browser режиме.

# На сервере

jupyter notebook --no-browser --port=8080

Подключаетесь к серверу с пробросом портов.

# На локальной машине

ssh -L 8080:localhost:8080 mlcluster

Открываете в своём браузере ссылку, которую вам выдал jupyter.

GitHub / GitLab

Мне бывает удобно писать код на локальном компе, а запускать на удалённом. Чтобы не пользоваться scp, я пушу код со своей машины, а пулю на удалённой. Чтобы было удобно, можно на сервере сгенерировать ключи и публичный сообщить гитхабу / гитлабу.

IDE

Современные IDE, вроде продуктов Jetbrains или VSCode умеют подключаться по SSH на сервер. Как и с X11 вы таскаете файлы и комитите тут, а на самом деле всё происходит там. Довольно удобно. Знайте что такая опция есть.

В итоге

В итоге SSH не страшная штука. Команд, о которых я рассказал, реально достаточно для работы (полу)программиста. Вам стоит понимать, что такое ключи, и научиться пользоваться двумя-тремя командами. Попробуйте поработать с SSH через терминал (особенно, на *nix системах), а если надоест, проверьте, поддерживают ли ваши инструменты SSH.