HTTP/3入門

第2章詳解QUIC ~ TCPに代わり下位層で使用する新しいトランスポートプロトコル

本章では、HTTP/3がTCPに代わって下位層で用いるQUICについて解説します。

QUICはトランスポートプロトコル

QUICはトランスポートプロトコルです。QUICの説明に入る前に、トランスポートプロトコルついておさらいします。

TCP/IPの4階層モデル

プロトコルは階層で役割を分担しています。TCP/IPの4階層モデルでは、アプリケーション層、トランスポート層、インターネット層、ネットワークインタフェース層に分かれます図1⁠。

図1 TCP/IPの4階層モデル
画像

アプリケーション層に分類されるアプリケーションプロトコルは、クライアントやサーバで動作するアプリケーションの動作に関するデータやメッセージの通信ルールを規定します。たとえばSMTPSimple Mail Transfer Protocolは、メールを送信する通信ルールを規定しています。HTTPはこの層に属します。

トランスポート層に分類されるトランスポートプロトコルは、アプリケーション層で規定されたデータやメッセージを相手に届ける通信ルールを規定します。TCPやUDPUser Datagram Protocol⁠、QUICはこの層に属します。なお、QUIC自体も下位層にUDPを利用します。

インターネット層に分類されるインターネットプロトコルは、パケットがインターネット上で中継され、適切な相手に届けるための通信ルールを規定します。IPはこの層に属します。

ネットワークインタフェース層に分類されるネットワークインタフェースプロトコルは、隣接するマシンどうしがやりとりするための通信ルールを規定します。MACやイーサネットはこの層に属します。

トランスポートプロトコルの信頼性

同じトランスポートプロトコルに分類されるプロトコルでも、その性質は異なります。信頼性という観点で比べてみましょう。

マシンどうしの通信では、パケットロスやパケットの順番の入れ替わりが発生する可能性があります。このようなことが起こっても、受け取り手が正しい順序で処理できる性質のことを信頼性と呼びます。

TCPには信頼性があります。パケットロスが起こった場合、ロスしたパケットを再送するようOSが相手に要求し、送りなおしてもらいます。パケットの順番の入れ替わりも、OSが正しい順番になおせるようになっています。アプリケーションは順番に並んだデータをOSから受け取り、処理します。

UDPには信頼性がありません。パケットロスが起ころうと、順番が入れ替わろうと、受け取った順でアプリケーションに渡します。パケットを再送してもらうか、正しい順番に並びなおすか、そのまま処理するかは、アプリケーションが責任を持ちます。

QUICは、下位層にUDPを使っていますが、TCPと同様に信頼性があります。

QUICの基本

本節では、QUICの仕様やバージョン、長所といった基本情報を整理します。

仕様

QUICの仕様は2021年5月にRFCとなっており、次の3つに分かれています。

  • QUIC: A UDP-Based Multiplexed and Secure TransportRFC 9000
  • Using TLS to Secure QUICRFC 9001
  • QUIC Loss Detection and Congestion ControlRFC 9002

順に、QUICのトランスポートプロトコルとしての機能を定めたもの、TLSTransport Layer Securityを使用した暗号化のしくみを定めたもの、パケットロスの検出や、帯域を逼迫ひっぱくさせないように通信を行う輻輳ふくそう制御について定めたものです。

バージョン

今回標準化されたQUICのバージョンは1です。バージョンを明示する際はQUICv1と呼びます。

バージョン番号の定義

QUICでは、バージョン番号は4バイトで表現されます。QUICv1の場合は0x00000001となります。以降は順に、QUICv2の場合は0x00000002QUICv3の場合は0x00000003と上がっていくものと思われます。

