REALITY・XTLS Visionの仕組みを解説|TLSハンドシェイクと二重暗号化の軽減

REALITYが接続先サイトのTLS特性を利用する仕組みと、Visionが二重暗号化を抑えて転送負荷を軽減する理由を解説します。

この記事の概要

REALITYは外部接続の認証とハンドシェイクを担い、XTLS Visionは条件を満たすデータの転送を担います。両者は同じプロトコル設定ではありません。VLESSの設定を入手済みで、SNI、公鍵、shortId、flowの役割を知りたい方に向けて、ハンドシェイク、暗号化の仕組み、クライアントの確認手順を順に解説します。設定項目ごとの役割を把握し、「ハンドシェイクに失敗する」場合と「接続後にWebページを開けない」場合の確認箇所を切り分けられます。

1. VLESS・REALITY・Visionの役割

「VLESS + REALITY + Vision」は、それぞれ異なる層を担う構成です。VLESSはユーザー識別情報や接続先アドレスなどのプロキシ要求を運びますが、アプリケーションデータを暗号化する機能はありません。REALITYはこの構成における安全な通信と認証を担い、Visionは条件を満たすトラフィックを効率よく転送します。3つをすべて「暗号化プロトコル」と呼ぶと、設定項目の役割を取り違える原因になります。

接続・認証レイヤー

プロキシプロトコル
VLESS
ユーザー識別情報
UUID
安全な通信
REALITY
サーバー認証
公鍵とハンドシェイク検証

UUIDとREALITYの公鍵は役割が異なり、互いに置き換えることはできません。

この記事で扱う通信構成

下位の通信方式
TCP / RAW(名称はバージョンにより異なります)
フロー制御値
xtls-rprx-vision
ハンドシェイクフィンガープリントの例
chrome
一般的な接続先ポート
443(実際の設定に従ってください)

この構成にWebSocketパスや別の通信ラッパーを追加しないでください。

v2rayNはデスクトップ向けのGUIクライアントですが、各機能を実際に使えるかどうかは選択したコアに依存します。v2rayNGはXrayコアを使用します。v2flyNGはv2flyコアを使用するため、名前が似ているからといって同じREALITY・Vision設定に対応すると考えてはいけません。設定をインポートできても、実行中のコアが対応機能を備えているとは限りません。

2. REALITYの「ハンドシェイク借用」は接続先サイトの秘密鍵を取得することではない

通常のTLS接続では、ブラウザーは証明書チェーンとドメイン名を検証してWebサイトの正当性を確認します。REALITYは、正しい認証情報を持つクライアントと、有効な認証情報を持たない通常のアクセスやプローブの両方に対応する設計です。接続先サイトのハンドシェイク時の特徴とフォールバック転送を利用し、認証されていない接続が、プロキシ特有のエラーを返すのではなく、接続先サイトにアクセスしたように見える状態にします。

クライアントのハンドシェイク サーバー認証 一時証明書の検証 VLESSリクエスト 接続先へのデータ転送

上記は認証に成功したプロキシ接続の流れです。クライアントは事前に設定されたサーバー公鍵とハンドシェイクの情報を使って、REALITYの一時証明書の仕組みを検証します。任意の証明書をそのまま信頼するわけではありません。サーバーが接続先サイトの秘密鍵を取得することも、一般に信頼される代替証明書を接続先サイト向けに発行することもありません。「証明書の特徴を借りる」という表現は概要をつかむのに便利ですが、証明書を複製すれば任意のサイトになりすませるという意味ではありません。

REALITYの認証に失敗した接続は、設定された接続先サイトに転送できます。アクセスした側には、そのサイト本来のTLS動作が見えます。そのため接続先サイトは、適当に入力してよい飾りの項目ではありません。サーバーから接続先サイトへ到達できるか、TLS 1.3に対応しているか、接続がどのように動作するかは、設定の品質に影響します。Xrayの新旧バージョンでは、サーバー側の接続先項目がtargetまたは旧名称のdestと表示される場合があります。実行バージョンに合わせて確認してください。

3. Visionが軽減する二重暗号化の層

