メディアタイプで複数サフィックスを許可する提案仕様

HTTPレスポンスでは、content-typeとしてメディアタイプ(MIME Type)が指定されます。
例えば次のようなものがあります。

  • content-type: text/html
  • content-type: text/javascript
  • content-type: image/svg+xml

メディアタイプは "+" でサフィックスをつけることが出来ます。
例えば次のようなものがあります。

RFC 6838ではサフィックスは一つのみが想定されています。
このサフィックスを複数つけられるようにする「Media Types with Multiple Suffixes」という提案仕様が出ています。

すでにW3Cの「Decentralized Identifiers(DID)」の仕様では、複数サフィックスのメディアタイプを利用しており、IETF側でもそれをサポートできるようにするという流れです。(なぜDIDで複数サフィックスを選んだかまでは追えてない...)

特に複雑な仕様ではなく、右側から解釈していきますよという話なようだ。

f:id:ASnoKaze:20211203005602p:plain
(IETF 112 mediaman WG スライド)

QUIC Version 2 の仕様 (RFC 9369)

(追記: 2023/06/01 RFC 9369になりました)

QUIC Version 2」という仕様が提案されています。これは、「RFC 9000」で標準化されたQUIC v1と機能上はまったく同じものです。

この提案仕様の目的は、主にふたつあります。

  • 硬直化(ossification)の問題を緩和し将来のQUICバージョンをインターネットでデプロイしやすくする
  • バージョンネゴシエーションを実行できるようにする

11月に実施されたIETF 112の後に、QUIC WGのメーリングリストで、この仕様にWGとして取り組んでいくコンセンサスが得られました。現在はWG Draftとなっています。

なお、Version 2はまだ2番目のバージョンということで便宜上そう呼んでいるようです。バージョン番号の正式なアサインは後に行われます。

硬直化(ossification)の問題の緩和

硬直化とは、新しいバージョンのプロトコルを使おうとしたときに、対応していないネットワーク機器やミドルウェアが不具合を起こし、通信が阻害されることを言います。TCP Fast Openや、TLS 1.3 などで、ハンドジェクは完了するが片方向で通信がブロックされるといった、おかしな挙動をするネットワーク機器が見つかり、問題になりました。

QUICも硬直化する可能性があります。将来デプロイされるQUICv2に対応してない実装が誤ってそのパケットを処理し、不具合が起き通信が阻害される可能性があります。Google QUICでの実験ではその問題がすでに起こっていたことを明らかにしています。もちろん、IETF QUICでは硬直化が起きないように対策されています。

QUICv1のパケットは、暗号化にバージョン固有のソルトを使用しています。将来のQUICでも同様にバージョン固有のソルトを使えば、そのバージョンに対応していない(=ソルトを知らない)実装は、暗号的に初期パケットを解読できません。ですので、間違えて処理をするという問題を軽減されています。

QUIC Version 2では、これらのバージョンに固有な暗号用のパラーメータが実装上正しく変えられるようになります。逆にQUIC Version 2に対応していない実装が、QUIC Version 1のロジックで復号しようとするネットワーク装置などの問題をあぶり出すことが出来ます。

暗号関連の変更点

QUIC Version 2で変更される暗号関係のパラメータは次のとおりです。

QUIC Version 2」では、initial_salt を次のように指定しています。

initial_salt = 0xa707c203a59b47184a1d62ca570406ea7ae3e5d3

またパケット保護に使う鍵の導出に使うラベルも変更されます

  • quic key => quicv2 key
  • quic iv => quicv2 iv
  • quic hp => quicv2 hp
  • quic ku => quicv2 ku

Retry Integrityタグに使う値は次に変更されます

secret = 0x3425c20cf88779df2ff71e8abfa78249891e763bbed2f13c048343d348c060e2
key = 0xba858dc7b43de5dbf87617ff4ab253db
nonce = 0x141b99c239b03e785d6a2e9f

バージョンネゴシエーション

QUICはクライアント・サーバ間で使用するQUICバージョンをネゴシエーションします。将来標準化されるQUICの登場を待ってその仕組を作るのではなく、すでに「https://www.ietf.org/id/draft-ietf-quic-version-negotiation-05.html」として標準化が進められています。この仕組を実際に使っていくことで、将来のQUICバージョンのデプロイをしやすく出来ます。バージョンネゴシエーションを行う選択肢として「QUIC Version 2」の標準化を行っているという意味もあります

バージョンネゴシエーションの仕組みは以前書いたとおりになります。
asnokaze.hatenablog.com

アプリケーションでの利用、拡張機能

QUIC Version 2は、機能上QUICv1と代わりありません。QUICv1を使うアプリケーションプロトコルは、ALPNの変更無くQUIC Version 2を使用出来ます。

また、QUICv1で機能する拡張は、QUIC Version 2でも使用できます。

その他

ふと、疑問が一点。
QUICv1で通信したことある、Version 2に対応しているクライアントとサーバがいたとする。次の通信で、QUICv1で0-RTTを投げたときにCompatible Version NegotiationしたときのEarly Dataの扱いは、実装依存なのかな?ハンドシェイク上はただのPSKという感じで?

なんだかややこしい...orz

新しい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になります。

  • 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で、どのように標準化を進めるか議論されることでしょう。