RFCになる前の草案段階のバージョン番号には接頭辞0xffが付き、草案の版数を入れます。たとえば、執筆時点で広く利用されている草案29版目(16進数で0x1dは、接頭辞との間を0で埋めて0xff00001dとなります。

将来に向けたしくみ

QUICv1は、将来的にQUICのバージョンが2になることを見越して設計されています。クライアントとサーバがお互いに対応しているバージョンで通信できるように、使用するバージョンをネゴシエーション(交渉)するしくみがあります。また、未対応のバージョンのパケットを処理できないようにするしくみもあります。

TCPと比べた長所

QUICには、TCPと比べて下記の長所があります。

トランスポート層でのHead-of-Line-Blocking問題の回避

前章で説明したように、TCPにおいてもHead-of-Line-Blocking問題が起こります。一般的に、TCPはOSで処理されます。パケットロスが発生すると、OSはそのデータの再送を要求し、パケットロスを回復したのちにアプリケーションにデータを渡します。パケットロス時に後続のパケットを受信できていたとしても、パケットロスしたデータが回復されるまでアプリケーションにはデータが渡されません。

QUICでは、パケットロスしたとしても、受信できた後続のパケットのデータはアプリケーションに渡され、処理が進められます。

IPアドレスが変わっても通信を継続できる

TCPのコネクションは、5タプルと呼ばれる情報で識別されます。5タプルとは、送信元IPアドレス、送信先IPアドレス、IPヘッダのプロトコル、送信元ポート番号、送信先ポート番号の5つの情報のことです。そのため、5タプルのうち1つでも変わると、TCPコネクションを継続できません。

QUICでは、コネクションの識別にコネクションIDを用います。そのため、IPアドレスやポート番号が変わっても通信を継続できます。さらに、クライアントが自発的に通信経路を切り替えるコネクションマイグレーション機能も持っています。コネクションマイグレーションについては後述します。

再送制御の効率化

QUICでは、送信者が送った順番を示すパケット番号をパケットに付与しています。パケットロスがあった場合、そのパケットをそのまま再送するのではなく、ロスしたパケットに含まれていたデータのうち、再送する必要があるもののみを、新しいパケット番号を付与したパケットで送りなおします。再送が起こったことを受け取り手がわかるので、輻輳制御を行ううえでメリットがあります。

また、TCPと同様にQUICでも、受け取ったデータに対して、受け取った旨を相手に通知するAckを行います。そのAckで表現できる量も向上しており、受信できたパケット番号と、受信できていないパケット番号を一度により多く通知できます。

トランスポート層の制御情報も暗号化される

通信時にアプリケーションデータを暗号化する方法の一つに、TLSがあります。たとえばHTTP/1.1やHTTP/2は下位層にTLSを利用し、HTTPメッセージを暗号化して通信します。TLSはTCP上で動作し、アプリケーションプロトコルを暗号化しますが、TCPの制御メッセージは暗号化しません。そのため、経路上の観測者に通信の状態がわかってしまいます。

QUICではTLSを、下位ではなく内部的に使用します。通信を確立する際に、QUICパケットにTLSのメッセージを格納して送信し、クライアントとサーバで鍵を共有します。その鍵を用いて、QUIC通信を暗号化します。TCPを利用した場合とは異なり、アプリケーションデータだけでなく、再送制御に関する情報や、切断のためのメッセージといった制御メッセージも暗号化されます。そのため、経路上の観測者は、再送が起こっていることやQUICのコネクションが切断されたことを観測できません。

なお、HTTP/1.1とHTTP/2は、TLSを使わなければ暗号化しない通信となります。QUICでは暗号化しない通信は行えません。

エンドユーザーへのより早い新機能の提供

QUICはTCPと比べ、エンドユーザーへより早く新機能を提供できます。

TCPは、一般的にはOSで処理されます。そのため、TCPの新しい機能がOSやカーネルに実装されたとしても、実際にエンドユーザーのマシンに反映されるのに数ヵ月以上の時間を要します。

QUICは、ユーザーランドで動作するブラウザといったアプリケーションで処理されます。OSに比べアプリケーションは容易に更新できるため、エンドユーザーにより早く新機能を届けられます。

まだQUICが使えないケースはある

現状では、QUICが使えないケースがあります。GoogleによるGoogle QUICを用いた初期調査によれば、Google QUICが疎通できないネットワークがあることが報告されています。QUICの利用が浸透すれば状況は良くなるかもしれませんが、QUICを利用するアプリケーションプロトコルでは、QUICを利用できない場合にTCPのものにフォールバックする必要があるかもしれません。

HTTP/3では、実装依存ではありますが、QUICが利用できない場合、TCPを使用する暗号化したHTTP/1.1やHTTP/2にフォールバックします。

QUIC通信の基本

本節では、QUIC通信の基本を紹介します図2⁠。

図2 QUIC通信
画像

QUICでは、通信を開始するクライアントとそれを受け入れるサーバ間でやりとりを行います。両者を区別しない場合、エンドポイントと呼びます。

QUICの通信は、QUICコネクションとして管理されます。各QUICコネクションは、コネクションIDで識別されます。コネクションIDには送信元コネクションIDと送信先コネクションIDがあります。

QUICのデータは、QUICパケットとして送信されます。QUICパケットは、UDPパケットに格納されます。1つのUDPパケットに複数のQUICパケットが入ることはありますが、1つのQUICパケットが複数のUDPパケットにまたがることはありません。

以降では、次節でQUICパケットの詳細を、次々節でQUICコネクションの詳細を解説します。

QUICパケット ─⁠─ データの送信単位

本節では、QUICパケットの詳細を解説します。

QUICパケットの構成

UDPパケットを含めてQUICパケットの構成を図示すると、図3のようになります。

図3 QUICパケットの構成
画像

各QUICパケットには、ヘッダとペイロード領域があります。ヘッダには、パケットの処理に必要な先述のコネクションIDやパケット番号などが格納されます。パケット番号は送信者が採番し、受信者はパケット番号を見ることでパケットロスなどの判断を行います。ペイロードには、後述するフレームが格納されます。

QUICパケットの種類

本項では、QUICパケットの種類を解説します。

QUICパケットには、ヘッダが異なるロングヘッダパケットとショートヘッダパケットの2種類があります。ロングヘッダパケットはQUICコネクションの確立時に使用され、確立後はショートヘッダパケットが使用されます図4⁠。

図4 ロングヘッダパケットとショートヘッダパケット
画像

ロングヘッダパケット ─⁠─ QUICコネクション確立時に使用

QUICコネクションの確立時に使用されるロングヘッダパケットのヘッダには、送信元コネクションIDと送信先コネクションIDの両方が格納されています。QUICコネクション確立時のハンドシェイク中に、お互いが使用するコネクションIDを示し合います。送られてきたパケットにサーバが応答する場合、受け取ったパケットが持つ送信元コネクションIDを、送信先コネクションIDに設定してデータを送り返します。

ロングヘッダパケットのヘッダにはほかにも、QUICのバージョンなどが格納されています。

ロングヘッダパケットには次の種類があります。

Initial
ハンドシェイクにおいて、クライアントから最初に送られる
0-RTT
0-RTTハンドシェイク時に使用される
Handshake
ハンドシェイクにおいて、Initialの次に送られる
Retry
ハンドシェイクをやりなおすときに送られる

ショートヘッダパケット ─⁠─ QUICコネクション確立後に使用

QUICコネクションの確立後に使用するショートヘッダパケットは、ロングヘッダパケットに比べ短いヘッダを持ち、送信先コネクションIDのみが格納されます。QUICコネクションの確立後は、送信先コネクションIDに紐付く送信元コネクションIDは既知だからです。

ショートヘッダパケットのヘッダにはほかにも、スピンビットと暗号鍵のフェーズが格納されます。スピンビットは、エンドポイントが使用するかどうかを選択できます。通信経路上での通信の最適化を期待する場合に用い、経路上の観測者が通信の遅延を観測できるようになります。暗号鍵のフェーズは、後述する鍵の更新を示します。

ショートヘッダパケットは1種類のみで、1-RTTパケットです。

フレーム ─⁠─ QUICにおけるメッセージの単位

QUICパケットには、1つ以上のフレームが格納されています。HTTP/2と同様に、QUICでもフレームはメッセージです。ハンドシェイクやアプリケーションデータ、QUICコネクションの制御メッセージなどは、すべてフレームとして格納されます。

フレームには用途別に20個のタイプがあります。その一部を表1に示します。タイプによって、どのようなデータを持つかは異なります。アプリケーションデータはSTREAMフレームで送受信されます。それ以外のフレームは、ハンドシェイク時やエラーの通知に使われます。

表1 フレームのタイプ(一部)
タイプ名 タイプ値 説明
PADDING 0x00 QUIC パケットのサイズを増やすために使用する。意味は持たない
PING 0x01 通信相手が生存していること、通信相手にパケットが正しく届くことの確認に使用する
ACK 0x02, 0x03 確認応答(後述)に使用する。詳細は割愛するが、輻輳状況を知らせるECNExplicit Congestion Notificationを使う場合は0x03のタイプ値を使う
RESET_STREAM 0x04 ストリーム(後述)の終了に使用する
CRYPTO 0x06 暗号ハンドシェイク用のデータ送信に使用する
NEW_TOKEN 0x07 再接続が必要になったときのハンドシェイク中に用いるトークンの送信にサーバが使用する
STREAM 0x080x0f ストリームを作成し、ストリームデータ(アプリケーションデータ)を送信するために使用する。詳細は割愛するが、タイプ値によって、アプリケーションデータのどの部分かを示すオフセットや、長さを示す領域を持つかどうかの違いがある
NEW_CONNECTION_ID 0x18 通信中にコネクション ID を変更する際に、新しく使うコネクション ID の通知に使用する
RETIRE_CONNECTION_ID 0x19 NEW_CONNECTION_ID で発行されたコネクション ID を使用しないことの通知に使用する
PATH_CHALLENGE 0x1a コネクションマイグレーションにおいて、新しい通信経路が有効かの確認に使用する
PATH_RESPONSE 0x1b コネクションマイグレーションにおいて、PATH_CHALLENGEへの応答として使用する
CONNECTION_CLOSE 0x1c, 0x1d コネクションのクローズに使用する。QUICコネクションに起因する場合は0x1cアプリケーションプロコルに起因する場合は0x1dのタイプ値を使う
HANDSHAKE_DONE 0x1e ハンドシェイクが完了したことの通知にサーバが使用する

ストリーム ─⁠─ アプリケーションデータの通信管理の仮想単位

本項では、前項で登場したアプリケーションデータを運ぶSTREAMフレームについて説明します。

QUICは、1つのQUICコネクション内に仮想的な通信管理単位であるストリームを複数持ち、ストリームごとにアプリケーションデータであるSTREAMフレームの送受信を管理します。送受信されるSTREAMフレームは、いずれかのストリームに属します。一度使い終わったストリームはクローズとなり、再利用はできません。なお、STREAMフレーム以外のフレームには、ストリームは用いられません。

ストリームは、ストリーム単位で信頼性を持っています。つまり、あるストリームでやりとりされるデータは、そのストリーム内で順番が保証されます。たとえば、あるストリームでパケットロスやパケットの順番の入れ替わりが発生した場合、必要であれば再送を待ち、もとの順番に戻してからアプリケーション側に渡します。この間、別のストリームは影響を受けず、処理を進められます図5⁠。

図5 QUICのストリームのイメージ
画像

TCPを使うHTTP/2では、ストリームの管理はHTTP/2、パケットの管理はTCPと管理者が分かれているため、ストリーム単位では信頼性を持つことはできません。HTTP/2とTCPで分かれて行っていたことをQUICではまとめて行うので、QUICはアプリケーションプロトコルに対してストリーム単位での信頼性を提供できます。これによりQUICは、第1章で説明したようなTCPのHead-of-Line-Blocking問題を解決します。

ストリームの種類

ストリームには、単方向ストリームと双方向ストリームがあります。単方向ストリームは、ストリームを開始した側からしかSTREAMフレームを送信できません。双方向ストリームは、ストリームを開始したあと双方からSTREAMフレームを送信できます。ストリームは、クライアント、サーバのどちらからも開始できます。つまり、ストリームには表2の4種類があります。

表2 ストリームの種類
種類 ストリーム ID ストリーム ID のビット表現の下位 2 ビット
クライアントが開始する双方向ストリーム 0, 4, 8, 12…… 00
サーバが開始する双方向ストリーム 1, 5, 9, 13…… 01
クライアントが開始する単方向ストリーム 2, 6, 10, 14…… 10
サーバが開始する単方向ストリーム 3, 7, 11, 15…… 11

ストリームID

各ストリームには、識別子として整数値のストリームIDが付いています。ストリームIDは、ストリームの種類によって区別されます。たとえばクライアントが開始する双方向ストリームでは、ストリームIDは0, 4, 8, 12......と0から順番に4ずつ上がっていきます。また、ストリームIDの整数をビットで表した際の下位2ビットは、必ず00となります。サーバが開始する双方向ストリームでは、ストリームIDは1, 5, 9, 13......と1から順番に4ずつ上がっていきます。また、ストリームIDの整数をビットで表した際の下位2ビットは、必ず01となります。クライアントが開始する単方向ストリーム、サーバが開始する単方向ストリームについても同様に決まっています。詳しくは表2を参照してください。

QUICパケットの暗号化

本項では、QUICパケットの暗号化について説明します。QUICパケットは、復号時に改ざんされていないことがわかる認証付き暗号で暗号化されます。

パケットのヘッダ部分とペイロード部分でそれぞれ暗号化されます。ヘッダは、すべてが暗号化されるわけではありません。パケット番号など、一部が暗号化されます。暗号化していない部分も、改ざんされた場合は検知できるようになっています。ペイロードは、すべてが暗号化されます。

鍵の種類

QUICパケットの暗号化に使用する鍵は、パケットの種類ごとに分かれています。

Initial Keys
ロングヘッダパケットのinitialパケット用の鍵
Early Data (0-RTT) Keys
ロングヘッダパケットの0-RTTパケット用の鍵
Handshake Keys
ロングヘッダパケットのHandshakeパケット用の鍵
Application Data (1-RTT) Keys
ショートヘッダパケットの1-RTTパケット用の鍵

Initial Keysは通信の開始に必要ですので、仕様で定義された固定値をもとに導出されます。それ以外の鍵は、QUICコネクションの確立時に得られた秘密値から導出されます。

Application Data (1-RTT) Keysはほかの鍵と比べ長く使うため、使用上限があります。同一の鍵で暗号化を行ったデータ量が上限を超えた場合、鍵を更新します。

QUICコネクション ─⁠─ QUICの通信単位

本節では、QUICコネクションの確立方法と終了方法を解説します。また、通信経路を切り替えるコネクションマイグレーションについても説明します。

QUICコネクションの確立

QUICはTCPとTLSを使う場合より、コネクションの確立を速く行えます。TCPとTLSを使う場合はTCPコネクションを確立してからTLSハンドシェイクを行いますが、QUICではそれらのやりとりをまとめて行います。これにより、アプリケーションデータを送信するまでの準備時間が短くなります。

通常は、1-RTTハンドシェイクという手順を使用します図6⁠。より速い0-RTTハンドシェイクも使えますが、ここでは割愛します。

図6 QUICの1-RTTハンドシェイク
画像

やりとりは、TLSのハンドシェイクで行われていることと同じです。TLS 1.3のコネクションであるTLSコネクション確立時に使うハンドシェイクメッセージClientHelloServerHelloFinishedなど)を、CRYPTOフレームに格納して送受信します。CRYPTOフレームは、ロングヘッダパケットであるInitialパケットとHandshakeパケットに格納されます。

