IETFに『Secure shell over HTTP/3 connections』という提案仕様が提出されています。
これは、HTTP/3コネクション上でSSHを実行するプロトコルを定義しています。なお、"SSH3"という名称を仕様中で使用していますが、あくまで提案段階ですので今後変わる可能性もあります。
SSH3ではHTTP/3を使うことにより以下の特徴を持ちます
- QUICのメリットが享受できる(例えばIPアドレスが変わってもコネクションを維持できる)
- HTTPの認証方式をサポートする(Basic認証、OAuth 2.0、Signature HTTP Authentication Scheme)
- SSH通信の秘匿 (第三者からするとただのHTTP通信にみえる)
- エンドポイントの秘匿 (Signature HTTP Authentication Schemeを使うことで、そこでサービスが動いてることを隠せる)
- HTTPを使うことでロードバランサ(ホスト名やパスによるルーティング)が利用できる。
- ポートフォワーディング時に、パケットのreordaringが不要なQUIC DATAGRAM(RFC9221)が利用できる
HTTP/3のリクエスト・レスポンスにSSHのメッセージを乗っけるわけのではなく拡張CONNECTメソッド(RFC8441)をつかって、HTTP/3のコネクションをSSH3用に利用する形になります。なお、WebTransportの利用も検討されていますが、現状はHTTP/3を利用する仕様になっています(フォールバック先としてHTTP/2を利用)。
アーキテクチャ
SSHv2は下記のとおりです
SSH3では次のとおりになります
- 認証や、URL関連はHTTP/3レイヤで処理する
- トランスポートはQUICが担い、チャネルの機能はQUICレイヤにマッピングされる
プロトコル
通信の開始
エンドポイントに対してQUICコネクションを確立し、HTTP/3通信を開始します。その際に、QUIC DATAGRAMおよび、HTTP/3 拡張CONNECTメソッドをSETTINGSで有効にします。
拡張CONNECTメソッドを使ってSSH3通信を開始します。この時、:protocol疑似ヘッダには"ssh3"が指定されます。パスにはURIテンプレートでユーザ名を指定できるようになっています。
https://example.org:4443/ssh3?user={username} https://proxy.example.org:4443/ssh3{?username}
また、拡張CONNECTメソッドを送信する際にHTTPレイヤでの認証を実行します。先述の通り、認証方式としてBasic認証、OAuth 2.0、Signature HTTP Authentication Schemeなどが利用できます。
HTTP Basic認証では以下のような通信になります。
チャネル (ストリームの利用)
クライアント開始の双方向ストリームをチャネルと利用します。WebTransportと同様に、リクエストストリームとは別で新しく開始します。
双方向ストリームには最初に次のとおりに書き込まれます。
Channel { Signal Value (i) = 0xaf3627e6, Conversation ID (i), Channel Type Length (i) Channel Type (..) Maximum Message Size (i) SSH messages (..) }
Conversation IDとして、リクエストストリームとの紐づけを行う事ができます。それ以外はSSHで必要な値ですね。
チャネルが開設したあとはSSHv2同様のメッセージを投げることが出来ます。
実装
実装も公開されている
github.com