SSH3: более быстрый и безопасный шелл с использованием HTTP/3

Источник: «SSH3: faster and rich secure shell using HTTP/3»
SSH3 — это полный пересмотр протокола SSH, накладывающий его семантику на механизмы HTTP.

В двух словах, SSH3 использует QUIC+TLS1.3 для создания безопасного канала и механизмы HTTP Authorization для аутентификации пользователей. Помимо прочего, SSH3 позволяет внести следующие улучшения:

Совет. Хотите быстро начать? Ознакомьтесь с тем, как установить SSH3. Вы научитесь настраивать SSH3-сервер и использовать SSH3-клиент.

SSH3 означает объединение SSH и H3.

SSH3 быстрее

Быстрее устанавливается сессия, а не пропускная способность! SSH3 обеспечивает значительно более быстрое создание сеанса, чем SSHv2. Создание новой сессии с помощью SSHv2 может занять от 5 до 7 циклов обхода сети, что хорошо заметно пользователю. SSH3 требуется всего 3 цикла. Задержка нажатия клавиш в текущем сеансе не изменилась.

Установление соединения SSH3 (вверху) VS SSHv2 (внизу) при пинге 100 мс в сторону сервера.
Установление соединения SSH3 (вверху) VS SSHv2 (внизу) при пинге 100 мс в сторону сервера.

SSH3 безопаснее

В то время как SSHv2 определяет собственные протоколы для аутентификации пользователей и установления безопасного канала, SSH3 опирается на надёжные и проверенные временем механизмы TLS 1.3, QUIC и HTTP. Эти протоколы уже широко используются для защиты критически важных приложений в Интернете, таких как электронная коммерция и интернет-банкинг.

В SSH3 уже реализованы распространённые методы аутентификации на основе пароля и открытого ключа (RSA и EdDSA/ed25519). Он также поддерживает новые методы аутентификации, такие как OAuth 2.0, и позволяет входить на ваши серверы с помощью учётных записей Google/Microsoft/Github.

Ваш публичный SSH3 сервер можно скрыть

Используя SSH3, вы можете избежать обычного стресса, связанного со сканированием и атаками на ваш SSH-сервер. Подобно секретным документам Google Drive, ваш SSH3-сервер может быть скрыт за секретной ссылкой и отвечать только на попытки аутентификации, сделанные с помощью HTTP-запроса к этой конкретной ссылке, как, например, в следующем примере:

ssh3-server -bind 192.0.2.0:443 -url-path <my-long-secret>

Заменив <my-long-secret>, скажем, на случайное значение M3MzkxYWMxMjYxMjc5YzJkODZiMTAyMjU, ваш SSH3-сервер будет отвечать только на попытки SSH3-соединения по URL https://192.0.2.0:443/M3MzkxYWMxMjYxMjc5YzJkODZiMTAyMjU, а на остальные запросы будет отвечать 404 Not Found. Поэтому злоумышленники и краулеры в Интернете не смогут обнаружить присутствие вашего SSH3-сервера. Они увидят только простой веб-сервер, отвечающий кодом 404 на каждый запрос.

SSH3 уже обладает широкими возможностями

SSH3 предоставляет новые возможности, которые не мог обеспечить протокол SSHv2.

Совершенно новые возможности

Реализованы знаменитые возможности OpenSSH

Реализация SSH3 уже предоставляет многие из популярных функций OpenSSH, поэтому если вы привыкли к OpenSSH, процесс перехода на SSH3 пройдёт без проблем. Вот список некоторых возможностей OpenSSH, которые также реализованы в SSH3:

Установка SSH3

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

Совет. SSH3 все ещё является экспериментальным и представляет собой плод исследовательской работы. Если вы боитесь публично разворачивать новый сервер SSH3, вы можете использовать функцию секретного пути SSH3, чтобы скрыть его за секретным URL.

Компиляция SSH3 из исходников

Для этого вам потребуется последняя версия Golang. Загрузите исходный код и скомпилируйте бинарные файлы, выполнив следующие действия:

git clone https://github.com/francoismichel/ssh3    # clone the repo
cd ssh3
go build -o ssh3 cli/client/main.go # build the client
CGO_ENABLED=1 go build -o ssh3-server cli/server/main.go # build the server, requires having gcc installed

Если у вас есть права root/sudo и вы хотите сделать ssh3 доступным для всех пользователей, вы можете напрямую скопировать двоичные файлы в /usr/bin:

cp ssh3 /usr/bin/ && cp ssh3-server /usr/bin

В противном случае вы можете просто добавить исполняемые файлы в переменную среды PATH, добавив следующую строку в конец файла .bashrc или подобного:

export PATH=$PATH:/path/to/the/ssh3/directory

Развёртывание SSH3 сервера

Прежде чем подключаться к хосту, необходимо развернуть на нем SSH3 сервер. В настоящее время демон SSH3 отсутствует, поэтому сейчас вам придётся запускать исполняемый файл ssh3-server в фоновом режиме с помощью screen или аналогичной утилиты.

Примечание. Поскольку SSH3 работает поверх HTTP/3, серверу необходим сертификат X.509 и соответствующий ему закрытый ключ. Если вы не хотите генерировать сертификат, подписанный реальным центром сертификации, вы можете сгенерировать самоподписанный сертификат с помощью скрипта generate_openssl_selfsigned_certificate.sh. Это даёт гарантии безопасности, схожие с механизмом хост-ключей SSHv2, с той же проблемой безопасности: вы можете быть уязвимы для атак типа "машина посередине" во время первого подключения к серверу. Использование настоящих сертификатов, подписанных публичными центрами сертификации, такими как Let's Encrypt, позволяет избежать этой проблемы.

Здесь показано использование исполняемого файла ssh3-server:

Usage of ./ssh3-server:
-bind string
the address:port pair to listen to, e.g. 0.0.0.0:443 (default "[::]:443")
-cert string
the filename of the server certificate (or fullchain) (default "./cert.pem")
-enable-password-login
if set, enable password authentication (disabled by default)
-generate-selfsigned-cert
if set, generates a self-self-signed cerificate and key that will be stored
at the paths indicated by the -cert and -key args (they must not already exist)
-key string
the filename of the certificate private key (default "./priv.key")
-url-path string
the secret URL path on which the ssh3 server listens (default "/ssh3-term")
-v verbose mode, if set

Следующая команда запускает публичный SSH3-сервер на порту 443 и отвечает на запросы новых сеансов по URL-адресу /ssh3:

ssh3-server -cert /path/to/cert/or/fullchain -key /path/to/cert/private/key -url-path /ssh3

Примечание. Как и в случае с OpenSSH, сервер должен быть запущен с правами root, чтобы входить в систему от имени других пользователей.

Авторизованные ключи и авторизованные идентификаторы

По умолчанию сервер SSH3 будет искать идентификаторы в файлах ~/.ssh/authorized_keys и ~/.ssh3/authorized_identities для каждого пользователя. ~/.ssh3/authorized_identities позволяет использовать новые идентификаторы, такие как OpenID Connect (oidc), о котором речь пойдёт ниже. Можно использовать популярные типы ключей, такие как rsa, ed25519, а также ключи в формате OpenSSH.

Использование SSH3 клиента

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

Здесь показано использование исполняемого файла ssh3:

Usage of ssh3:
-pubkey-for-agent string
if set, use an agent key whose public key matches the one in the specified path
-privkey string
private key file
-use-password
if set, do classical password authentication
-forward-agent
if set, forwards ssh agent to be used with sshv2 connections on the remote host
-forward-tcp string
if set, take a localport/remoteip@remoteport forwarding localhost@localport towards remoteip@remoteport
-forward-udp string
if set, take a localport/remoteip@remoteport forwarding localhost@localport towards remoteip@remoteport
-insecure
if set, skip server certificate verification
-keylog string
Write QUIC TLS keys and master secret in the specified keylog file: only for debugging purpose
-use-oidc string
if set, force the use of OpenID Connect with the specified issuer url as parameter
-oidc-config string
OpenID Connect json config file containing the "client_id" and "client_secret" fields needed for most identity providers
-do-pkce
if set, perform PKCE challenge-response with oidc
-v if set, enable verbose mode

