CONFIGURATION REFERENCE

V2Ray設定ファイル完全ガイド

JSON構造・インバウンドとアウトバウンド・ルーティングとDNS・ポリシーと検証

このページでは設定項目ごとに解説します。インストール後、パラメーターの意味や接続時の動作を確認したい方に適しています。初めて使う場合は、まず使い方ガイドを読み、サブスクリプションの追加、ノードの選択、プロキシ設定、接続確認の順に進めてください。その後、このページで詳細を確認できます。クライアントをまだインストールしていない場合は、クライアントをダウンロードからOSに合ったものを選んでください。デスクトップでは、v2rayNの設定画面を確認するのがおすすめです。

JSON構造の概要:オブジェクト、配列、参照関係

まずデータの流れを把握する

設定ファイルはノードのパラメーターを並べたものではなく、リクエストの処理経路を定義するものです。アプリからのリクエストはインバウンドに入り、ルーティングがリクエストの属性に応じてアウトバウンドを選びます。アウトバウンドは接続先またはプロキシサーバーへの接続を開始します。DNSはドメイン名の解決が必要な箇所にアドレスを提供し、ポリシーは接続のライフサイクルや統計を制御します。項目を一つずつ読む前に、まずこの流れを把握すると、各モジュールの関係を理解しやすくなります。

トップレベルは通常、オブジェクトで、波括弧内にモジュールを名前付きで配置します。inboundsとoutboundsは配列です。1つのプロセスで複数の入口を待ち受けたり、複数の出口を用意したりできるためです。routing、dns、policyは通常オブジェクトです。配列の要素はカンマで区切り、最後の要素の後にはカンマを付けません。真偽値はtrueまたはfalse、ポートは通常数値、プロトコル名やタグは文字列で指定します。画面上の文字をすべてそのまま引用符で囲めばよいわけではありません。

以下は、ローカルで構造を検証するための完全なダイレクト接続設定です。ループバックアドレスでSOCKSの入口を公開するだけで、リモートプロキシノードは含みません。すべてのリクエストはローカルネットワークから送信されます。コアが設定を読み込めること、アプリが待ち受けポートに接続できること、ログにリクエストが記録されることを確認するためのものです。リモートプロキシへの接続が確立したことを意味するものではなく、ダイレクト接続の成功からサブスクリプションの設定が正しいと判断することもできません。テスト後は、引き続き使うクライアント設定を明確に選んでください。

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    }
  ],
  "routing": {
    "domainStrategy": "AsIs",
    "rules": []
  }
}

タグは設定内の接続先を示す識別子

tagは内部識別子であり、表示名を必ず翻訳するものではありません。ルーティングのoutboundTagは、対象アウトバウンドのタグと大文字・小文字を含めて完全に一致させる必要があります。inboundTagはルールを適用する入口を限定します。タグは短く分かりやすい名前にし、同じ種類のオブジェクト間で重複しないようにしてください。アウトバウンドのタグを変更する場合は、それを参照するルーティング側も合わせて変更します。そうしないと、設定ファイルを読み込めても、実行時やリクエスト転送時に参照先が見つからないことがあります。

設定項目を省略することと、空の値を明示的に指定することは異なります。省略可能な項目を省くと、通常は実装の既定動作が使われます。null、空文字列、空オブジェクトを指定しても、同じ結果になるとは限りません。例をコピーする際は項目の階層を確認してください。streamSettingsをプロトコルのアカウントオブジェクト内に置いたり、rulesをトップレベルに直接置いたりしないでください。JSON構文の検証に通るのは、括弧やデータ型などの形式が正しいことを示すにすぎず、コアがその項目を認識する保証にはなりません。

クライアント生成設定と手動設定の違い

GUIクライアントは、ノード、ルーティングのテンプレート、DNSの設定に応じて実行時の設定を再生成することがあります。一時ファイルを直接編集しても、次回のノード切り替えや再起動で上書きされる可能性があります。長期的に使う設定は、まずクライアントの該当項目から変更してください。完全なJSONを主な管理対象にするのは、カスタム設定をインポートする運用を明確に選んだ場合に限ります。エクスポートした設定にはサーバーアドレスやアカウント情報が含まれることがあります。トラブルシューティング用に共有する前に削除し、項目構造と必要なエラー情報だけを残してください。

XrayとV2Flyには共通する従来の設定構造が多くありますが、新機能、別名、既定値まで常に一致するとは限りません。このページの従来形式はデータの流れを理解するためのもので、異なるコア間の互換性を保証するものではありません。「不明な項目」や「不明なトランスポート形式」が出た場合は、まず実行中のコアを確認し、そのコアが使う設定形式を調べてください。異なる設定形式の項目名を同じファイルに混在させないようにしましょう。プロトコル、トランスポート、セキュリティ層、クライアントの違いは用語集で確認できます。設定を探す階層を間違えないために役立ちます。

inbounds(インバウンド):待ち受けアドレス、ポート、トラフィック検出

待ち受けアドレスで接続できる範囲が決まる

