新しいQUICのマルチパス拡張の仕様

Multipath-TCPのように、複数の経路を使用したQUIC通信を可能にする『Multipath Extension for QUIC』という提案仕様が出されています。これにより、例えばWi-Fiとキャリア回線を両方使った通信も行えるようになります。

QUICのマルチパス機能は、長らく議論されており、複数の提案仕様が出されていました。それらについては、去年書いた記事を御覧ください。
asnokaze.hatenablog.com

今回提出された、『Multipath Extension for QUIC』は、いままで出てきた提案仕様に共通するコア機能にフォーカスした仕様となっています。

f:id:ASnoKaze:20211114234421p:plain
(IETF 112 の発表スライド PDF)

なお、この提案はIETF 112でも議論になり、この仕様を元に議論を進めていくコンセンサスが得られそうです。

設計

Multipath Extension for QUIC』の基本的な設計は次のとおりです。

  • RFC 9000 QUICv1の仕組みを可能な限り再利用する。特に、コネクションマイグレーションのパス検証(path validation)の仕組みを利用する
  • パケットはQUICv1と同じパケットヘッダー形式を使用する
  • 輻輳制御、RTT測定、PMTU検出はパスごとに行う。(各パスの利用スケジューラについてドキュメントでは定義しない)
  • パスは送信元/送信先IP・送信元/送信先ポートの4タプルごとに一つとなる。なお、パスごとにコネクションIDは異なるものが使用される(QUICv1の通り)

複数パスの利用は、コネクションマイグレーションと同じ手順を踏みます。このときにコネクションをマイグレーションするのではなく、同時に利用できるようになるのが大きな違いです。

その他に大きな違いは、次のとおりです。

  • パスを破棄する PATH_ABANDONフレームの定義
  • シングルパケット番号空間/マルチパケット番号空間の定義

- マルチパケット番号空間利用時の、ACK_MPフレームの利用

順番に見ていきましょう。

(この提案仕様では、複数パス上でやりとりするパケットを管理するのに、シングルパケット番号空間/マルチパケット番号空間と2種類の方法を定義しています。どちらか一つになることを想定していますが、実際に試しながら議論を進めていくようです)

パケット番号空間

先述の通り、シングルパケット番号空間/マルチパケット番号と二種類の管理方法があります。

シングルパケット番号空間

f:id:ASnoKaze:20211115001127p:plain
(中間会議にスライド)

複数のパスで単一のパケット番号空間を利用します。このとき、QUICv1と同じACKフレームを利用します(どのパスで受け取ったパケットに対して、どのパスでもACKを返せます)

マルチパケット番号空間

f:id:ASnoKaze:20211115001906p:plain
(中間会議にスライド)

複数のパスごとに独立したパケット番号空間を持ちます。パスをしてしてACKを返すことが出来る、ACK_MPフレームを用います(ACK_MPを送るパスと、ACK_MPの対象となるパスは異なって良い)

f:id:ASnoKaze:20211115002510p:plain

通常のACKフレームとは異なり、パケット番号空間を示すPacket Number Space Identifierがある。Packet Number Space IdentifierはコネクションIDはによって指定される。

パケット暗号時の、ナンスがユニークになるように暗号処理にQUICv1から処理が少し変更される。

ネゴシエーション

クライアントとサーバはお互いにマルチパス拡張をサポートしているかまず確認します。そのために、QUICのハンドシェイク時にトランスポートパラメータとしてenable_multipathを送信します。

enable_multipathの値は

  • 0: サポートしていない
  • 1: シングルパケット番号空間のみサポート
  • 2: マルチパケット番号空間のみサポート
  • 3: シングルパケット番号空間/マルチパケット番号空間 両方をサポート

クライアントが両方サポートしている場合は、サーバ側がどちらを使うか選択します。

また、active_connection_id_limitパラメータを使うことで、同時に使用するパスの数も制限することが出来ます。


新しいパスの利用開始

新しいパスを利用するクライアントは、PATH_CHALLENGEおよびPATH_RESPONSEを利用しパス検証を行います。

検証が成功すると、非プローブの1-RTTパケットを送信できるようになります。

パスの利用終了

