プロキシ経由のUDPとQUIC
プロキシでウェブ接続の確認に成功しても、プログラムが必要とする通信を扱えるとは限りません。例えば、ゲームにはプロキシ経由でログインできても、プレイ中の更新データをやり取りできない場合があります。ウェブサイトは普通に開けても、ブラウザーがHTTP/3ではなくHTTP/2を使っていることもあります。これらの操作では、必要なネットワーク機能が異なります。
プロトコル選択の全体像は、SOCKSプロキシとHTTPプロキシの比較をご覧ください。この記事では、UDPがプロキシ経由で宛先に届く仕組み、QUICがその経路に求める条件、そしてアプリケーションが意図したトランスポートと出口IPを使っているかの確認方法を説明します。
UDP、QUIC、HTTP/3の役割
TCPは、順序のそろったバイト列を届けます。データの一部が失われると再送を行い、欠けた部分が埋まるまで後続のバイトをアプリケーションに渡しません。UDPは、データグラムと呼ばれる独立したメッセージを送ります。UDP自体は、到達、順序、重複の防止を保証しません。こうした状況への対応は、UDPを使うソフトウェアが決めます。
そのため、アプリケーションは用途に応じた動作を選べます。音声アプリは、再生に間に合わなかった音声パケットを捨てるかもしれません。ゲームは、古い位置情報より新しい更新を優先できます。DNSのやり取りは、短い問い合わせと応答だけで済む場合があります。実際に使うトランスポートはプログラムによります。これらの例は、すべての通話、ゲーム、DNSリクエストがUDPを使うという意味ではありません。
QUICは、UDP上に構築されたトランスポートプロトコルです。接続確立、失われたデータの回復、輻輳制御、信頼性のあるストリームを追加します。信頼性のあるQUICストリームで転送するファイルは、欠けることなく正しい順序で届きます。パケットがUDPデータグラムの中を通ることによって、QUICが提供する信頼性がなくなるわけではありません。
QUICでは、1つの接続で複数のストリームを扱えます。あるストリームのデータが失われても、データが届いているほかのストリームは処理を続けられます。すべてのストリームを1本の順序付きTCP接続で運ぶ場合に比べ、待ち時間を減らせることがあります。ただし、結果は経路、パケット損失、サーバー、クライアントにも左右されます。QUICを選ぶだけでアプリケーションが速くなる保証はありません。
HTTP/3は、QUIC上でHTTPを運びます。HTTP/1.1とHTTP/2は、通常TCPを使います。いずれもHTTPSサイトを提供できるため、アドレスのhttps://だけでは、HTTPのバージョンやUDPの使用は分かりません。
暗号化は別の性質です。UDPはデータを暗号化しません。QUICはTLS 1.3を使ってアプリケーション通信を保護します。通常のUDPアプリケーションは別の保護手段を使うことも、暗号化せずにデータを送ることもあります。プロキシで転送するだけで、自動的に保護が追加されるわけではありません。
SOCKS5でUDPを運ぶ仕組み
SOCKS5は、クライアントからデータグラムを受け取り、そのペイロードを宛先へ送り、応答を返すUDPリレーを定義しています。クライアントはまず、TCPを使ってこの転送を設定します。その後、制御接続とデータグラムの経路が並行して存在します。
- クライアントはTCPでSOCKS5サーバーに接続し、合意した認証手続きを完了します。
UDP ASSOCIATEを要求します。プロキシが受け入れると、応答にはリレーのアドレスとUDPポートが含まれます。- クライアントは、宛先を示すSOCKSヘッダーを付けてデータグラムをリレーに送ります。リレーは、そのヘッダーを取り除いてペイロードを転送します。応答をクライアントへ返すときは、SOCKSヘッダーを付けてデータグラムを送ります。
- クライアントは、リレーを使っている間、TCP制御接続を開いたままにします。接続を閉じると、その接続で設定したUDP転送も終了します。この制御接続とUDP転送の対応関係を、UDPアソシエーションと呼びます。
リレーのアドレスやポートは、プロキシ設定に入力したTCP接続先と異なる場合があります。普段使う接続先へ生のUDPを送っても、SOCKS5の手続きは実行されません。CONNECTだけを実装したクライアントは、TCPにはSOCKS5を使えますが、ここで必要な手続きには対応していません。SOCKS4には、このUDPリレー機能の定義がありません。
これにより、よくある部分的な成功を説明できます。ファイアウォールがTCP接続と認証を許可していても、交渉で決まったリレーへのデータグラムを遮断することがあります。パスワードは通るのに、アプリケーションにはUDPの応答が届きません。経路の両方の部分が利用できる必要があります。
HTTPプロキシはUDPを転送できるか
通常のHTTPのCONNECTリクエストは、宛先へのTCP接続を開き、バイト列を運ぶようプロキシに要求します。UDP転送は設定しません。HTTPSプロキシまでの接続にTLSを使っても、その接続が保護されるだけで、要求するトンネルの種類は変わりません。
HTTPには追加のUDPトンネル方式があり、一般にCONNECT-UDPと呼ばれ、MASQUEの一部として開発されました。対応するクライアントとサーバーを使うと、クライアントはUDP宛先へのトンネルを要求できます。プロキシはデータグラムをその宛先へ転送し、応答を返します。双方がこの方式に明示的に対応している必要があります。
クライアントとプロキシの間では、HTTP/3と必要な拡張機能に対応していれば、HTTPデータグラムをQUIC DATAGRAMフレームで運べます。また、信頼性のあるHTTPストリーム内のフレーム化されたメッセージであるカプセルで運ぶこともできます。これにはTCP上のHTTP/2も含まれます。この場合、経路の最初の部分がTCPでも、プロキシは宛先へUDPを送ります。
この選択は、届くタイミングに影響します。TCP接続でデータが失われると、後続のバイトは回復を待つことがあり、その中で運ばれるデータグラムも遅れます。トンネル自体は動作していても、特定のリアルタイム処理には向かない場合があります。プログラムにhttp://のプロキシアドレスを入力するだけでは、これらの追加UDP方式は有効になりません。
どの接続でQUICを使うのか
「QUICプロキシ」という表現は、文脈を確認する必要があります。プロキシへ到達するためのトランスポートを指す場合も、アプリケーションと宛先の接続を指す場合もあります。両者は、通信の別々の区間です。
| QUICを使う区間 | プロキシの動作 | 確認できること |
|---|---|---|
| クライアントとプロキシの間 | QUICで接続を受け付けます。例えば、HTTP/3で通常のCONNECTを送っても、宛先にはTCP接続を開くよう要求します。 | プロキシまでの接続がQUICを使っています。ウェブサイトへの接続は、別途確認が必要です。 |
| UDPリレーを経由した、アプリケーションと宛先の間 | SOCKS5のUDP転送や適切なHTTP UDPトンネルを使い、アプリケーションのQUICパケットを含むデータグラムを転送します。 | 経路全体が機能すれば、アプリケーションは宛先とQUIC接続を確立できます。HTTP/3を使うには、両端がHTTP/3にも対応し、それを選択する必要があります。 |
通常のUDPリレーでは、プロキシがアプリケーションのQUIC接続を終端する必要はありません。アプリケーションと宛先を暗号化通信の両端としたまま、パケットを転送します。ただし、プロキシには転送先が分かり、通信量やタイミングも観測できます。
アプリケーション側の対応が重要な理由
プログラムは、サービスが提供する転送方式を実装している必要があります。SOCKS5のチェックボックスだけでは、UDP ASSOCIATEに対応しているか分かりません。同様に、直接接続ではHTTP/3に対応していても、プロキシ接続はTCPのみという場合があります。
具体例としてChromeがあります。内蔵のSOCKS5対応は、TCPベースのURLリクエストをプロキシ経由にするもので、SOCKS5でUDPを中継しません。この設定でページを開いても、サービスのUDPリレーをテストしたことにはなりません。この制限は、その特定のクライアントモードに関するものです。ほかのクライアントや外部の経路制御ソフトウェアでは、対応機能が異なる場合があります。
設定の適用範囲も確認してください。ログイン、ファイルのダウンロード、音声、ゲーム通信は、1つのアプリケーション内でも別々のネットワーク機能を使うことがあります。ウェブリクエスト用のプロキシ設定は、その一部にしか適用されない場合があります。システムのプロキシ設定も、各プログラムがそれに従うかどうかで適用が変わります。
ほかのアプリケーションの通信を転送するプログラムは、UDPとサービスの転送方式に対応していれば、そのUDPをプロキシ経由にできます。TCPだけを転送しても不十分です。仮想ネットワークインターフェースを使う場合は、経路の規則によって、どの通信がそこに入るかが決まります。アプリケーション、経路制御プログラム、プロキシの接続先を組み合わせた状態でテストしてください。
フォールバック、失敗、直接接続
必要な経路が使えないときの結果は、アプリケーションの機能と方針によって変わります。何かが開いたかどうかだけを見ていると、次の3つの結果は似て見えることがあります。
| 観測された結果 | 読み取り方 |
|---|---|
| 操作が失敗する | 必要なやり取りが完了していません。クライアント、トンネルの設定、ネットワーク経路、宛先のどこで失敗したかを調べます。 |
| HTTP/2またはHTTP/1.1でサイトが開く | ウェブサイトとの通信は、TCPベースのHTTPバージョンを使っています。ウェブアクセスは動作していますが、そのサイトへのHTTP/3接続は確認できません。別の区間であるプロキシまでの接続は、異なるトランスポートを使っている場合があります。 |
| UDPのやり取りが直接接続で成功する | 通信が、意図したプロキシ経路の外を通っています。その出口アドレスは、別途確認する必要があります。 |
TCPベースのHTTPバージョンへ切り替えることを、フォールバックと呼びます。QUICが使えなくても、通常の閲覧を続けられる場合があります。クライアントが別の接続を開くのであり、QUIC自体がTCPに変わるわけではありません。そのため、QUICを無効にすると、ウェブアプリが利用可能なTCP経路を使えるようになる場合がありますが、UDPを必要とする機能にUDPを提供することはできません。
宛先への直接接続は、経路の選択です。未対応のUDPが必ず直接送信されるわけではありません。ソフトウェアは、停止する、別のトランスポートを試す、設定された迂回規則に従うなどの動作を取ります。作業のすべての通信をプロキシ経由にする必要がある場合は、その経路が失敗すると停止するモードを使い、プロキシが利用できないときの動作を確認してください。
設定後にUDPが動かなくなる理由
ポート規則と戻りの経路
TCPポート443とUDPポート443は、別々のトランスポートに属します。片方を許可しても、もう片方は開きません。SOCKS5では、返されたUDPリレーの接続先にクライアントが到達でき、さらにリレーから宛先のUDPポートにも接続できる必要があります。HTTP/3は443以外のポートも使えるため、アプリケーションが実際に使う接続先を確認してください。
応答は、リレー、ファイアウォール、さらにネットワーク間でアドレスや、多くの場合はポートも変換するNATを通って戻る必要があります。データグラムを送っただけでは、この戻り経路が機能するとは分かりません。ネットワークが変わると、クライアントのパブリックIPやポートの対応付けも変わることがあります。SOCKS5リレーは、そのUDPアソシエーションに記録された送信元IP以外からのデータグラムを拒否する必要があるため、アドレスが変わると新たなアソシエーションが必要になる場合があります。
中断と状態の失効
リレーやNAT機器は、UDPのやり取りに一時的な記録を保持します。その記録は、通信を休止している間に期限切れになることがあります。通話やセッションが最初は動いていても、クライアントが設定し直すまでUDPの経路が使えなくなる場合があります。出口IPが同じでも防げません。UDP転送に必要な状態と、サービスによるIPの割り当ては別のものです。
データグラムのサイズとMTU
MTUは、ネットワークリンクが断片化せずに運べるIPパケットの最大サイズです。経路で使えるサイズは、途中で最も小さい上限であるパスMTUに制限されます。IP、UDP、追加のトンネルヘッダーは、いずれもパケット内の容量を使います。小さなテストメッセージは通っても、大きなデータグラムは破棄されることがあるため、アプリケーションは経路全体と追加ヘッダーを考慮する必要があります。
QUICの経路は、IPヘッダーとUDPヘッダーを除いて、少なくとも1,200バイトのUDPペイロードを運べる必要があります。クライアントは、QUIC Initialパケットを運ぶUDPデータグラムを、少なくともこのペイロードサイズになるようパディングします。クライアントとプロキシの区間に付くプロキシヘッダーには、さらに容量が必要です。これは、インターフェースのMTUを1,200に設定するという推奨ではありません。小さなDNSの問い合わせと応答は通るのに、より大きなQUICハンドシェイクが通らない理由を説明しています。
遅延、損失、負荷
通話やゲームでは、届くこと自体と同じくらい、いつ届くかが重要です。遅延の変動、パケット損失、パケットレートの制限は、動作しているUDPリレーでも品質を悪化させることがあります。帯域幅だけでは、これらの条件は分かりません。プロキシを使うと経路に区間が増えます。ネットワークや処理内容によって、性能が良くなる場合も悪くなる場合もあります。
プロキシ経由のUDPとHTTP/3の確認方法
実際に使うアプリケーション、または同じ転送方式を実装するクライアントでテストしてください。有用なテストでは、同じやり取りについて、応答、トランスポート、出口アドレスを確認します。
- 必要な通信に応答する宛先を選びます。実際のアプリケーションサーバーか、管理下のUDP応答サーバーを使ってください。HTTP/3なら、対応していることが分かっている宛先を選びます。適当なUDPポートから応答がないだけでは、どこで失敗したかは分かりません。
- リレーまたはトンネルが受け入れられたことを確認します。SOCKS5では、
UDP ASSOCIATEの結果と、返されたリレーのアドレスとポートを調べます。HTTP UDPトンネルでは、そのトンネルが受け入れられたことを確認します。認証だけでは、この段階の確認にはなりません。 - リクエストと応答を完了させます。管理下の応答サーバーなら、リクエスト識別子を返し、観測した送信元IPを記録できます。これで、そのUDP通信に使われた出口を確認できます。別途行うウェブのIP確認は、その確認リクエスト自身についてしか分かりません。
- HTTP/3では、宛先との通信で使うプロトコルを確認します。クライアントまたはサーバーの接続ログで、HTTP/3または
h3の表示を、プロキシ経路を使った証拠とともに確認してください。テストクライアントにHTTP/3専用モードがあれば、自動フォールバックでは隠れてしまう失敗を明らかにできます。 - 実際に近いデータグラムのサイズ、継続的な通信、休止後の再開など、用途に合う条件で繰り返します。作業で直接通信が禁止されている場合は、プロキシが利用できないときの動作も確認してください。結果とともに、クライアントのバージョンと接続設定を記録します。
パケットキャプチャーは、経路の特定に役立ちます。標準のSOCKS5 UDP転送は、交渉で決まったリレーにデータグラムを送ります。一方、HTTP UDPトンネルは外側にTCP接続を使う場合があるため、最初の区間でUDPが見えないだけでは、失敗の証拠として不十分です。
リモートDNSとpingは、別のものをテストします。プロキシは、アプリケーションのUDP通信を中継せずに、TCP接続用のホスト名を名前解決できます。通常のpingはICMPを使います。どちらも、意図したプロキシ経路で観測するUDPのリクエストと応答の代わりにはなりません。
UDP対応を選ぶべき場面
まず、作業に必要な通信を確認してください。HTTP/1.1やHTTP/2で動くウェブサイトやAPIの処理なら、TCP専用プロキシで十分な場合があります。HTTP/3のテスト、UDPを使うメディア通信など、UDPに依存する機能には、適切なリレーまたはトンネルと、それを使えるクライアントが必要です。
対応しているUDP転送方式とクライアント設定を、サービスに確認してください。そのうえで、許可される宛先とポート、データグラムのサイズ上限、アイドル時の動作、作業に関係する通信量やパケットレートの制限を確認します。TCPとUDPで同じ出口IPや地域を使う必要がある場合は、実際のアプリケーションで検証してください。アカウントが同じことや、ウェブの確認に成功したことだけでは、出口の動作が同じとは確認できません。