インバウンドは、クライアントがアプリからのリクエストをどこで受け取るかを定義します。デスクトップでよく使われるSOCKSの入口はSOCKSプロキシに対応したアプリの通信を受け取り、HTTPの入口はHTTPプロキシとして送信されたリクエストを受け取ります。ここでいうプロトコルはローカルアプリとクライアントの間の通信方式であり、リモートノードのVMessやVLESSとは異なります。アプリで設定するプロキシの種類はインバウンドと一致させてください。HTTPプロキシにしか対応していない設定欄にSOCKSのポートを入力しても、ポートに接続できるだけで正しいプロトコルに変換されることはありません。

listenを127.0.0.1にすると、入口はローカルのIPv4ループバック接続だけを受け付けます。0.0.0.0に変更すると、ローカルのすべてのIPv4インターフェースで待ち受けますが、家庭内ネットワークだけに限定されるわけではありません。ほかのネットワークにも接続している場合は、そのインターフェースでもサービスが公開される可能性があります。LAN内で共有するには、OSのファイアウォール、接続元の制限、入口の認証も検討してください。クライアントの設定を一つ有効にしただけで、アクセス範囲が制限されたと判断してはいけません。

portはローカルの待ち受けポートで、ノードサーバーのポートとは別です。ローカルポートを変更したら、ブラウザー、開発ツール、プロキシを手動設定したアプリも更新してください。ポートが使用中の場合は、別のクライアントが起動していないか、ほかのプログラムが待ち受けていないかを確認します。ノードを何度も切り替えるだけでは解決しません。ログにバインド失敗が出ている場合、ローカルの入口を作成する段階で問題が発生しており、まだリモートプロトコルのネゴシエーションには進んでいません。この段階では、サーバーのUUID、TLS、ルーティングを変更しても待ち受けの競合は解決できません。

{
  "inbounds": [
    {
      "tag": "socks-in",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": ["http", "tls"],
        "routeOnly": true
      }
    }
  ]
}

SOCKS、UDP、システムプロキシはそれぞれ別の設定

例のudpは、SOCKSインバウンドがUDPリクエストを処理することを許可します。ただし、SOCKSを使っていないアプリの通信を自動的にプロキシへ流すものではなく、その後のアウトバウンドやリモートサービスがUDPに対応することも保証しません。通信経路全体には、アプリがSOCKSのUDP ASSOCIATEを使うか、システムネットワークが転送を許可するか、リモートのプロトコル構成がUDPを運べるかが関わります。切り分けでは、まずこの方式に明確に対応したアプリでテストしてください。ブラウザーでページが開けただけで、すべてのUDP通信が検証済みだと判断しないでください。

システムプロキシが影響するのは、通常、システムのプロキシ設定に従うアプリです。端末上のすべての通信がプロキシ経由になるわけではありません。アプリがシステム設定を無視したり、接続先へ直接接続したりする場合、クライアントが起動中でもリクエストがインバウンドに入るとは限りません。クライアントの仮想NICや透過的な通信の取り込みは別の仕組みで、ルーティング、権限、DNSの設定も必要です。この記事では明示的なプロキシ設定を前提に説明します。実際にどの入口を使っているかを確認し、該当するログからリクエストがコアに届いているかを判断してください。

sniffingで取得した情報の用途

sniffingは、取り込んだ通信のプロトコル特性から、HTTPのホスト名やTLSハンドシェイクのサーバー名などの宛先情報を抽出しようとします。すべてのアプリ通信を復号する機能でも、あらゆる接続からドメイン名を復元できる機能でもありません。アプリが宛先IPだけを渡し、通信の特徴からも名前を特定できない場合、ドメインルールに使える情報がないことがあります。検出を有効にしても、一部のルーティング情報を補うだけです。アプリのプロキシ設定やDNS設計の代わりにはなりません。

destOverrideは検出を試みる情報の種類を指定します。routeOnlyは、検出した情報をルーティングにだけ使い、元の宛先を保持する意図を示します。このオプションは、まず現在のコアが対応しているか確認してください。クライアント画面に同じ名前の設定があっても、すべての実装で動作が一致するとは限りません。ドメインルールの診断では、有効化前後の宛先記録とアウトバウンドの選択を比較します。名前を取得できていないのか、ルールに一致していないのか、それとも一致後により上位のルールに処理を移されているのかを確認できます。

入口を共有する必要がある場合は、まずローカル限定の基本設定で動作を確認してから、待ち受け範囲とアクセス権を段階的に広げてください。待ち受け、認証、システムプロキシ、ノードの設定を同時に変更すると、接続失敗時にローカルアクセスの拒否と上流のハンドシェイク失敗を区別できません。設定後は、信頼できる別の端末から許可した接続経路を確認し、公開すべきでないインターフェースが開いていないかも調べてください。GUIでの接続手順は使い方ガイドに戻って順に確認できます。

outbounds(アウトバウンド):プロトコルのアカウント、既定の出口、タグ

アウトバウンドは次の接続先を定義する

アウトバウンドは、リクエストを受け取ったコアが次にどのように接続するかを決めます。freedomは宛先への直接接続、blackholeは通信の遮断を表します。VMessやVLESSなどのプロトコルを使うアウトバウンドは、指定されたプロキシサーバーへリクエストを送ります。リモートノードのアドレスは次の接続先であり、ユーザーが最終的にアクセスするWebサイトではありません。設定を読む際は、サーバーアドレス、最終的な宛先、DNSサーバーを分けて記録してください。いずれもドメイン名やポートを含む場合がありますが、通信経路での役割は異なります。

