QUIC-INVARIANTS
RFC 8999 Version-Independent Properties of QUIC → Update: RFC 9368 QUIC-VN 概要
このドキュメントでは、QUICトランスポートプロトコルのすべてのバージョンに共通するプロパティを定義します。
1. QUICの極めて抽象的な説明
QUICは、2つのエンドポイント間のコネクション指向プロトコルです。これらのエンドポイントはUDPデータグラムを交換します。これらのUDPデータグラムにはQUICパケットが含まれます。QUICエンドポイントはQUICパケットを使用してQUIC接続を確立します。QUIC接続とは、エンドポイント間で共有されるプロトコル状態です。
2. すべてのQUICバージョンの固定プロパティ
QUIC QUIC-TRANSPORTは、安全で多重化されたトランスポートを提供することに加えて、バージョンをネゴシエートするオプションを備えています。これにより、プロトコルは新しい要件に応じて時間の経過とともに変化します。プロトコルの多くの特性はバージョン間で変化する可能性があります。 このドキュメントでは、新しいバージョンが開発および導入されても安定性を維持することを意図したQUICのサブセットについて説明します。これらの不変条件はすべて、IPバージョンに依存しません。このドキュメントの主な目的は、QUICの新しいバージョンを導入できるようにすることです。変更できないプロパティをドキュメント化することで、QUICエンドポイントがプロトコルの他の側面の変更をネゴシエートする能力を維持することを目的としています。その結果、エンドポイント以外のエンティティに提供される情報量が最小限に抑えられることも保証されます。本文書で特に禁止されていない限り、プロトコルのあらゆる側面はバージョン間で変更される可能性があります。付録Aには、QUICバージョン1に関する知識に基づいて想定される可能性のある誤った前提の一部(網羅的ではありません)が記載されています。ただし、これらはQUICのすべてのバージョンに当てはまるわけではありません。
3. 表記規則と定義
本文書におけるキーワード「MUST(しなければならない)」、「MUST NOT(してはならない)」、「REQUIRED(必須)」、「SHALL(するべき)」、「SHALL NOT(すべきでない)」、「SHOULD(すべきでない)」、「RECOMMENDED(推奨される)」、「NOT RECOMMENDED(推奨されない)」、「MAY(してもよい)」、「OPTIONAL(選択できる)」は、ここで示すようにすべて大文字で表記されている場合に限り、BCP 14 RFC2119 RFC8174 で規定されているとおりに解釈されます。 本文書は、規範的な用語が使用されていない場合でも、将来の QUIC バージョンに対する要件を定義します。本文書では、QUIC-TRANSPORT の用語と表記規則を使用します。 4. 表記規則
パケットのフォーマットは、本セクションで定義される表記法を使用して記述します。この表記法は、QUIC-TRANSPORT で使用されているものと同じです。 複合フィールドは名前が付けられ、その後に一対の中括弧で囲まれたフィールドのリストが続きます。このリストの各フィールドはカンマで区切られます。各フィールドには、長さ情報に加え、固定値、オプション、または繰り返しの有無が示されます。各フィールドでは以下の表記規則が使用され、すべての長さはビット単位です。
x (A): x の長さが A ビットであることを示します。
x (A..B): x の長さが A から B までの範囲であることを示します。A を省略すると最小値が 0 ビットであることを示し、B を省略すると上限がないことを示します。この形式の値は常にバイト境界で終わります。
x (L) = C: x の値が C の固定値であることを示します。x の長さは L で表され、L は上記の長さ形式のいずれかを使用できます。
x (L) ...: x が 0 回以上繰り返され、各インスタンスの長さが L であることを示します。
このドキュメントでは、ネットワークバイトオーダー(ビッグエンディアン)の値を使用します。
フィールドは各バイトの上位ビットから配置されます。
図1に構造例を示します。
code: Formet例
構造例 {
1ビットフィールド (1),
固定値を持つ7ビットフィールド (7) = 61,
任意長フィールド (..),
可変長フィールド (8..24),
繰り返しフィールド (8) ...,
}
図1: フォーマット例
5. QUICパケット
QUICエンドポイントは、1つ以上のQUICパケットを含むUDPデータグラムを交換します。このセクションでは、QUICパケットの不変特性について説明します。QUICのバージョンによっては、1つのUDPデータグラムに複数のQUICパケットを許容する場合がありますが、不変特性はデータグラムの最初のパケットのみを対象とします。
QUICは、ロングヘッダーとショートヘッダーの2種類のパケットヘッダーを定義します。ロングヘッダーを持つパケットは、最初のバイトの最上位ビットがセットされていることによって識別されます。ショートヘッダーを持つパケットでは、そのビットはクリアされています。
QUICパケットは、ヘッダーを含めて整合性が保護される場合があります。ただし、QUICバージョンネゴシエーションパケットは整合性が保護されません。セクション6を参照してください。
ここで説明する値を除き、QUICパケットのペイロードはバージョン固有であり、任意の長さになります。
5.1. ロングヘッダー
ロングヘッダーは図2に示す形式をとります。
code:Long Header
ロングヘッダーパケット {
ヘッダー形式 (1) = 1、
バージョン固有ビット (7)、
バージョン (32)、
宛先接続ID長 (8)、
宛先接続ID (0..2040)、
送信元接続ID長 (8)、
送信元接続ID (0..2040)、
バージョン固有データ (..)、
}
図2: QUICロングヘッダー
ロングヘッダーを持つQUICパケットでは、最初のバイトの上位ビットが1に設定されます。そのバイトのその他のビットはすべてバージョン固有です。
次の4バイトには、32ビットのバージョンフィールドが含まれます。バージョンについてはセクション5.4で説明します。
次のバイトには、それに続く宛先接続IDフィールドのバイト長が含まれます。この長さは8ビットの符号なし整数としてエンコードされます。宛先接続IDフィールドは宛先接続ID長フィールドに続き、長さは0~255バイトです。接続IDについてはセクション5.3で説明します。
次のバイトには、それに続く送信元接続IDフィールドの長さ(バイト単位)が含まれます。この長さは8ビットの符号なし整数としてエンコードされます。送信元接続IDフィールドは送信元接続ID長フィールドに続き、長さは0~255バイトです。
パケットの残りの部分には、バージョン固有の内容が含まれます。
5.2. ショートヘッダー
ショートヘッダーは、図3に示す形式をとります。
code:Short Header
ショートヘッダーパケット {
ヘッダー形式 (1) = 0、
バージョン固有ビット (7)、
宛先接続ID (..)、
バージョン固有データ (..)、
}
図3: QUIC ショートヘッダー
ショートヘッダーを持つ QUIC パケットでは、最初のバイトの上位ビットは0に設定されます。
ショートヘッダーを持つ QUIC パケットでは、最初のバイトの直後に宛先接続IDが含まれます。ショートヘッダーには、宛先接続ID長、送信元接続ID長、送信元接続ID、またはバージョンフィールドは含まれません。宛先接続IDの長さは、ショートヘッダーを持つパケットではエンコードされず、本仕様によって制約されません。
パケットの残りの部分は、バージョン固有のセマンティクスを持ちます。
5.3. 接続ID
接続IDは、任意の長さを持つ不透明なフィールドです。
接続IDの主な機能は、下位プロトコル層(UDP、IP、およびそれ以下)でのアドレス指定の変更によって、QUIC接続のパケットが誤ったQUICエンドポイントに配信されないようにすることです。接続IDは、エンドポイントとそれらをサポートする中継局によって使用され、各QUICパケットがエンドポイントの正しいインスタンスに配信されることを保証します。エンドポイントでは、接続IDはパケットの宛先となるQUIC接続を識別するために使用されます。
接続IDは、各エンドポイントによってバージョン固有の方法を使用して選択されます。同じQUIC接続のパケットでも、異なる接続ID値が使用される場合があります。
5.4. バージョン
バージョンフィールドには4バイトの識別子が含まれます。エンドポイントはこの値を使用してQUICのバージョンを識別できます。値が0x000000000のバージョンフィールドは、バージョンネゴシエーション用に予約されています。セクション6を参照してください。その他の値も有効となる可能性があります。
このドキュメントで説明されている特性は、QUICのすべてのバージョンに適用されます。このドキュメントで説明されている特性に準拠していないプロトコルはQUICではありません。将来のドキュメントでは、特定のQUICバージョンまたは複数のQUICバージョンに適用される追加の特性が説明される可能性があります。
6. バージョンネゴシエーション
QUICエンドポイントは、長いヘッダーと、理解できない、またはサポートしていないバージョンを持つパケットを受信した場合、応答としてバージョンネゴシエーションパケットを送信することがあります。短いヘッダーを持つパケットはバージョンネゴシエーションをトリガーしません。
バージョンネゴシエーションパケットは最初のバイトの上位ビットを設定するため、セクション5.1で定義されている長いヘッダーを持つパケットのフォーマットに準拠します。バージョンネゴシエーションパケットは、バージョンフィールドが0x00000000に設定されていることで識別できます。
code:Version Negotiation Packet
バージョンネゴシエーションパケット {
ヘッダー形式 (1) = 1、
未使用 (7)、
バージョン (32) = 0、
宛先接続ID長 (8)、
宛先接続ID (0..2040)、
送信元接続ID長 (8)、
送信元接続ID (0..2040)、
サポートバージョン (32) ...、
}
図4: バージョンネゴシエーションパケット
バージョンネゴシエーションパケットの最初のバイトの最上位ビットのみに値が定義されています。「未使用」とラベル付けされた残りの7ビットは、送信時に任意の値に設定でき、受信時には無視されなければなりません。
バージョンネゴシエーションパケットには、送信元接続IDフィールドの後に、サポートバージョンフィールドのリストが含まれます。各フィールドは、パケットを送信するエンドポイントがサポートするバージョンを示します。バージョンネゴシエーションパケットには、これ以外のフィールドは含まれません。エンドポイントは、サポートバージョンフィールドが含まれないパケット、またはサポートバージョン値が切り捨てられたパケットを無視しなければなりません。
バージョンネゴシエーションパケットは、整合性や機密性の保護を使用しません。特定のQUICバージョンには、エンドポイントがサポート対象バージョンセット内の変更や破損を検出できるようにするプロトコル要素が含まれている場合があります。
エンドポイントは、受信したパケットの送信元接続IDフィールドの値を宛先接続IDフィールドに含める必要があります。送信元接続IDフィールドの値は、受信パケットの宛先接続IDフィールドからコピーする必要があります。宛先接続IDフィールドは、クライアントによって最初にランダムに選択されます。両方の接続IDをエコーすることで、クライアントは、サーバーがパケットを受信したこと、およびバージョンネゴシエーションパケットがパケットを観察できない攻撃者によって生成されたものではないことをある程度確信できます。
バージョンネゴシエーションパケットを受信したエンドポイントは、後続のパケットで使用するバージョンを変更する可能性があります。エンドポイントがQUICバージョンを変更する条件は、選択したQUICのバージョンによって異なります。
QUICバージョン1をサポートするエンドポイントがバージョンネゴシエーションパケットを生成および使用する方法の詳細については、QUIC-TRANSPORTを参照してください。 7. セキュリティとプライバシーに関する考慮事項
ミドルボックスは、特定のバージョンのQUICの特性を観察し、他のバージョンのQUICが同様の特性を示している場合、同じ基盤となるセマンティクスが表現されていると想定する可能性があります。このような特性は潜在的に多数存在します。付録Aを参照してください。QUICバージョン1では、観察可能な特性の一部を排除または隠蔽する取り組みが行われてきましたが、これらの多くは依然として残っています。他のバージョンのQUICでは、異なる設計上の決定が行われ、異なる特性を示す可能性があります。
QUICバージョン番号はすべてのQUICパケットに現れるわけではありません。つまり、バージョン固有の特性に基づいてフローから情報を確実に抽出するには、ミドルボックスが確認するすべての接続IDの状態を保持する必要があります。
このドキュメントで説明されているバージョンネゴシエーションパケットは、整合性が保護されていません。攻撃者による挿入に対しては、中程度の保護しか備えていません。エンドポイントは、結果として異なるQUICバージョンを試みる場合、バージョンネゴシエーションパケットのセマンティクス内容を認証する必要があります。
8. 参考文献
8.1. 規範的参考文献
8.2.参考文献
付録A. 誤った前提
QUICバージョン1 QUIC-TRANSPORT には、監視から保護されていないものの、新しいバージョンの導入時に変更可能であると考えられる特性がいくつかあります。 このセクションでは、QUICバージョン1に関する知識に基づいて、QUICに関して想定される誤った前提の例をいくつか挙げます。これらの記述の中には、QUICバージョン1には当てはまらないものもあります。これは網羅的なリストではなく、あくまでも例示を目的としています。
以下の記述は、特定のQUICバージョンにおいて、いずれも誤りとなる可能性があります。
QUICはTLS QUIC-TLS を使用し、一部のTLSメッセージはネットワーク上で確認できます。 QUICのロングヘッダーは、接続確立時にのみ交換されます。
特定の5タプル上のすべてのフローには、接続確立フェーズが含まれます。
フロー上で交換される最初のパケットは、ロングヘッダーを使用します。
長時間の休止期間の前の最後のパケットには、確認応答のみが含まれていると想定される可能性があります。
QUICは、接続確立時に交換するパケットを保護するために、認証付き暗号化(AEAD)機能(AEAD_AES_128_GCM; RFC5116 を参照)を使用します。 QUICパケット番号は暗号化され、暗号化された最初のバイトとして表示されます。
QUICパケット番号は、送信されるパケットごとに1ずつ増加します。
QUICには、クライアントが送信する最初のハンドシェイクパケットの最小サイズがあります。
QUICでは、クライアントが最初に話すことが規定されています。
QUICパケットは常に最初のバイトの2番目のビット(0x40)がセットされています。
QUICバージョンネゴシエーションパケットは、サーバーによってのみ送信されます。
QUIC接続IDは頻繁に変更されません。
QUICエンドポイントは、バージョンネゴシエーションパケットを受信すると、使用するバージョンを変更します。
QUICロングヘッダーのバージョンフィールドは、双方向で同じです。
バージョンフィールドに特定の値を持つ QUIC パケットは、対応するバージョンの QUIC が使用されていることを意味します。
QUIC エンドポイント間では、一度に 1 つの接続のみが確立されます。
著者のアドレス
Martin Thomson
Mozilla
メールアドレス: mt@lowentropy.net