パスの利用を終了するのには、PATH_ABANDONフレームを送信する (終了するパスとはことなるパスで送信しても良い)
f:id:ASnoKaze:20211115002920p:plain

Path Identifierで終了するパスを指定する。指定は、コネクションIDで指定するか、送信しているパスが対象であることを伝える事ができる。

新しいHTTPメソッド、QUERYメソッドの仕様

新しいHTTPメソッドを定義する「The HTTP QUERY Method」という提案仕様が議論されています。

もともとは、SEARCHメソッドという呼び名が候補としてあげられていましたが、長い議論ののち、一旦QUERYと呼ぶ方向となっております。最終的なFixについては、この draft 02の公開とともに改めてコンセンサスを求めた後に行われます。

QUERYメソッド

「GETリクエストにボディを付けたいという」という質問は長らく有りました。しかし、GETやHEADリクエストでボディをつけることは非推奨となっています (参考URL)。

そのような要望のなかで、リクエストでボディを含められる冪等性の保証された新しいHTTPメソッドが検討されました。それがQUERYメソッドです。冪等性があるため、ブラウザやProxyは自動でリトライすることができます。(なお、POSTはセマンティクス上冪等ではない)

(脱線しますが、HTTPセマンティクスの用語としてはボディではなくコンテンツと呼ぶのが正しい。詳しくは「HTTPセマンティクス仕様の改訂版」参照)

また、GETでURLパラメータに含めるのと異なり、URLエンコードも不要ですし、実装によるURL長の制限に引っかかることも有りません。

キャッシュ

QUERYメソッドは通常のキャッシュする際に、ボディ(コンテンツ)をキャッシュのキーに加えます

リクエスト例

QUERY /contacts HTTP/1.1
Host: example.org
Content-Type: example/query
Accept: text/csv

select surname, givenname, email limit 10

レスポンス例

HTTP/1.1 200 OK
Content-Type: text/csv

surname, givenname, email
Smith, John, john.smith@example.org
Jones, Sally, sally.jones@example.com
Dubois, Camille, camille.dubois@example.net

0.0.0.0/8のIPアドレスなどを利用可能にする提案仕様

IPv4アドレスの枯渇すると言われ続けております。

The IPv4 unicast extensions project」では、予約されているIPアドレスなどをユニキャストアドレスとして利用可能にし、4億1900万ものIPアドレスを追加することを謳っています。

実際、IETFで予約済みアドレスをユニキャストアドレスとして使用できるようにする提案を提出しています。

単に提案するだけでなく、歴史的経緯の説明が書かれています。また、問題なく利用できるかの調査も行っており、例えば各種OSやネットワーク機器の実装の調査、クラウドサービスなどで内部的利用の調査も行っています。

IETF 112で発表があるようなので簡単に予習をしておく。

発表スライド(PDF)もあわせて参照ください。

なお、IETFへの提案は誰でも行うことが出来き、あくまで提案であるということに注意してください。ですので、すぐにIPアドレスの運用が変わるということはなく、オープンな場で議論が進められます。(ご意見のお持ちの方はもちろん参加できます)

240.0.0.0/4

240.0.0.0/4は、Class Eや実験用アドレスレンジとして予約されているIPアドレスです。このレンジをユニキャストアドレスとして使用できるようにします。

このIPアドレスを、Linux, Android, macOS, iOS といったOSではユニキャストアドレスとして使用できるようです。ただし、Windowsではブロックされると述べています。

GCPのドキュメント(URL)では、VPCのサブネットとしてこのレンジが利用できると書かれています。

0.0.0.0/8

0.0.0.0/8は、仕様上は、RFC 792で自動構成用に予約されていました。これはRFC 1122によって廃止され、今日まで何も予約されていません。DHCPでのみ0.0.0.0が利用されています。このレンジをユニキャストアドレスとして使用できるようにします。

ユニキャストアドレスとして使うことに関して、提案仕様の中でLinuxについては『この文書で指定されている動作は、2019年7月にリリースされたバージョン5.2以降のLinuxカーネルによって実装されています。』と書かれています。

127.1.0.0 ~ 127.255.255.255

IPv6ループバックアドレスは一つしかありませんが、IPv4では 16,777,216個も確保されています。127.0.0.0/16をループバックアドレス用に利用し、127.1.0.0 ~ 127.255.255.255をユニキャストアドレスとして使用できるようにします。