この送受信の中で、クライアントは、サーバの真正性を保証するサーバ証明書を取得して確認します。また、次項で説明する通信に関するトランスポートパラメータの交換と、次々項で説明するアプリケーションプロトコルのネゴシエーションも行います。そして、クライアントとサーバは、後続のパケットの暗号処理に必要な鍵を共有します。

クライアントは、最後のCRYPTOフレームを送ると、クライアント側としてはQUICコネクションが確立されます。そのあとは、ショートヘッダパケットである1-RTTパケットを用いてアプリケーションデータを送信します。

サーバは、クライアントからの最後のCRYPTOフレームを受信すると、ハンドシェイクが終わったことを明示的に示すHANDSHAKE_DONEフレームを送信し、サーバ側としてもQUICコネクションが確立されます。そのあとは、1-RTTパケットを用いてアプリケーションデータを送信します。

このハンドシェイクの結果として、送ったデータに対して適切な応答が返ってくることを確認できます。これによって、サーバはクライアントが送信元IPアドレスを偽装しているのではなく、送信元IPアドレスをたしかに所持していることがわかります。

トランスポートパラメータ ─⁠─ 通信に関するパラメータ

QUICではハンドシェイク時に、通信に関するトランスポートパラメータとしてquic_transport_parametersというデータを送信します。これは、TLSハンドシェイクメッセージに付随するデータであるTLS拡張として送られます。トランスポートパラメータには、たとえば次のものがあります。