従来の設定形式では、ルーティングルールに一致しないリクエストは通常、outbounds配列の先頭のアウトバウンドに渡されます。そのため、アウトバウンドの順序には意味があり、単なる表示順ではありません。directを先頭に移すと、ルールに一致しなかった通信の経路が変わります。誤解を防ぐには、既定の出口を明示し、ルーティングの末尾にも意図したフォールバックルールを用意してください。変更後は新しい接続で確認しましょう。すでに確立済みの接続は、設定変更後すぐに経路が切り替わるとは限りません。

以下はVLESSアウトバウンドの構造例です。サーバーとアカウントの項目だけを示しており、トランスポートのセキュリティが設定済みで接続可能なノードを表すものではありません。example.comは説明用のアドレスで、すべてゼロのUUIDはデモ用です。実際の構築ではサーバーから提供された値を使用してください。ポートが443だからといってTLSが有効とは限りません。ポート番号が決めるのは接続先だけであり、安全な接続を確立するかどうかは対応するトランスポート設定とサーバー側の構成によって決まります。

{
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "example.com",
            "port": 443,
            "users": [
              {
                "id": "00000000-0000-0000-0000-000000000000",
                "encryption": "none"
              }
            ]
          }
        ]
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ]
}

アカウント項目を異なるプロトコル間で流用しない

VLESSのencryptionにnoneを指定するのは、このプロトコル層の設定です。接続全体に保護がないという意味ではありません。実際のセキュリティ層はstreamSettingsで確認します。VMessはアカウント設定の項目やネゴシエーションの仕組みが異なるため、両者のユーザーオブジェクトをそのまま入れ替えることはできません。ノード共有リンクのパラメーターには省略形や別の名前が使われる場合もあります。インポート後は、リンクのクエリパラメーターを一つずつJSONに貼り付けるのではなく、クライアントが解析したプロトコルの種類を起点に確認してください。

アカウント情報、トランスポート方式、サーバーの対応状況をすべて整合させる必要があります。UUIDが正しくてもトランスポートが違えば、アカウント認証前に切断されることがあります。セキュリティ層の確立に成功しても、認証情報が誤っていればプロキシリクエストは完了しません。ログにサーバーへの接続が記録されていても、アカウント認証の成功を意味するわけではありません。2つのプロトコルの違いはVMessとVLESSの違いを比較で確認し、実際のノードの項目を照合してください。

ダイレクト接続とブロックにも明示的な名前が必要

direct、proxy、blockはこの記事で使うタグ名であり、コアが自動作成する固定オブジェクトではありません。ルールにoutboundTag: "block"と書いた場合は、対応するアウトバウンドが必要です。ダイレクト接続でも、ドメイン名の解決、IPv4とIPv6の選択、OSのルーティング、ローカルファイアウォールの影響を受けます。すべてのネットワーク設定を迂回できるわけではありません。ある宛先への直接接続が失敗しても、プロキシのアウトバウンドが壊れているとは限らないため、2つの経路を別々にテストしてください。

クライアントが複数のノードに対応していても、実行時設定ですべてのアウトバウンドが同じ形で並ぶとは限りません。現在のノードだけを生成するモードもあれば、追加のアウトバウンドや内部経路を生成するモードもあります。ノードを切り替えた後、手書きのルールが存在しないタグを参照して無効になることがあります。長期的に管理する場合は、クライアントで固定できるルーティング先を優先し、最終的に適用される設定を確認してください。一度のエクスポートで見た一時的な名前に依存しないようにしましょう。同名のアウトバウンドが複数あると参照先が曖昧になるため、重複は避けてください。

サブスクリプションの更新で、サーバーアドレス、ポート、トランスポート設定、ノード識別子が変わることがあります。古いアドレスに新しいアカウント項目をつなぎ合わせたり、異なるノードのセキュリティ設定を混在させたりしないでください。まず動作しているクライアント設定を保存し、更新をインポートしたらノードを一つずつテストします。共有リンクとネイティブ設定の対応関係はサブスクリプション形式と共有リンクの比較で確認し、サブスクリプションのコンテナ、ノード情報、最終的な実行設定を区別してください。

routing(ルーティング):ルールの順序、条件、フォールバック

上から順に確認し、最初に一致したルールを適用

ルーティングは、コアに届いたリクエストの属性に応じて出口を選択します。まだコアに届いていないアプリの通信を自動的に取り込む機能ではありません。従来形式のフィールドルールは通常、配列の順に評価され、最初に条件を満たしたルールの結果が適用されます。上にあるルールほど優先順位が高くなります。まず確認すべきなのは、一覧に目的のルールが存在するかだけでなく、そのルールに到達する前に別のルールで処理されていないかです。すべての通信に一致する広範なルールは後ろに置きましょう。先に置くと、その後の細かなルールが評価されません。

同じルール内では、異なる種類の条件をすべて満たす必要があるのが一般的です。同じ配列内の候補値は通常、いずれか一つに一致すればよいという意味です。たとえばinboundTagとdomainを同時に指定したルールは、指定した入口から届き、かつドメイン条件にも一致することを意味します。入口またはドメインのどちらか一方だけでよいという意味ではありません。独立した2つのケースを表したい場合は、すべての項目を1つのルールに詰め込むより、2つのルールに分けるほうが明確で、ログを使った切り分けも簡単です。