ユニキャストアドレスとして使うことに関して、提案仕様の中で『LinuxおよびFreeBSDカーネルへの小さなパッチが必要』と述べています。

IPアドレスホスト部が0のもの

例えば、93.184.216.0/24サブネットの中の93.184.216.0をユニキャストアドレスとして使用できるようにします。このアドレスは1980年代の古い実装との互換性のために使用されてこなかったと述べています。

現在では、LinuxFreeBSDではデフォルトでユニキャストアドレスとして扱うようです。

おわりに

冒頭にも書きましたが、IETFへの提案は誰でも行うことが出来き、これは議論の始まりに過ぎません。これによりすぐにIPアドレスの運用が変わるということはないかと思います。

一方で、実装やインターネット通信上で多くの懸念を持たれる方もいると思います。提案者はコメントを募集されておりますので、コンタクトを取られると良いと思います。議論は IETF int-area メーリングリストで行われます (URL)。

匿名かつ検証可能なPrivate Access Tokensの提案仕様

Private Access Tokens」という提案仕様が、Google, Apple, Fastly, Cloudflareの方々らの共著でIETFに提出されています。なお、すでに実装が進められているそうです。

この「Private Access Tokens」の一つのモチベーションに次のようなものがあります。

昨今、プライバシー保護の要求は高まっており、ユーザのIPアドレスを秘匿する、iCloud Private RelayやOblivious HTTPといった技術が出てきています。いままではIPアドレスベースでアクセスレートリミットを行っていましたが、

そのような環境でも、アクセスのレートリミットを設けたいというというのが一つの目的です。

それを、追加のユーザインタラクション無しに、かつユーザをトラッキングできないような匿名なトークンで行うというのがPrivate Access Tokens」です。

IETF 112のSec Dispatch WGのセッションで発表(Agenda)があるようですが、簡単に予習しておきます。(追記: 発表資料スライド)

なお、RSAブラインド署名やHPKEなど、使われている暗号処理はまではまだ理解できてないので概要だけ。

仕様の内容

この仕様では、大きく分けて2つのことが書かれています。

  • Private Access Tokensの発行する手順 (Issuance Flow)
  • Private Access Tokensを使用する手順 (Challenge/Response Flow)

また、各手順に置いて、登場人物がどのようなやり取りをするのかが定義されてます。

登場人物

  • Client: IssuerにPrivate Access Tokensをリクエストし取得する。Originのサービスにアクセスするために、Private Access Tokensをオリジンに提示する。
  • Mediator: IPアドレスやアカウント名などの情報をも使用してClientを認証する。ClientをIssuerに対して匿名化し、匿名化されたClientとIssuerのやりとりを中継する。
  • Issuer: Originに代わって匿名化されたClientにPrivate Access Tokensを発行する。OriginをMediatorに対し匿名化し、Originのポリシーを適用する。
  • Origin: ClientをチャレンジでIssuerにリダイレクトする。そして、クライアントからのレスポンスとしてPrivate Access Tokensを受け取る。Clientにコンテンツやサービスを提供する。

IssuerはOriginによって選択されますが、MediatorはClientによって選択されます。

IssuerはOriginがClientに課したいポリシーを知っており、Originに代わりそれらを課します(ポリシーは、クライアントごとに10アクセスに制限すると言った例)。なお、IssuerへアクセスではClientの情報は匿名化されているため、本当のユーザはわかりません。

各登場人物は処理が必要な情報だけしか知りえません。共謀しないとい前提で、各登場人物がどのような情報を知りえるかは仕様の方を御覧ください。

大雑把な流れ

大雑把な流れは以下のとおりです。赤字がChallenge/Response Flowになります。
f:id:ASnoKaze:20211107235145p:plain

  • ClientがOriginにアクセスする
  • Originは、Challenge/Response Flowの一環としてOriginからIssuerにリダイレクトを行う。このとき、WWW-AuthenticateヘッダでTokenChallenge及び、Issuance Flowに必要な情報をClientに通知します
  • Clientは、TokenChallengeをブラインド処理し、Issuer固有の鍵で暗号化した上で、Mediatorを介してIssuerにPrivate Access Tokensを要求します。
  • Issuerは、復号を行い、各種検証を行った後、ポリシーの適応とPrivate Access Tokensの発行を行います。Mediatorを介してClientに渡されます。
  • ClientはChallenge/Response Flowの一環として、ResponseをOriginに送信します。