max_idle_timeout
最大アイドル時間
stateless_reset_token
ステートレスリセット用トークン(後述)
max_ack_delay
Ackを送るまでの最大遅延時間
initial_max_streams_bidi
オープンできる双方向ストリーム数の初期値
initial_max_streams_uni
オープンできる単方向ストリーム数の初期値

ALPN ─⁠─ アプリケーションプロトコルのネゴシエーション

QUICではハンドシェイク時に、通常のTLSと同様に、使用するアプリケーションプロトコルのネゴシエーションを行います。これには、HTTP/2でも利用していたRFC 7301のTLS Application-Layer Protocol Negotiation Extensionで定義されるしくみ(以下、ALPN)を利用します。ALPNでは、ハンドシェイク中にTLS拡張を使ってアプリケーションプロトコルを決定します。

HTTP/3の場合も、QUICコネクションの確立時に、TLSハンドシェイクのメッセージでALPNとしてh3を送り合い、HTTP/3の使用を決定します。

コネクションクローズ ─⁠─ 通信の終了

QUICでQUICコネクション上のやりとりを終了し、QUICコネクションに関する情報を破棄することをコネクションクローズと言います。

コネクションクローズする方法には、アイドルタイムアウト、即時クローズ、ステートレスリセットの3種類があります。