Аутентификация с использованием приватного ключа

Вы можете подключиться к SSH3 серверу по адресу my-server.example.org, прослушивающему /my-secret-path, используя закрытый ключ, расположенный в ~/.ssh/id_rsa, с помощью следующей команды:

ssh3 -privkey ~/.ssh/id_rsa username@my-server.example.org/my-secret-path

Аутентификация с использованием приватного ключа на основе агента

SSH3 клиент работает с агентом OpenSSH и использует классическую переменную среды SSH_AUTH_SOCK для связи с этим агентом. Как и в случае с OpenSSH, SSH3 выдаёт список ключей, предоставленных агентом SSH, и по умолчанию подключается с использованием первого ключа, прослушанного агентом. Если вы хотите указать конкретный ключ для использования с агентом, вы можете либо указать приватный ключ напрямую с помощью аргумента -privkey, как описано выше, либо указать соответствующий публичный ключ с помощью аргумента -pubkey-for-agent. Это позволяет выполнять аутентификацию в ситуациях, когда только агент имеет прямой доступ к приватному ключу, а у вас есть доступ только к публичному ключу.

Аутентификация на основе пароля

Хотя это и не рекомендуется, вы можете подключиться к серверу с помощью паролей (если это явно разрешено на ssh3-server) с помощью следующей команды:

ssh3 -use-password username@my-server.example.org/my-secret-path

Установление сессии на основе конфигурации

ssh3 анализирует вашу OpenSSH конфигурацию. В настоящее время он обрабатывает только параметры Hostname, User, Port и IdentityFile. Допустим, у вас есть следующие строки в конфигурации OpenSSH, расположенной в ~/.ssh/config:

Host my-server
HostName 192.0.2.0
User username
IdentityFile ~/.ssh/id_rsa

Аналогично тому, как это делает OpenSSH, следующая команда ssh3 соединит вас с SSH3 сервером, работающим на 192.0.2.0 на UDP-порту 443, используя аутентификацию с публичным ключом и приватным ключом, расположенным в .ssh/id_rsa:

ssh3 my-server/my-secret-path

Если вы не хотите использовать SSH3 на основе конфигурации, вы можете прочитать разделы ниже, чтобы узнать, как использовать параметры CLI для ssh3.

Аутентификация OpenID Connect (пока экспериментальная)

Эта функция позволяет подключаться с помощью внешнего провайдера идентификации, например, провайдера вашей компании или любого другого провайдера, реализующего стандарт OpenID Connect, например, Google Identity, Github или Microsoft Entra. Процесс аутентификации показан в GIF ниже.

Безопасное соединение без закрытого ключа с помощью аккаунта Google.
Безопасное соединение без закрытого ключа с помощью аккаунта Google.

Способ подключения к поставщику идентификационных данных настраивается в файле ~/.ssh3/oidc_config.json. Ниже приведён пример файла config.json для использования с учётной записью Google. Этот файл конфигурации представляет собой массив и может содержать несколько конфигураций поставщиков идентификационных данных.

[
{
"issuer_url": "https://accounts.google.com",
"client_id": "<your_client_id>",
"client_secret": "<your_client_secret>"
}
]

Это может измениться в будущем, но в настоящее время, чтобы заставить эту функцию работать с вашим аккаунтом Google, вам нужно настроить новое экспериментальное приложение в консоли Google Cloud и добавить вашу электронную почту в качестве авторизованного пользователя. В результате вы получите client_id и client_secret, которые затем сможете задать в файле ~/.ssh3/oidc_config.json. На стороне сервера нужно просто добавить следующую строку в ~/.ssh3/authorized_identities:

oidc <client_id> https://accounts.google.com <email>

В настоящее время мы рассматриваем возможность убрать необходимость указания client_id в файле authorized_identities в будущем.

Дополнительные материалы

Предыдущая Статья

Основы TypeScript: Сетеры/Гетеры, protected, private/public/static

Следующая Статья

Value Objects в PHP 8: Создание лучшего кода