ブラウザーでHTTPSサイトにアクセスすると、ブラウザーと接続先サイトの間にはすでにTLSの層があります。その通信全体をプロキシの外側のTLSでさらに包むと、アプリケーションの暗号文に外側のTLSレコード処理と暗号化が重ねて適用される場合があります。プロキシサーバーでは外側の通信の復号と転送も必要になり、計算処理やデータ移動の負荷が増えます。ただし、負荷の増加量は実装、ハードウェア、トラフィックの種類によって異なります。

段階・トラフィックVisionの処理方法ここからは判断できないこと
接続開始時とプロキシ要求外側の安全なハンドシェイク、認証、必要なプロトコル処理を完了します。最初のバイトから安全な通信経路を迂回するわけではありません。
判定条件を満たす内側のTLS 1.3トラフィック安全に切り替えられる条件がそろうと、直接コピーする経路に切り替わり、外側のTLSを重ね続ける負荷を軽減できます。すべてのHTTPS接続が必ずこの経路に切り替わるわけではありません。
通常の平文データ、または切り替え条件を満たさないトラフィックそれぞれに応じた保護付きの転送経路で処理されます。すべてのデータで暗号化が1層省かれるとは限りません。
システム下位層でのデータ転送コア、OS、接続条件が許せば、より効率的なデータ転送方式を利用できる場合もあります。Visionを有効にしても、必ずゼロコピーになるわけではありません。

ここでいう「直接コピー」は、Webページの平文がネットワーク上にさらされるという意味ではありません。この経路を通るデータも、ブラウザーと接続先サイトの間のTLSで保護されています。Visionは内側のプロトコル状態を判定して経路を切り替えるものであり、単純に暗号化を無効にするものではありません。条件を満たさない場合にこの説明を当てはめることもできません。

確認方法:まずフロー制御の一致を確認し、その後スループットを比較

まずクライアントとサーバーの両方でxtls-rprx-visionが設定されていることを確認します。そのうえで同じ回線、同じHTTPSの大容量ファイル、近い時間帯でCPU使用率とスループットを比較してください。Webページを一度開いただけでは直接コピー経路が機能したか判断できず、一定の速度向上率を示すこともできません。

4. インポート後に確認する設定項目

サブスクリプションから大半のパラメーターを設定できる場合が多いものの、更新時の項目欠落、手動編集、コアのバージョン差によって接続に失敗することがあります。まず元のインポート設定を保存し、複製した設定を項目ごとに変更してください。一度に変更するのは1項目だけにすると、ログの変化と設定変更を対応させやすくなります。

TLS 1.3
この記事で扱うハンドシェイクと内側の切り替えに関する主要バージョン
443
一般的な接続先HTTPSポート(必須ではありません)
16
shortIdで使える16進数の上限(文字数は偶数)
  1. サーバーアドレスとポート:プロキシサービスが実際に待ち受けている場所を指定します。接続先ポートの443と、クライアント側のローカルSOCKS待ち受けポートは別の項目であり、入れ替えることはできません。
  2. UUIDとflow:UUIDはサーバー側のVLESSユーザーに対応します。クライアントのflowは、そのユーザーに対するサーバー側の設定と一致させてください。xtls-rprx-visionを指定しても、Visionが有効になっていないサーバーが自動的に対応するわけではありません。
  3. 公鍵:サーバー側のREALITY秘密鍵に対応する公鍵を指定します。Webサイトの証明書テキストではありません。共有リンクでは通常、pbkにこの値が含まれます。GUIとコアのJSONでは、バージョンによって項目名が異なる場合があります。該当バージョンのドキュメントで確認し、リンクのパラメーター名をそのままJSONの項目名として使わないでください。
  4. SNIとフィンガープリント:serverNameはサーバー側で許可された名前の範囲内に設定します。fingerprintのchromeはClientHelloのフィンガープリントを指定する値です。端末上のブラウザーを変更するものでも、すべてのネットワーク上の特徴を隠すものでもありません。
  5. shortId:クライアントの値は、サーバー側の許可リストにある項目と一致させてください。16進数で指定し、最大16文字、文字数は偶数にします。サーバー側で空の値が許可されている場合に限り、クライアント側も空欄にできます。