アイドルタイムアウトでは、エンドポイントは相手からの通信が来ない状態が、事前に決めた時間を超えた場合にコネクションクローズします。

即時クローズでは、エンドポイントはCONNECTION_CLOSEフレームを送信することで即時にコネクションクローズします。QUICコネクション、アプリケーションプロトコルでエラーが発生したときに使用します。

ステートレスリセットは、トークンを使ってコネクションクローズします。たとえば、サーバが再起動などにより暗号処理に必要な鍵情報を失った場合、受信したQUICパケットを処理できません。こうなると、クライアントはアイドルタイムアウトまで待つしかありません。それを防ぐために、QUICコネクションが確立されたあとに、切断用のトークンをサーバからクライアントに安全に払い出します。クライアントはこのトークンを送信することで、状態を失ったサーバともコネクションクローズできます。

コネクションマイグレーション ─⁠─ 切断なく通信を切り替える

QUICは、QUICコネクションを切断することなく、クライアントから自発的に通信経路を切り替えるコネクションマイグレーションという機能を持っています。スマートフォンにおいて、キャリア回線からWi-Fi回線へ切り替える際などに利用できます。

コネクションマイグレーションでは、まずクライアントからPATH_CHALLENGEフレームを送り、それを受けとったサーバからPATH_RESPONSEフレームを送り返すことで、新しい経路2でやりとりできることを確認します図7⁠。そのあと、実際に経路2で通信を開始し、古い経路1の通信を中止します。このとき、通信回線に依存する輻輳制御の状態などはリセットされます。