{
  "routing": {
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        "type": "field",
        "inboundTag": ["socks-in"],
        "domain": ["full:example.com"],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "ip": [
          "10.0.0.0/8",
          "172.16.0.0/12",
          "192.168.0.0/16",
          "127.0.0.0/8",
          "::1/128",
          "fc00::/7",
          "fe80::/10"
        ],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "network": "tcp,udp",
        "outboundTag": "proxy"
      }
    ]
  }
}

ドメインルールとIPルールの違い

full:example.comはドメインの完全一致を表します。domain:example.comは、そのドメインとサブドメインに一致します。プレフィックスのない文字列や正規表現にはそれぞれ異なる意味があるため、見た目が似ているだけで同じ範囲に一致すると考えてはいけません。特定サイトの例外を設定する場合は、まず完全一致で動作を確認し、必要に応じて範囲を広げます。正規表現はJSON文字列としてエスケープする必要があります。バックスラッシュの階層を誤ると、ファイルを読み込めてもルールの意味が変わることがあります。

IPルールが照合するのは宛先アドレス、またはルーティング中に得られた解決済みアドレスです。ブラウザーのアドレスバーにあるドメイン名を、そのままIPアドレスとして比較するわけではありません。アプリがIPだけを送信し、ドメイン名の情報が得られない場合、ドメインルールは適用されないことがあります。逆に、アプリがドメイン名を送信したときに追加の名前解決を行うかどうかは、domainStrategyに左右されます。ドメインリストを完全に整備しても、入口にリクエストが届かない、宛先情報がない、ルールの順序が誤っているといった問題は解決しません。

戦略ルーティング段階での主な動作確認ポイント
AsIsルーティングのためにドメイン名をIPアドレスへ能動的に解決しない。既存のドメインルールで十分か。
IPIfNonMatchドメインに一致しない場合に名前解決し、IPルールを試す。フォールバックルールで照合が早期終了していないか。
IPOnDemandIP条件が必要になった時点で名前解決する。名前解決の依存関係とルールの並び順。

IPIfNonMatchは、すべてのリクエストで先に名前解決してからルールを照合するという意味ではありません。ドメインの段階で広範なルールに一致すると、想定していたIP照合まで進まない場合があります。例の末尾にあるnetworkルールは明示的なプロキシのフォールバックです。使う際は名前解決戦略との組み合わせに注意してください。ドメイン名のリクエストで、解決結果を使ってプライベートIPかどうかを先に判定したい場合は、ルールを設計し直すか、適切な名前解決戦略を選びます。先に書いたプライベートIP一覧がすべてのドメインリクエストに必ず優先適用されると考えてはいけません。

リソースファイルとルールの結果を分けて検証

geosite:やgeoip:形式を使うには、クライアントまたはコアが対応する分類データを読み込める必要があります。カテゴリ名が存在するか、データを利用できるか、どのように更新されるかを実環境で確認してください。リソース不足は設定の依存関係の問題であり、ドメイン分類が想定と異なる場合はデータの収録範囲の問題です。混同しないようにしましょう。最初の検証では、具体的なドメイン名とIP範囲を使ってルーティングの動作を確認し、その後で分類データを追加すると、未知の要因を一度に抱えずに済みます。

ルールを検証する際は、入口タグ、リクエストの宛先、トランスポートの種類、最終的に選ばれたアウトバウンドを記録し、条件を一つずつ変更します。既存のWeb接続、バックグラウンドの接続プール、アプリのキャッシュが古い経路を使い続ける場合があります。元の接続を閉じて新しいリクエストを送るのがおすすめです。ルールへの一致が示すのは、コアが出口を選択したことだけで、リモートへの到達を保証するものではありません。正しいアウトバウンドが選ばれているのに失敗する場合は、すでに確認できたルールの順序を変え続けるのではなく、アウトバウンドのハンドシェイク、DNS、接続先サービスを調べてください。

dns設定:名前解決の経路、対象範囲、接続の依存関係

まず、どのコンポーネントが名前解決しているかを確認

1つのリクエストに、アプリ内蔵のDNS、システムのリゾルバー、コア内蔵のDNS、リモートプロキシ側の名前解決が関わる場合があります。トップレベルにdnsを設定しても、端末上のすべてのアプリの名前解決がその経路に切り替わるわけではありません。明示的なプロキシでは、アプリがドメイン名をプロキシに渡す場合と、先に名前解決してIPアドレスだけを渡す場合があります。ルーティングで利用できる情報はそれぞれ異なります。問題を調べる前に、クライアントのDNS設定画面にどのサーバーが入力されているかだけでなく、アプリがどの形式の宛先を渡しているかを確認してください。

内蔵DNSは主に、ルーティング戦略がIPアドレスを必要とする場合、一部のアウトバウンドが宛先を解決する場合、ドメイン接続時に名前解決が必要な場合など、コア内での名前解決に使われます。実際に内蔵DNSが使われるかは、該当モジュールとオプションにも左右されます。システムプロキシを設定しても、通常はOSのDNS設定が書き換わるわけではありません。Webページは表示できるのに別のアプリで問題が起きる場合、そのアプリが異なる名前解決経路を使っている可能性があります。アプリの通信経路と名前解決元を別々に検証し、失敗をすべてDNSサーバーの不安定さのせいにしないでください。

