SSH

SSH — прикладной протокол для защищённого удалённого доступа. Через него можно открыть shell, выполнить одну команду, передать файл или построить туннель. Клиент проверяет подлинность сервера по host key, а сервер проверяет пользователя по паролю, публичному ключу или другому настроенному механизму.

Обычный TCP-порт — 22, но администратор может выбрать другой. Сам номер порта не является защитой.

Пара ключей

При аутентификации по ключу создаётся пара:

  • private key остаётся у владельца и никому не передаётся;
  • public key добавляется на сервер в ~/.ssh/authorized_keys.
ssh-keygen -t ed25519 -C "personal-laptop"

Passphrase защищает private key, если файл будет скопирован. Чтобы не вводить её при каждом соединении, ключ можно загрузить в ssh-agent.

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

Публичную часть можно показать или скопировать:

cat ~/.ssh/id_ed25519.pub
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@example.org

Подключение

ssh deploy@example.org
ssh -p 2222 deploy@example.org
ssh -i ~/.ssh/id_ed25519 deploy@example.org
ssh deploy@example.org 'systemctl status notes-site'

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

Host notes-server
    HostName example.org
    User deploy
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

После этого достаточно:

ssh notes-server

Файл конфигурации не должен содержать private key. Адрес публичного сервера может быть несекретным, но в JavaNotes я всё равно не публикую реальные адреса инфраструктуры.

Проверка сервера

При первом соединении клиент показывает fingerprint host key. Его нужно сверить по доверенному каналу. Слепое подтверждение любого нового ключа отключает важную часть защиты от атаки «человек посередине».

Известные ключи хранятся в ~/.ssh/known_hosts. Сообщение о смене ключа может означать переустановку сервера, смену адреса или атаку — сначала выясняю причину, а не удаляю запись автоматически.

Диагностика соединения:

ssh -v notes-server
ssh -vvv notes-server

В подробном выводе видно:

  • какой config применился;
  • какие ключи предложил клиент;
  • прошла ли проверка host key;
  • на каком этапе отказал сервер.

Ключи для разных направлений

Не обязательно использовать одну пару ключей везде:

  • личный ключ — для входа разработчика;
  • deploy key — для чтения конкретного GitHub-репозитория;
  • отдельный automation key — для workflow;
  • service account с минимальными правами — для развертывания.

Если automation key скомпрометирован, ограниченная учётная запись уменьшает последствия. Подключать CI сразу как root без необходимости не стоит.

SSH-туннели

Локальный port forwarding открывает локальный порт и передаёт соединение к ресурсу со стороны сервера:

ssh -L 15432:database.internal:5432 notes-server

После этого клиент обращается к localhost:15432, а SSH-сервер соединяется с database.internal:5432.

Remote forwarding (-R) открывает порт на удалённой стороне. Dynamic forwarding (-D) создаёт SOCKS proxy. Оба режима требуют отдельной оценки доступа: туннель способен обойти ожидаемую сетевую границу.

Права на файлы

OpenSSH отклоняет слишком открытые private keys:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
chmod 600 ~/.ssh/authorized_keys

Вопросы для собеседования

Почему серверу достаточно public key?

Клиент доказывает владение соответствующим private key с помощью криптографической подписи. Private key по сети не передаётся.

Чем host key отличается от user key?

Host key удостоверяет сервер перед клиентом. User key удостоверяет пользователя перед сервером.

Почему ssh-keyscan сам по себе не подтверждает подлинность?

Он получает ключ от того узла, который ответил сейчас. Без сверки fingerprint по доверенному каналу можно сохранить ключ атакующего.

Что даёт passphrase?

Шифрует private key на диске. Она не заменяет отзыв ключа и не защищает уже разблокированный agent.

Связанные заметки