図7 コネクションマイグレーション
画像

コネクションマイグレーションを行った際は、新しい経路上では新しいコネクションIDを使います。そのため、経路上の第三者が移行前と移行後の通信を関連付けることはできません。

パケットロスに伴うデータの再送

QUICでは、パケットロスを検出し、必要なデータを再送します。その方法を見ていきましょう。

パケットロスの検出

エンドポイントはパケットを受信すると、パケット番号を確認します。受け取ったパケット番号は、1、4のように歯抜けが起こる場合があります。この歯抜けの幅が一定数以上の場合、パケットロスが起こったと判断します。一定数以下の場合、歯抜けとなったパケット番号を持つパケットを待ちます。一定時間以上待ってもそのパケットが送られてこない場合、パケットロスが起こったと判断します。

確認応答の送信

ロスしたパケットのデータを再送してもらうために、受信できたパケットと受信できていないパケットのパケット番号を相手に通知します。これを確認応答と呼び、ACKフレームを送ることで行います。

ACKフレームには、受信できたパケット番号の範囲と、受信できなかったパケット番号の範囲が記述されます。1つのACKフレームの中に複数の範囲を指定できるため、TCPのAckよりも多くの情報を伝えられます。

ロスしたパケットが運んでいたデータの再送

ACKフレームを受信したエンドポイントは、相手が受け取れなかったデータのうち、送りなおす必要があるもののみを、新しいパケット番号で再送します。ロスしたパケットに含まれていたアプリケーションデータは再送されます。PADDINGフレームといった意味を持たないデータは再送されません。