以下の部分設定は、公開DNSアドレスを使ってサーバー一覧と静的マッピングの構造を説明します。hosts内のテスト用ホスト名は、ドキュメント用に予約されたアドレスを指しており、実際のWebサイトは提供しません。実環境で使う際はこのデモ用マッピングを削除し、ネットワークからの到達性、名前解決の要件、プライバシーに応じてDNSサービスを選んでください。すべての環境で例のアドレスを使う必要はなく、現在のネットワークに適したアクセス結果が得られるとも限りません。

{
  "dns": {
    "hosts": {
      "full:resolver-test.example": "192.0.2.10"
    },
    "servers": [
      "1.1.1.1",
      "8.8.8.8"
    ],
    "queryStrategy": "UseIP"
  }
}

名前解決の対象範囲とフォールバック動作を合わせて考える

DNSサーバーのオブジェクトには、address、domains、expectIPsなどを指定し、DNSサービスのアドレス、優先するドメイン範囲、期待する結果を定義できます。ドメインの範囲指定は、単純なアクセスルールではありません。あるDNSサーバーで名前解決されたからといって、Webサイトへの接続も同じアウトバウンドを通るとは限りません。名前解決の経路と実際の通信経路を別々に設定し、両者が意図どおりか確認してください。DNSサーバーのグループを、ルーティングのプロキシ用・ダイレクト接続用グループと同じものと考えてはいけません。

これらの項目に対応する従来形式の設定では、expectIPsで名前解決結果が期待どおりかを確認します。skipFallbackなどのフォールバック関連オプションは、一致しない場合や結果が想定と異なる場合の処理に影響します。コアによってフォールバックの詳細が異なるため、実際の実装を確認してください。複数のサーバーを記述したからといって、常に記載順に一つずつ試すとは限りません。予備サーバーを一つ設定すれば、すべての失敗をカバーできるとも限りません。ログで実際の問い合わせと応答を確認してから、対象範囲を絞り込むか判断してください。

queryStrategyは、内蔵DNSが問い合わせるアドレスファミリーに影響します。一般的な値はUseIP、UseIPv4、UseIPv6です。IPv4だけを返すようにすると、一部のIPv6経路の問題を避けられる場合がありますが、システム全体でIPv6を無効にするわけではなく、あらゆる接続障害を恒久的に解決する方法でもありません。OSのIPv6ルーティング自体が使えない場合は、まず問題の箇所を特定してください。アプリ内蔵のリゾルバーが、この問い合わせ戦略に従うとも限りません。

DNSサーバーへの接続経路も必要

暗号化DNSを使う場合は、問い合わせ内容だけでなく、DNSサービスへの接続方法と、そのサービスのドメイン名を誰が解決するかも検討してください。プロキシサーバーのアドレス解決にDNSが必要で、そのDNSへの接続も、まだ確立されていない同じプロキシに依存していると、起動時に循環依存が起きることがあります。設計時には、必要な初期名前解決の経路を明示し、現在のコアが該当するDNSプロトコルをどうサポートしているか確認してください。サーバー一覧にHTTPSのURLを入力しただけで、接続の依存関係が自動的に解決するわけではありません。

hostsは少数の名前を明示的にマッピングできますが、WebサイトのIPアドレスを長期間固定すると、負荷分散、アドレス変更、証明書の利用と衝突することがあります。トラブルシューティングに使う場合は、変更前の結果、マッピング後の差分、元に戻す方法を記録してください。DNSを変更した後も、OS、アプリ、コアにキャッシュが残っていることがあります。新しいリクエストで検証し、必要に応じてクライアントの手順に従ってキャッシュを消去するか、関連プロセスを再起動してください。ページを再読み込みしただけでは、名前解決が再実行されるとは限りません。

結果を比較する際は、単にページを「開けるか」だけでなく、問い合わせのタイムアウト、空の応答、アドレスファミリーへの到達不可、その後の接続失敗を区別してください。ドメイン名を解決できても、接続先ポートで拒否されるなら問題は接続層にあります。IPアドレスへの直接接続はできるのにドメイン名では失敗する場合は、セキュリティ層が要求するサーバー名も確認してください。関連用語はルーティングとDNSの用語集で確認し、このページの検証手順に沿って原因の範囲を絞り込んでください。

policy(ポリシー):ユーザーレベル、タイムアウト、統計

ポリシーはアウトバウンド選択ルールではない

policyは接続処理と統計に関する動作を管理し、ドメイン名に応じてプロキシの出口を選ぶ機能ではありません。ルーティングのdomainStrategy、DNSの問い合わせ戦略、ユーザーレベルのポリシーはそれぞれ異なる層の設定です。画面上でいずれも「ポリシー」と表記されていても、相互に置き換えることはできません。Webサイトへの接続をダイレクト接続にするかプロキシ経由にするかを変える場合はルーティングを確認してください。接続が一定時間アイドル状態になった後に終了する理由を調べる場合は、タイムアウト、アプリの動作、サーバー側の制限を確認します。

