
Быстрый, безопасный протокол оболочки, построенный на HTTP/3, QUIC и TLS 1.3. Поддерживает OAuth2, OpenID Connect и классическую аутентификацию SSH с пробросом UDP-портов и возможностями скрытого сервера.
[!NOTE] SSH3, вероятно, сменит название. Он по-прежнему использует протокол SSH Connection Protocol (RFC4254), работающий поверх HTTP/3 Extended connect, но требуемые изменения слишком масштабны и слишком далеки от философии популярных реализаций SSH, чтобы рассматривать их для интеграции. Черновик спецификации уже переименован ("Remote Terminals over HTTP/3"), но нам нужно время, чтобы подобрать хорошее постоянное название.
SSH3 — это полный пересмотр протокола SSH, отображающий его семантику на механизмы HTTP. Он появился в результате нашей исследовательской работы, и мы (исследователи) недавно предложили его в качестве Internet-Draft (draft-michel-remote-terminal-http3-00).
По сути, SSH3 использует QUIC+TLS1.3 для установки защищённого канала и механизмы HTTP Authorization для аутентификации пользователей. Среди прочего, SSH3 обеспечивает следующие улучшения:
[!TIP] Хотите быстро начать? Узнайте, как установить SSH3. Вы научитесь настраивать SSH3-сервер и использовать SSH3-клиент.
Быстрее — для установления сеанса, а не пропускной способности! SSH3 обеспечивает значительно более быстрое установление сеанса, чем SSHv2. Установление нового сеанса с SSHv2 может занимать от 5 до 7 сетевых круговых задержек, что легко заметно пользователю. SSH3 требуется всего 3 круговые задержки. Задержка нажатия клавиш в активном сеансе остаётся неизменной.
SSH3 (сверху) VS SSHv2 (снизу): установление сеанса при ping 100 мс до сервера.
В то время как SSHv2 определяет собственные протоколы для аутентификации пользователей и установки защищённого канала, SSH3 полагается на надёжные и проверенные временем механизмы TLS 1.3, QUIC и HTTP. Эти протоколы уже широко используются для защиты критически важных приложений в Интернете, таких как электронная коммерция и интернет-банкинг.
SSH3 уже реализует распространённые методы аутентификации на основе пароля и открытого ключа (RSA и EdDSA/ed25519). Он также поддерживает новые методы аутентификации, такие как OAuth 2.0, и позволяет входить на ваши серверы, используя учётные записи Google/Microsoft/Github.
Хотя SSH3 демонстрирует потенциал для более быстрого установления сеанса, он всё ещё находится на ранней стадии доказательства концепции. Как и для любого нового сложного протокола, требуется экспертная криптографическая проверка в течение длительного времени, прежде чем можно будет сделать обоснованные выводы о безопасности.
Мы разрабатываем SSH3 как проект с открытым исходным кодом, чтобы облегчить обратную связь и анализ со стороны сообщества. Однако мы пока не можем рекомендовать его для использования в производственных системах без дополнительного рецензирования. Пожалуйста, сотрудничайте с нами, если у вас есть соответствующий опыт!
Учитывая текущее состояние прототипа, мы рекомендуем тестировать SSH3 в изолированных средах или частных сетях. Имейте в виду, что подключение экспериментальных серверов напрямую к Интернету может создать риски до проведения тщательной проверки безопасности.
Хотя скрытие серверов за секретными путями имеет потенциальные преимущества, это не отменяет необходимости строгого анализа уязвимостей перед выходом в продакшн. Мы воодушевлены будущими возможностями 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-сервера за секретным URL может снизить влияние атак сканирования, но никогда не заменит классические механизмы аутентификации. Секретная ссылка должна использоваться только для того, чтобы ваш хост не был обнаружен. Знание секретного URL не должно предоставлять кому-либо доступ к вашему серверу. Используйте классические механизмы аутентификации, описанные выше, для защиты вашего сервера.
SSH3 предоставляет новые возможности, которые не мог предоставить протокол SSHv2.
Эта реализация SSH3 уже предоставляет многие популярные функции OpenSSH, поэтому если вы привыкли к OpenSSH, процесс перехода на SSH3 будет плавным. Вот список некоторых функций OpenSSH, которые также реализует SSH3:
~/.ssh/authorized_keys на сервереknown_hosts, когда X.509 сертификаты не используютсяssh-agent для аутентификации по открытому ключу-proxy-jump). Если A — SSH3-клиент, а B и C — SSH3-серверы, вы можете подключиться от A к C, используя B в качестве шлюза/прокси. Прокси использует UDP-пересылку для пересылки QUIC-пакетов от A к C, поэтому B не может расшифровать трафик A<->C SSH3.~/.ssh/config на клиенте и обработка опций конфигурации Hostname, User, Port и IdentityFile (остальные опции пока игнорируются). Также парсит новый параметр UDPProxyJump, который работает аналогично ProxyJump в OpenSSH.Помогите нам ответственно развивать SSH3! Мы приглашаем компетентных исследователей в области безопасности проверить нашу кодовую базу и предоставить обратную связь. Также свяжите нас с соответствующими органами стандартизации, чтобы со временем продвигать SSH3 через формальные процессы IETF/IRTF.
При совместной помощи мы надеемся итеративно улучшать SSH3 до готовности к безопасному использованию в продакшне. Но мы не можем достоверно делать окончательные заявления о безопасности без свидетельств обширной экспертной криптографической проверки и принятия уважаемыми авторитетами в области безопасности. Давайте работать вместе, чтобы реализовать возможности SSH3!
Вы можете либо загрузить последние релизные бинарники,
установить с помощью go install, либо скомпилировать эти бинарники самостоятельно из исходного кода.
[!TIP] SSH3 всё ещё экспериментальный и является плодом исследовательской работы. Если вы боитесь публично разворачивать новый SSH3-сервер, вы можете использовать функцию секретного пути SSH3, чтобы скрыть его за секретным URL.
go install github.com/francoismichel/ssh3/cmd/...@latest
Вам понадобится последняя версия Golang. Загрузка исходного кода и компиляция бинарников производятся следующим образом:
git clone https://github.com/francoismichel/ssh3 # клонировать репозиторий
cd ssh3
go build -o ssh3 cmd/ssh3/main.go # собрать клиент
CGO_ENABLED=1 go build -o ssh3-server cmd/ssh3-server/main.go # собрать сервер, требуется установленный gcc
Если у вас есть права 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-server в фоне
с помощью screen или аналогичной утилиты.
[!NOTE] Поскольку SSH3 работает поверх HTTP/3, серверу требуется X.509-сертификат и соответствующий закрытый ключ. Публичные сертификаты можно автоматически сгенерировать для вашего публичного доменного имени через Let's Encrypt, используя аргумент командной строки
-generate-public-certна сервере. Если вы не хотите генерировать сертификат, подписанный реальным удостоверяющим центром, или у вас нет публичного доменного имени, вы можете самозаверяющий сертификат, используя аргумент-generate-selfsigned-cert. Самозаверяющие сертификаты обеспечивают аналогичные гарантии безопасности, как механизм ключей хоста в 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")
-key string
the filename of the certificate private key (default "./priv.key")
-enable-password-login
if set, enable password authentication (disabled by default)
-generate-public-cert value
Automatically produce and use a valid public certificate usingLet's Encrypt for the provided domain name. The flag can be used several times to generate several certificates.If certificates have already been generated previously using this flag, they will simply be reused without being regenerated. The public certificates are automatically renewed as long as the server is running. Automatically-generated IP public certificates are not available yet.
-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)
-url-path string
the secret URL path on which the ssh3 server listens (default "/ssh3-term")
-v verbose mode, if set
-version
if set, displays the software version on standard output and exit
Следующая команда запускает публичный SSH3-сервер на порту 443 с действительным публичным сертификатом Let's Encrypt
для домена my-domain.example.org и отвечает на запросы новых сеансов по пути URL /ssh3:
ssh3-server -generate-public-cert my-domain.example.org -url-path /ssh3
Если у вас нет публичного доменного имени (только IP-адрес), вы можете либо использовать существующий сертификат
для вашего IP-адреса с помощью аргументов -cert и -key, либо сгенерировать самозаверяющий сертификат с помощью
аргумента -generate-selfsigned-cert.
Если у вас есть существующие сертификаты и ключи, вы можете запустить сервер следующим образом, чтобы использовать их:
ssh3-server -cert /path/to/cert/or/fullchain -key /path/to/cert/private/key -url-path /ssh3
[!NOTE] Как и в OpenSSH, сервер должен быть запущен с правами root для входа в систему от имени других пользователей.
По умолчанию SSH3-сервер ищет идентификаторы в файлах ~/.ssh/authorized_keys и ~/.ssh3/authorized_identities для каждого пользователя.
~/.ssh3/authorized_identities позволяет использовать новые идентификаторы, такие как OpenID Connect (oidc), описанные ниже.
Популярные типы ключей, такие как rsa, ed25519 и ключи в формате OpenSSH, могут использоваться.
Как только у вас запущен 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
-proxy-jump string
if set, performs a proxy jump using the specified remote host as proxy
-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 [email protected]/my-secret-path
SSH3-клиент работает с агентом OpenSSH и использует стандартную переменную окружения SSH_AUTH_SOCK для
взаимодействия с этим агентом. Как и в OpenSSH, SSH3 перечисляет ключи, предоставленные SSH-агентом,
и по умолчанию подключается, используя первый ключ из списка агента.
Если вы хотите указать конкретный ключ для использования с агентом, вы можете либо указать закрытый ключ
напрямую с помощью аргумента -privkey, как указано выше, либо указать соответствующий открытый ключ с помощью
аргумента -pubkey-for-agent. Это позволяет аутентифицироваться в ситуациях, когда только агент имеет
прямой доступ к закрытому ключу, но у вас есть доступ только к открытому ключу.
Хотя это не рекомендуется, вы можете подключиться к вашему серверу, используя пароли (если они явно включены на ssh3-server),
с помощью следующей команды:
ssh3 -use-password [email protected]/my-secret-path
ssh3 парсит ваш конфигурационный файл OpenSSH. В настоящее время он обрабатывает только опции Hostname, User, Port и IdentityFile из OpenSSH.
Также добавляется новая опция, используемая только SSH3, такая как URLPath или UDPProxyJump. URLPath позволяет опустить секретный путь URL в вашей
команде SSH3. UDPProxyJump позволяет выполнить прокси-прыжок SSH3 и имеет то же значение, что и аргумент командной строки -proxy-jump.
Допустим, у вас есть следующие строки в вашем конфигурационном файле OpenSSH, расположенном в ~/.ssh/config:
IgnoreUnknown URLPath
Host my-server
HostName 192.0.2.0
User username
IdentityFile ~/.ssh/id_rsa
URLPath /my-secret-path
Как и в OpenSSH, следующая команда ssh3 подключит вас к SSH3-серверу, работающему на 192.0.2.0 на UDP-порту 443, с использованием аутентификации по открытому ключу с закрытым ключом, расположенным в .ssh/id_rsa:
ssh3 my-server/my-secret-path
Если вы не хотите использовать SSH3 на основе конфигурации, вы можете прочитать разделы ниже, чтобы узнать, как использовать параметры командной строки ssh3.
Эта функция позволяет вам подключаться, используя внешнего поставщика идентификации, например, вашей компании или любого другого поставщика, реализующего стандарт OpenID Connect, такого как Google Identity, Github или Microsoft Entra. Процесс аутентификации показан на GIF-изображении ниже.
Безопасное подключение без закрытого ключа с использованием учётной записи 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 и добавить ваш email в качестве авторизованного пользователя.
Это предоставит вам client_id и client_secret, которые затем можно указать в вашем ~/.ssh3/oidc_config.json. На стороне сервера вам просто нужно добавить следующую строку в ваш ~/.ssh3/authorized_identities:
oidc <client_id> https://accounts.google.com <email>
В настоящее время мы рассматриваем возможность удаления необходимости указывать client_id в файле authorized_identities в будущем.
Часто бывает так, что к некоторым SSH-хостам можно получить доступ только через шлюз. SSH3 позволяет выполнить прокси-прыжок, аналогично тому, что предлагает OpenSSH. Вы можете подключиться от A к C, используя B в качестве шлюза/прокси. B и C должны быть запущены как работающие SSH3-серверы. Это работает путём установки UDP-пересылки на B для пересылки QUIC-пакетов от A к C. Соединение от A к C, таким образом, является полностью сквозным, и B не может расшифровать или изменить трафик SSH3 между A и C.