感想

Issuance Flowの細かいところ難しい...

クレデンシャルを安全に共有する「Secure Credential Transfer」の仕様

AppleGoogle方らによって「Secure Credential Transfer」という提案仕様が、IETFのDispatch WGに提出されています。

この仕様は、イントロダクションにも書かれている通り、iOSAndroidといったプラットフォームの異なるデバイス間でクレデンシャルを共有する方法を定めています。

実際にそういったデバイスを作ってる方々からこのような提案が出てくるというのは興味深いところです。

Secure Credential Transferの概要

この「Secure Credential Transfer」では、リレーサーバというWebアプリケーションを導入し、SenderからReceiverにクレデンシャルを共有します。

共有方法には2つの手順があり

  • ステートレス: 単一のクレデンシャルのみ送信できる
  • ステートフル: 複数のデータを送信できる。ただし手順が長い。

どちらの手順でも、SenderとReceiverは、リレーサーバ上にメールボックスを作成し操作します。メールボックスは仕様上の用語であり、Eメールは関係なく、WebのAPIを介し読み書きを行います。メールボックはそれぞれユニークなURLをもちます (例: https://relay.example/m/1234567890)

SenderとReceiverが、リレーサーバとやりとりする、ときに使用するAPIに関してもこの仕様で定義されます。

また仕様上は、Provisioning Partnersという用語が出てきます。これは、デバイス上でProvisioning Infoを取り扱う主体(エンティティ)を指す用語です。

ステートレス ワークフロー

簡単なステートレスのワークフローで簡単な流れを紹介します。

f:id:ASnoKaze:20211024012313p:plain

  • Senderは、Secretを用いてクレデンシャル情報をProvisioning Infoとして暗号化します。
  • Senderは、リレーサーバのCreateMailbox APIを利用して、メールボックスを作成します
  • リレーサーバは、作成したメールボックスのURLを返します
  • Senderは、得られたメールボックスのURLとSecretを直接Receiverに送ります。仕様上では例として、次のものが上げられています。SMS、電子メール、iMessage。
  • Receiverは、URLとSecretの療法を用いて、Relayサーバーから暗号化されたProvisioning Infoを受け取ります。
  • Receiverはクレデンシャルを取り出した後、該当のメールボックスを削除します

なお、このやり取りの中で、メールボックスは特定のSenderとReceiverに紐付けられます。SenderとReceiverは自身のDevice Claim(トークン)を登録して、それを用いてリレーサーバのAPIを叩きます。そのため、Device Claimが登録された後は、ほかのデバイスはそのメールボックスを利用できません。

なおSenderからReceiverへSecretを送る際、誤った相手と共有してしまうと問題になります。その旨Security Considerationsにも記載されています。

こんご

この仕様については、Dispatch WGのメーリングリストに投稿されています。来月行われるIETF 112で、どのように標準化を進めるか議論されることでしょう。

DNS HTTPSレコードを使用したWebSocketサポートの通知

以前紹介した通り、HTTP/3やECHに対応していることをDNSで通知するためのHTTPSレコードというものがあります。
asnokaze.hatenablog.com

このHTTPSレコードで、WebSocketの対応についても通知できるようにする「Advertising WebSocket support in the HTTPS resource record」という提案仕様がMozillaの方より提出されています。

モチベーション

これは、特にHTTP/2やHTTP/3でWebSocketを使う際にメリットがあります。

それぞれの動作については以前書いたとおりです

既存のWebSocket over HTTP/2とWebSocket over HTTP/3では、拡張CONNECTメソッドを用いてストリームをWebSocket通信用に切り替えます。仕様上、この拡張CONNECTメソッドをクライアントが使うためには、サーバがこの拡張をサポートしていることを知る必要があります。

サーバが拡張CONNECTメソッド対応していることは、HTTP/2, HTTP/3コネクションが確立した後にサーバから送られてくるSETTINGSフレームで知ることが出来ます。つまり、クライアントは、このSETTINGSフレームの受信を待ってCONNECTメソッドのリクエストを送ることになります。

Advertising WebSocket support in the HTTPS resource record」では、HTTPSレコードにWebSocket (拡張CONNECTメソッド)への対応が記述されるため、SETTINGSフレームの受信を待つ必要がありません。

HTTPSレコードの拡張

HTTPSレコードの仕様で定義されるSvcParamKeyとしてextended-connectキーを新しく定義します。この、extended-connectがある場合はalpnとしてh2かh3を指定する必要があります

おそらくこんな感じ

   simple.example. 7200 IN HTTPS 1 . alpn=h3 extended-connect ...

おまけ

似たようなモチベーションで検討されている仕様があります。

TLS ALPSという仕組みがChromeでは実装されています。これも、TLSハンドシェイク中にHTTPレイヤのSETTINGSを送信可能にします。
asnokaze.hatenablog.com

HTTP/2の改定版仕様の変更点について

2015年に標準化された、RFC7540 HTTP/2 の改定作業が進められています。

作業中のドキュメントは「http2bis」として公開されている。

現時点で含まれている変更点を見ていきます。なお、今後も変更が入る可能性はあります。

HTTPセマンティクス仕様を参照

もともとのHTTP/2の仕様では、HTTPメッセージのセマンティクスについて既存のHTTP/1.1の仕様を参照していました。しかし、HTTP/1.1の仕様はHTTPセマンティクス仕様に分離整理されました。

f:id:ASnoKaze:20211004003333p:plain

それにあわせて、改訂版ではその新しいHTTPセマンティクス仕様を参照しています。ヘッダやボディといった用語について変更された部分があるので、HTTP/2の改訂版仕様でも用語の使い方をあわせています。

セマンティクス側の変更点について以前書いた記事を参照ください。

asnokaze.hatenablog.com

TLS 1.3 への対応

もともとのHTTP/2の仕様は、TLS 1.3が出る前に標準化されました。その後、RFC8740「Using TLS 1.3 with HTTP/2」としてHTTP/2においてTLS1.3を使う場合の仕様が記述されています。

今回の改訂版は、RFC8740を取り込みつつ、TLS 1.3の使い方について言及しています

  • RFC8740に則り、post-handshake authenticationの禁止される
  • NewSessionTicketおよびKeyUpdateはHTTP/2に影響がないので、そのまま使用できる
  • RFC8470 に準じていれば、TLS 1.3 の 0-RTT Early DataでHTTPリクエストを送信出来る

RFC7540で定義される優先度制御の廃止

もともとHTTP/2で定義された依存関係を指定する優先度制御方式は、複雑すぎるということで廃止されました。以前紹介した、新しいHTTP優先度制御方式の使用が推奨されます。
asnokaze.hatenablog.com

改訂版では、具体的な優先度制御に関する記述が削除されました。ただし、既存のHTTP/2実装と互換性を維持するために、PRIORITYフレームやHEADERSフレームのフォーマットは変更はありません。既存のPRIORITYフレームを受信した場合は単純に破棄されます。

アップグレードを廃止

もともとの仕様では、HTTP/1.1でつないでから、その通信をHTTP/2にアップグレードする手順が定義されていました。ほぼ使われていないため、この方式は廃止されました。

フィールドのバリデーションを厳密に行う

ヘッダなどのフィールドにおいて、どのような文字が許容されるか、検証項目がより厳密になりました。

HTTP/2からHTTP/1.1に通信を中継するリバースプロキシの実装で、いくつかの脆弱性が見つかったため、より厳密に言及されるようになりました。

基本的には実装上の脆弱性ですが、具体的な攻撃手法は、「HTTP/2: The Sequel is Always Worse | PortSwigger Research」などを参照ください。

Experimental Useを開放

Experimental Useとして予約されていた拡張フレームタイプ値・SETTINGSパラメータ値を開放

Hostヘッダと:authority疑似ヘッダが一致すること

Hostヘッダと:authority疑似ヘッダが必ず一致することが必須となりました。

これも、HTTP/2からHTTP/1.1にプロキシする場合に、曖昧な部分があったため、厳密化されました