levelsは、レベル番号をキーにしたオブジェクトです。JSONではキーも文字列として記述するため、たとえば"0"となります。一方、アカウントオブジェクトのlevelは通常、数値です。レベルはユーザーや該当する処理を一連のポリシーに関連付けるためのもので、ノードの速度評価でも、画面上のノード表示順でもありません。レベルを明示しない場合、多くの設定では既定レベルが使われますが、対象モジュールや既定の動作は現在のコアで確認してください。

{
  "policy": {
    "levels": {
      "0": {
        "handshake": 8,
        "connIdle": 300,
        "uplinkOnly": 2,
        "downlinkOnly": 5,
        "statsUserUplink": false,
        "statsUserDownlink": false
      }
    },
    "system": {
      "statsInboundUplink": false,
      "statsInboundDownlink": false,
      "statsOutboundUplink": false,
      "statsOutboundDownlink": false
    }
  }
}

タイムアウトが適用される段階を理解する

handshakeは、このポリシーに対応するプロトコル処理で、ハンドシェイク完了を待つ時間を制限します。すべてのネットワーク接続段階に共通する総タイムアウトではありません。サーバーへの接続、TLSネゴシエーション、プロキシプロトコルの認証、アプリのリクエストには、それぞれ異なる状況があります。例の値は単位と構造を説明するための目安であり、すべてのネットワークに最適な推奨値ではありません。ネットワークが不安定な場合に値を少し大きくすると役立つこともありますが、認証情報の誤りは待ち時間を延ばしても解消しません。

connIdleは、通信がない状態の接続を維持できる時間を表します。短く設定しすぎると、長時間通信のなかったセッションを再利用する際に影響することがあります。長く設定すると、アイドル接続がより多くのリソースを占有する可能性があります。接続の維持にはアプリ、リモートサービス、途中のネットワーク機器も影響するため、長時間接続が一度切れただけで、この項目が有効になったと判断しないでください。切断前に通信があったかを確認し、クライアントとサーバーのログから、どちらが接続を終了したかを調べましょう。

uplinkOnlyとdownlinkOnlyは、片方向のデータ送信が終了した後、もう一方の方向で通信を続けられる待機時間を設定します。ここでいう上り・下りは接続処理の方向を指し、帯域幅の上限ではありません。ダウンロード完了後に上り方向が閉じられた場合や、アプリが接続を半閉鎖した場合に、接続終了までの処理へ影響することがあります。ダウンロード速度の制御には使えず、「高速化」のために安易にゼロにしないでください。まず問題が接続確立、データ転送中、接続終了のどの段階で起きるかを確認してください。

項目グループ制御対象意味しないもの
handshake該当プロトコルのハンドシェイク待ち時間。すべての接続段階に共通するタイムアウト。
connIdle接続のアイドル時間。ネットワークのスループットやノードの優先順位。
statsUserUplinkユーザートラフィックの計測を有効にする設定。可視化された統計画面の自動生成。

統計の有効化と表示は別に設定する

ユーザー統計を有効にするには、通常、トップレベルの統計モジュール、識別可能なユーザー情報、統計を読み取るAPIまたはクライアント機能も必要です。statsUserUplinkをtrueにしただけでは、トラフィックグラフは自動的に表示されません。対応するユーザー識別子や統計の種類もプロトコルによって異なる場合があります。統計が空の場合は、すぐにプロキシ接続の失敗を疑うのではなく、実際の通信がどの入口とアカウントを通ったか、該当する計測が有効になっているかを確認してください。

システム全体のインバウンド・アウトバウンド統計は該当するオブジェクトごとに集計され、ユーザー統計はアカウント単位で処理されます。計測位置、再接続、接続の再利用、カウンターのリセットによって結果が異なることがあるため、どの時点でもすべての数値が完全に一致するとは限りません。クライアントに表示される速度は、設定に固定された値ではなく、一定間隔の測定差分から算出される場合もあります。計測の設定変更と同時にルーティングやノードを変えると、データ取得の差を実際の通信経路の変化と誤認する可能性があります。

個人のデスクトップ利用では、まずクライアントが生成したポリシーを維持し、アイドル時の切断、ハンドシェイクの待機時間、統計など、具体的な必要性を確認してから変更してください。変更ごとに元の値、変更理由、検証条件を記録し、元に戻せるようにしておきます。コアのポリシーでは、OSのスリープ、モバイルネットワークの切り替え、リモート側のタイムアウト、アプリの接続プール管理までは制御できません。すべてのタイムアウトを長くしてもエラーの発生を遅らせるだけで、接続品質が改善するとは限りません。根拠のある変更は、一律の「最適化設定」を使うより確実です。

トランスポートとセキュリティ層:streamSettings、TLS、flow

プロトコル、トランスポート、セキュリティ層を分けて確認

ノード設定には、少なくともプロキシプロトコル、通信を運ぶトランスポート、接続のセキュリティという3つの要素があります。VLESSやVMessはプロキシプロトコル、TCPやWebSocketなどはトランスポート方式、TLSやREALITYは関連するセキュリティ機能を表します。画面上で一つの表に並んでいても、これらの名前を同じ項目に入力するわけではありません。接続できない場合は、「プロトコルの種類」だけを何度も切り替えるのではなく、まず3つの要素をそれぞれサーバーの情報と照合し、その後に追加パラメーターを確認すると不一致を見つけやすくなります。