アンプ攻撃への対策

先述したようにQUICはUDPを使用します。UDPを使った攻撃に、攻撃対象者に大量のトラフィックを送り付けるアンプ攻撃があります。本節では、QUICでのアンプ攻撃対策について説明します。

攻撃の行われ方 ─⁠─ 大量のトラフィックを送り付ける

攻撃者は、パケットの送信元アドレスとして攻撃対象者のIPアドレスに偽装します。公開されているサーバにそのパケットを送信すると、応答は攻撃対象者に返されます。

サーバに送信したデータ量よりも応答のデータ量が大きくなる場合、攻撃対象者に大量のトラフィックを生み出せます。トラフィックの増幅率は、攻撃手法によっては100倍以上となります。これにより、攻撃対象者のネットワークを逼迫させます。

QUICにおける対策

先述したように応答は攻撃対象者に返されます。そのため、何往復も継続的にやりとりすることはできません。ですので、最初に受け取ったパケットに対する応答の増幅率を下げることが対策として効果的です。そこで、QUICコネクション確立時に最初に送るパケットは、必ず1,200バイト以上とするよう仕様に規定されています。1,200バイト未満のものはサーバによって破棄されます。

また、先述したハンドシェイクの結果としてクライアントによる送信元IPアドレスの所持が確認できるまで、送信できるデータ量は制限されます。

QUICの今後

本節では、QUICの今後を簡単に紹介します。

QUICv1では採用が見送られた機能

QUICを標準化する中で、議論されたもののQUICv1では採用されなかった機能があります。これらの機能は、将来のQUICに組み込まれる可能性があります。

FEC ─⁠─ ロスしたパケットを回復するしくみ

FECForward Error Correctionとは、送信する各パケットに冗長化データを持たせ、パケットをロスしても、そのほかのパケットに含まれる冗長化データをもとに復元できるようにするしくみです。

先行事例により単純なしくみでは十分なメリットが得られないとわかったため、QUICv1では見送りになりました。現在、この機能をQUICに盛り込むことは、活発には議論されていません。

MP-QUIC拡張 ─⁠─ 複数通信経路の同時利用

Wi-Fi回線とキャリア回線を同時に使って通信を行うといった、複数の通信経路を利用する方法があります。これを実現するために、TCPにはRFC 8684で定義されたMultipath TCPと呼ばれる仕様があります。QUICにおける同様の仕様がMP-QUICです。

複雑さが増すため、QUICv1では盛り込まれませんでした。現在は、QUICへ機能追加を行う拡張仕様として議論が継続されています。

HTTP以外での利用

QUICはHTTP以外のアプリケーションプロトコルでも利用が検討されています。たとえば、DNSDomain Name System⁠、SSHSecure Shell⁠、RTPReal-time Transport Protocolなどです。

まとめ

本章ではQUICについて解説しました。トランスポートプロトコルであるQUICは、アプリケーションプロトコルに対して通信の信頼性と暗号化の機能を提供します。

次章は、いよいよHTTP/3の詳解です。

おすすめ記事

記事・ニュース一覧