HTTP/3コネクション上でSSHを実行するSSH3プロトコル

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