streamSettingsは通常、アウトバウンドのsettingsと同じ階層に配置します。前者は通信を運ぶ接続の確立方法、後者はプロキシプロトコル自体のサーバーとアカウント情報を定義します。以下は、従来形式のWebSocketとTLSの部分的な構造を示す例です。実際のアウトバウンドに組み込む必要があり、サーバー側も対応するサービスを提供していなければなりません。ネットワーク名やトランスポート設定には、コアの進化に伴う別名や仕様変更がある場合があります。コピーする前に、実行中の実装を確認してください。

{
  "streamSettings": {
    "network": "ws",
    "security": "tls",
    "tlsSettings": {
      "serverName": "example.com",
      "allowInsecure": false
    },
    "wsSettings": {
      "path": "/proxy",
      "headers": {
        "Host": "example.com"
      }
    }
  }
}

アドレス、serverName、Hostはそれぞれ用途が異なる

アウトバウンドのaddressは、実際に接続する次の接続先です。serverNameはTLSのサーバー名に関する処理に使います。WebSocketのHostはHTTPリクエストの情報です。適切な構成ではそれぞれ異なる値にできますが、どれも「ドメイン名に見える」からといって自由に置き換えてはいけません。サーバー側がサーバー名やHTTPのホスト名に基づいてサイトを振り分ける場合、アドレスとポートに到達できても、項目の値が誤っていると別のサービスに接続する可能性があります。

pathは、先頭のスラッシュや大文字・小文字、クエリ文字列を含め、サーバー側で合意したWebSocketのパスと一致させる必要があります。HTTP 404やアップグレードの失敗は、アカウント情報ではなく、パスやリバースプロキシの転送設定が合っていないことを示す場合があります。まずリクエストが想定したサービスに届いているかを確認し、その後でプロキシプロトコルの認証を調べてください。TLSハンドシェイクの失敗はそれより前に発生します。その段階ではHTTP層がまだ動作していないため、WebSocketのパスを何度変更しても結果は変わりません。

allowInsecureはfalseのままにしてください。証明書の検証で問題が発生した場合は、まずシステム時刻、サーバー名、証明書の有効期間、サーバーの構成を確認します。検証を無効にすると重要なエラーが隠れ、誤ったサービスへの接続を解決することもできません。環境によっては、追加の信頼済み証明書の設定が必要です。検証全体を無効にするのではなく、実際の証明書チェーンに応じて対処してください。トラブルシューティングの記録には具体的なエラーの種類を残し、「TLSエラー」のような情報不足の説明だけで済ませないようにしましょう。

REALITYとVisionには明確な対応範囲がある

REALITYはXrayエコシステムに関連するセキュリティ機能です。V2Flyやあらゆるインポーターが同じ項目に対応しているとは限りません。サーバーから提供されたサーバー名、公開パラメーター、ショートID、クライアントフィンガープリントを一組として対応させてください。項目名は、現在のコアとクライアントがサポートする形式に従います。複数の解説記事からそれぞれ一部分をコピーして組み合わせたり、別の用途の秘密情報をクライアントに入力したりしないでください。仕組みを詳しく知りたい場合は、REALITYとXTLS Visionの仕組みを解説をご覧ください。

flowは該当プロトコルのアカウント設定にあります。xtls-rprx-visionは、対応するサーバーとトランスポートの組み合わせでのみ使用できます。一般的な速度向上オプションではなく、すべてのVLESSノードに一律で追加するものでもありません。サーバー側で対応するフロー制御が設定されていない場合、クライアント側だけで指定すると接続に失敗することがあります。フィンガープリントも特定のセキュリティ層における設定です。正しいサーバー名の代わりにはならず、名前から実際のブラウザーのネットワーク動作すべてを推測することもできません。

多重化のMuxも、前述のセキュリティ層とは別の概念です。複数の論理リクエストで一つの通信接続を共有する仕組みですが、適切かどうかはプロトコルの対応状況、トランスポートの組み合わせ、通信内容によります。既定で有効にしても高速化が保証されるわけではなく、組み合わせによっては適さない場合もあります。並行接続や長時間接続だけで失敗する場合は、ほかの設定を変えずに比較テストを行ってください。Muxの無効化、flowの変更、フィンガープリントの置き換え、TLSの調整を同時に行うと、どの変更が影響したか分からなくなります。

ノードのインポートに成功した場合に確認できたのは、「項目を解析できた」ことまでです。すべてのトランスポート機能が検証済みだと判断してはいけません。クライアントが別のコアの拡張項目を保持できなかったり、編集画面で保存した際に設定を再生成したりすることがあります。インポート後に重要な項目を確認し、新しい接続でテストしてください。該当機能に対応したクライアントへ切り替える場合は、ダウンロードページから対応プラットフォームを選び、トラブルシューティングの比較対象として元の設定も残しておきましょう。

設定の検証:読み込み、ログによる切り分け、復元

構文、読み込み、実際のリクエストを分けて検証