v2rayNGでは、該当する設定を長押しして「編集」を開き、サーバーアドレス、ポート、通信のセキュリティ、SNI、公鍵などを確認できます。画面上の項目名はバージョンにより多少異なります。v2rayNでは設定をダブルクリックして編集画面を開き、実際に選択されているコアも確認してください。トラブル対応のために「証明書を検証しない」などの設定を有効にしないでください。REALITYの公鍵認証の代わりにはなりません。

5. ハンドシェイク・プロキシ要求・アプリの通信を分けて確認

「ノードに接続できない」には、複数の異なる原因があります。TCPポートに到達できない場合、SNIを変更しても解決しません。REALITY認証に失敗している場合、ルーティングルールを変更しても解決できません。すべてのパラメーターを適当に入れ直すのではなく、接続の順序に沿って情報を集めてください。

  1. まず接続先を確認:サーバーアドレス、実際のポート、サーバーの待ち受け状態、ファイアウォールのルールを確認します。タイムアウトと接続拒否は異なる状態です。タイムアウトの場合は、回線のパケットロスやフィルタリングも考えられます。
  2. 次にハンドシェイク認証を確認:公鍵、SNI、shortId、フィンガープリントの設定を照合します。サーバー側でハンドシェイク時の時間差制限を設定している場合は、鍵の誤りと誤認しないよう、両端のシステム時刻が同期しているかも確認してください。
  3. 続いてVLESSユーザーを確認:ハンドシェイク完了後も失敗する場合は、UUID、flow、サーバー側のユーザー設定を確認してください。外側の接続が確立しても、プロキシ要求が受け付けられたとは限りません。
  4. 最後にアプリの通信経路を確認:アプリの通信がクライアントに届いていることを確認し、続いてDNS、ルーティングルール、サーバー側の出口を調べます。接続成功のログがあっても、ブラウザーの通信がそのプロキシを経由した証拠にはなりません。

公鍵とUUIDを設定しても、ハンドシェイクに失敗するのはなぜですか?

まず元のサブスクリプションから設定を複製し、SNI、shortId、通信のセキュリティがREALITYになっているかを項目ごとに照合してください。次に、秘密鍵の変更後にサーバーの公鍵も更新されているか確認し、同じ時刻の両端のログを見てください。遅延テストの結果だけで判断しないでください。

接続はできるのにWebページが開けません。フィンガープリントを変更すべきですか?

まずブラウザーがシステムプロキシまたは指定したローカルプロキシを使っていることを確認し、リクエストがクライアントのログに記録されているか調べてください。リクエストがプロキシに届いている場合は、DNSの名前解決とルーティング先を確認します。ハンドシェイクエラーがないなら、フィンガープリントを何度も切り替えることを優先すべきではありません。

Visionを有効にしても速度が変わりません。設定が反映されていないのでしょうか?

必ずしもそうとは限りません。まず両端のflowを確認し、ダウンロード元とテスト時間帯を固定してCPU使用率とスループットを確認します。回線の帯域、パケットロス、接続先サーバーの速度制限がボトルネックになる場合もあります。小さなWebページでは、データ転送負荷の軽減効果を実感しにくいこともあります。

v2flyNGに切り替えると、同じサブスクリプションをそのまま使えないのはなぜですか?

まず設定がXrayのREALITY・Vision機能に依存していないか確認してください。この種の設定は、該当機能に対応したv2rayNG、または適切なコアを選んだv2rayNで使用してください。クライアント名や通信方式のラベルを変えても、コアの機能差は解消されません。

6. 対応範囲を理解してから設定変更を検討

REALITYでプロキシサーバーのIPアドレスを隠すことはできず、通信が識別されないと保証することもできません。接続先サイトの選択、サーバーの構成、ネットワーク経路、クライアントのバージョンによって実際の動作は変わります。Visionの主なメリットは、条件を満たすデータの転送効率です。物理回線の帯域幅や往復遅延を変えるものではありません。パケットロス、混雑、サーバー負荷は別途確認してください。

最後に確認するのは、画面上に3つの名称が並んでいるかどうかではなく、通信経路全体が正しく動作するかです。クライアントが正しいサーバーに接続し、REALITY認証が通り、VLESSユーザーとフロー制御が一致し、アプリのリクエストが想定どおりにルーティングされる必要があります。各層を分けて考えると、設定やトラブル対応を再現しやすくなります。

v2rayN / v2rayNG ダウンロード