設定の検証は3段階に分けられます。第1段階はJSON構文で、括弧、カンマ、文字列、データ型が有効かを確認します。第2段階はコアによる読み込みで、現在の実装が項目、プロトコル、リソース、参照先を受け入れるかを確認します。第3段階は実際のリクエストで、アプリが正しい入口に接続し、ルーティングが想定どおりの出口を選び、アウトバウンドのハンドシェイクが成功して、宛先から応答を得られるかを確認します。前の段階に成功しても、後の段階の代わりにはなりません。部分的な例を組み込んだ後は、コピーした部分だけでなく、設定ファイル全体をもう一度検証してください。

GUIクライアントでは、まずクライアント内蔵の設定チェック、ログ表示、コアの再起動機能を使ってください。具体的な操作場所はクライアントによって異なります。変更前に元の設定を保存するかコピーをエクスポートし、変更後は保存が完了したことを確認してからコアを再読み込みします。クライアントが設定を自動生成する場合は、実行フォルダー内の一時ファイルだけでなく、保存した画面上の設定を確認してください。プロセスが存在していても、新しい設定が読み込まれたとは限りません。古いプロセスが動作し続けている場合や、新しいプロセスが起動直後に終了した場合は、ログで状況を判断してください。

問題の切り分け中は、一時的にログの詳細度を上げると確認しやすくなります。以下は、宛先、接続の進行状況、ルーティング結果を短時間観察するための部分設定です。詳細ログにはアクセス先ドメイン、サーバーアドレス、アカウントに関する情報が含まれる場合があるため、長期間保存したり、そのまま公開したりしないでください。必要な証拠を得たら低いログレベルに戻し、不要になった記録はローカルのファイル管理方法に従って処理します。トラブルシューティング情報を共有する際は、該当するエラー行と必要な前後の情報だけを残してください。

{
  "log": {
    "loglevel": "info"
  }
}

データの流れに沿って段階ごとに確認

最初に、リクエストがインバウンドに届いているかを確認します。プロキシ設定に従うことが明らかなアプリから新しいリクエストを送り、該当する宛先がログに記録されるかを見ます。記録がなければ、アプリのプロキシ方式、待ち受けアドレス、ポート、システムプロキシの適用範囲を確認してください。次にルーティングの出口を確認します。ログに表示されたアウトバウンドが想定と異なる場合は、タグの参照、ルールの順序、宛先情報を調べます。この段階でアカウント情報を先に変更する必要はありません。その後でリモートへの接続、セキュリティ層、プロキシプロトコルのハンドシェイクを確認し、最後に接続先サービスからの応答を調べます。

症状まず確認する項目変更を後回しにする項目
起動直後に終了する構文、項目、ポート、リソースの依存関係。Webサイトのドメインルール。
アプリのリクエストがログにないアプリの接続方法とインバウンドの待ち受け。リモートのアカウントとセキュリティ層。
想定と異なるアウトバウンドが選択されるタグ、ルールの順序、宛先情報。すでに接続できているサーバーアドレス。
サーバー接続後に失敗するセキュリティ層、トランスポート、認証情報、サーバーの状態。問題に関係のないローカル待ち受けポート。

エラーの文言は、発生した段階を踏まえて判断してください。「接続が拒否されました」は通常、そのアドレスとポートで接続を受け付けるものがないことを示しますが、ローカル入口の場合もリモートの場合もあります。「タイムアウト」は名前解決、接続確立、応答待ちのいずれでも発生します。証明書エラーの場合は通常、セキュリティ層の状況を確認する必要があります。最後の一語だけを抜き出して結論を出さないでください。エラーの直前に表示された宛先、ポート、使用したアウトバウンドも合わせて記録すれば、どの接続段階の問題か判断できます。前後の情報を残さずに何度もテストを繰り返しても、有用な情報は増えません。

元に戻せる最小限の変更手順を作る

待ち受けポートの修正後に検証してからドメインルールを調整するなど、毎回独立した変数を一つだけ変更してください。ノードの複数項目を同時に変える必要がある場合は、関連する一組を一つの変更単位として扱い、変更前の一式を復元用に保存します。同じアプリ、同じ宛先、新しい接続を使って検証してください。テストごとにWebページと異なるプロトコルのツールを使い分けるのは避けます。特定のアプリだけで問題が発生する場合は、アプリ内蔵の名前解決、接続の再利用、プロキシを迂回する設定も確認してください。

レイテンシテストで確認できるのは、実際に測定対象となった経路だけです。TCP接続が確立してもプロキシ認証の成功は保証されません。実際の接続リクエストが通っても、大容量データの転送が安定するとは限りません。ダウンロード速度が正常でも、すべてのドメインルールが想定どおりとは限りません。測定範囲を理解するには、v2rayNの速度測定方法をご覧ください。ルーティングの問題では出口、名前解決の問題では問い合わせ、スループットの問題では継続的なデータ転送を優先して確認します。一つの数値だけですべての設定状態を判断しないでください。

別の端末や別のコアに移行する場合は、最終的なJSONをコピーするだけで完了と考えないでください。OSの権限、ポートの競合、分類データ、証明書の信頼設定、クライアントによる設定生成が異なることがあります。新しい環境で最小構成の入口と単一ノードへの接続を確認してから、カスタムDNS、ルーティング、ポリシーを段階的に戻してください。ルーターや中継ルーターではOSレベルの転送も関わります。OpenWrtでXrayを実行する構成方法も参考にしてください。デスクトップの明示的なプロキシ設定を、透過プロキシ方式としてそのまま使うことはできません。