JSON · routing · dns · policy

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

ローカルの待ち受けからoutboundの選択まで、各項目の役割や範囲、検証方法を確認できます。

初めて利用する方は、まず使い方ガイドを読み、設定のインポート、モード選択、接続確認を済ませてください。このページでは、コアのJSON設定やルーティングの確認、自作設定の管理方法を解説します。クライアントの基本的な使い方を案内するページではありません。

JSON構造の概要と設定の範囲

設定の出どころを確認してから項目を変更する

V2Rayの設定は、ノード情報を並べた一覧ではありません。通信がどこから入り、どのルールに一致し、プロセスからどう出ていくかを記述するものです。トップレベルのオブジェクトには通常、log、inbounds、outbounds、routing、dns、policyが含まれます。すべての項目が必須というわけではなく、省略時の動作はコアの既定値によって決まります。項目を調べる前に、使用中のコアがXrayかV2Flyか、起動時にクライアントが設定を再生成するかを確認してください。そうしないと、変更したファイルが実際には読み込まれていない可能性があります。

デスクトップでは、まずv2rayNを使うのが一般的です。サブスクリプションを読み込んだ後、画面上でサーバー、システムプロキシ、ルーティングモードを選ぶと、クライアントがコア用の設定に変換します。この場合、サブスクリプションには接続情報、画面上の設定にはユーザーの選択が保存され、実行フォルダー内のJSONは生成結果にすぎないことがあります。それぞれ役割が異なります。トラブル時は生成結果を確認できますが、継続的な変更は画面から設定するか、クライアントが対応するカスタム設定の入口で行ってください。一時的に編集しただけで、クライアントの設定に保存されたと思い込まないようにしましょう。上書きの挙動を理解しないまま同じファイルを繰り返し編集するのも避けてください。

起動確認に使えるローカル直結の基本設定

以下は完全な基本設定です。ローカルのループバックアドレスでSOCKS inboundを待ち受け、受信した接続をfreedom outboundに渡し、ログレベルをwarningにします。リモートプロキシには接続しません。コアが起動するか、ローカルポートが使えるか、テスト対象のアプリが実際にこのinboundを使っているかを確認するのに適しています。ポート番号は例です。クライアントがすでに使用している場合は、競合するプロセスを停止するか、空いている別のポートを選んでください。直結の基本設定で動作を確認できても、ローカルの通信経路が機能していることを示すだけで、リモート設定の正しさまでは確認できません。

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

標準JSONでは、プロパティ名と文字列をダブルクォーテーションで囲み、オブジェクトや配列の最後の要素の後にカンマを付けません。真偽値はtrueまたはfalseとし、ポート番号などの数値はクォーテーションで囲む必要はありません。コメント付きの拡張形式を読み込めるコアのツールもありますが、エディターやクライアントのインポート機能など、他の処理段階で受け付けられるとは限りません。コピーや問題箇所の特定をしやすくするため、ここでは標準JSONを使い、コード内にコメントは加えません。説明はコードの外に記載することで、解析の違いを抑え、部分ごとの置き換えもしやすくなります。

オブジェクト・配列・タグの関係

inboundsとoutboundsは配列です。1つのプロセスで複数の入口を待ち受け、複数の出口を管理できるためです。配列の各要素はオブジェクトです。tagは設定内で参照する名前であり、プロトコル名ではなく、それ自体で機能が作られるわけでもありません。outboundにproxyという名前を付けても、リモートアドレスが設定されたことにはなりません。ルーティングのoutboundTagは、実在するoutboundに対応させる必要があります。大文字・小文字や綴りを含めて一致させ、短く、固定され、意味の明確なタグを使うのがおすすめです。

設定を管理するときは、変更を検証可能な小さな手順に分けてください。まず起動できる基本設定を保存し、次にoutboundを1つ追加し、その後ルーティングルールを1つ加え、最後にDNSやpolicyを調整します。変更のたびに、対象項目、想定する結果、元に戻す方法を記録しましょう。配列の順序は既定の出口やルールの判定に影響することがあるため、見た目を整える目的で並べ替えてはいけません。クライアントを通常どおり使うだけなら、画面から生成される設定を優先してください。特別な動作が必要な場合に限り、手動で管理しましょう。画面上の状態とコアの設定ファイルの両方を管理する複雑さを避けられます。

inbounds:ローカル待ち受けと通信の入口

listen・port・protocolの役割

inboundは、アプリからコアへ渡される接続を受け付けます。listenはバインドするローカルアドレス、portは待ち受けポート、protocolはそのポートで受け付けるリクエスト形式を指定します。どれも欠かせません。正しいポートに接続しても、プロトコルが違えば有効なリクエストを確立できません。SOCKSの入口を通常のHTTPプロキシとしてアプリに設定することはできず、その逆も同様です。トラブル時はポート番号だけでなく、クライアントに表示されている待ち受けプロトコルと、アプリ側のプロキシ種別を一つずつ照合してください。

ローカルアプリだけで使う場合は、通常127.0.0.1で待ち受けます。このアドレスは同じ端末のループバック接続のみを受け付け、LAN内のアドレスとは異なります。また、IPv6のループバックアドレスも自動的に対象になるわけではありません。0.0.0.0で待ち受けると、通常はすべてのIPv4ネットワークインターフェースにバインドされますが、他の端末から接続できるかはファイアウォールやネットワークの分離状況にも左右されます。待ち受け範囲を広げる前に、利用する端末、認証方法、クライアント終了後も待ち受けプロセスが残るかを確認してください。LANからのアクセスを許可することは、単なる接続の最適化ではなく、アクセス可能な範囲を変更することです。

SOCKSとHTTP、2種類の入口を設定する例

以下の設定断片では、別々のポートにバインドする2つの入口を示し、後続のルーティングから参照できるようタグを付けています。SOCKSのudpは、そのinboundでSOCKS UDPリクエストを処理できることを示します。ただし、アプリが実際に該当する仕組みを使い、outboundとネットワーク経路もUDPに対応している必要があります。HTTP inboundは、HTTPプロキシを使うアプリを主な対象とします。入口を2つ設定しただけで、すべてのアプリや通信が自動的に取り込まれるわけではありません。この断片を第1章の基本設定に使う場合は、同じ名前のトップレベル項目を追加するのではなく、inbounds配列全体を置き換えてください。

{
  "inbounds": [
    {
      "tag": "socks-local",
      "listen": "127.0.0.1",
      "port": 10808,
      "protocol": "socks",
      "settings": {
        "auth": "noauth",
        "udp": true
      }
    },
    {
      "tag": "http-local",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ]
}

通常、同じアドレスとポートを2つのリスナーで同時に使用することはできません。バインドに失敗した場合は、クライアントを重複して起動していないか、テスト用のコアが動作していないか、古いプロセスが正常に終了しているかを確認してください。アプリ側のポートだけ変更してinboundをそのままにしたり、inboundだけ変更してシステム側では古いプロキシポートを使い続けたりしないようにしましょう。デスクトップ版v2rayNでは、画面上のローカル待ち受けポートが他の入口の関連設定に結びついている場合があります。実際の設定とログで確認し、例のポート番号がすべての環境で共通だと考えないでください。

スニッフィングと元の宛先の関係

inboundにはsniffingを設定し、一部のプロトコルの初期データからドメイン名などを識別して、ドメインベースのルーティングに役立てることもできます。これは復号ツールではなく、すべての接続を識別できる保証もありません。適切なDNS設定の代わりにもなりません。IPアドレスしか含まれない接続や、宛先情報を確認できないプロトコルもあり、ルールが参照できる情報は異なります。実際の宛先を書き換えず、識別結果をルーティングのみに使いたい場合は、使用中のコアが該当オプションに対応しているか、意味がどう定義されているかを確認してください。異なるコアの高度なスニッフィング項目を機械的にコピーするのは避けましょう。

inboundが機能しているか確認するには、まず手動でプロキシを設定できるアプリを選び、アドレスとプロトコルを指定して個別のリクエストを送信します。そのうえで、ログに対応する入口タグが記録されているか確認してください。記録がまったくない場合は、アプリがプロキシを経由しているか、別のネットワーク設定を使用していないか、ログレベルが接続情報を表示できる設定かを確認します。システムプロキシはアプリに設定を渡す手段の一つであり、通信を強制的に転送するものではありません。アプリの通信範囲を設定する基本操作は使い方ガイドを、接続できない場合はよくある質問・トラブル対処を参照してください。

outbounds:プロトコルと接続先の設定

まずoutboundを作り、ルールから参照する

outboundは、受け取った通信を宛先へどう送るかを定義します。freedomは宛先へ直接接続し、blackholeは通信を破棄または拒否します。リモートプロキシのプロトコルを使う場合は、サーバー情報やアカウント情報も必要です。outboundが配列に含まれていても、必ず使用されるわけではありません。選択されるoutboundは、ルーティング結果と既定の動作によって決まります。一般的な構成では、どのルールにも一致しない接続に最初のoutboundが使われるため、配列の順番を変えると通信経路が変わることがあります。既定の出口を明確にし、タグ名から動作を推測しないようにしてください。

以下の設定断片には、直接接続と通信を遮断する2つのoutboundのみが含まれます。基本のinboundと組み合わせ、ルーティングからの参照を練習するのに適しています。リモートサーバーは含まれていないため、リモート接続の設定例として扱うことはできません。settingsはプロトコル固有のオブジェクトで、使用できる項目はプロトコルごとに異なります。トップレベルの共通項目が似ていても、内部のパラメーターを使い回せるわけではありません。リモートプロトコルのオブジェクトをfreedomに変更する場合は、元のプロトコルのパラメーターも削除してください。不要な項目が残ると、設定の読み取りやトラブル対処が難しくなり、アカウント情報が引き続き使われると誤解するおそれもあります。

{
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ]
}

接続情報・トランスポート・セキュリティ層を区別する

リモートoutboundには通常、サーバーのアドレスとポート、プロトコルの認証情報、トランスポートとセキュリティの設定という3種類の情報が含まれます。VMess、VLESS、Trojanでは認証情報の構造が異なります。TCPやWebSocketなどのトランスポートも、名称を1つ変えるだけで切り替えられるわけではありません。TLSはさらに別の層で、サーバー名や証明書の検証に関わります。リンクをインポートすると、クライアントが一部の項目を変換します。手動で設定する場合は、組み合わせ全体を確認してください。個々の項目が妥当に見えても、接続先の環境にある他の設定と適合するとは限りません。

項目の層主な役割確認ポイント
プロトコルのsettings接続先アドレス、アカウント、プロトコル固有の設定同じサービスの設定情報に合わせる
streamSettingsトランスポートとセキュリティ層トランスポート、パス、セキュリティの設定が互いに適合しているか
outboundのtagルーティングルールから参照参照名が完全に一致しているか
配列内の位置既定の出口の選択に影響先頭のoutboundが想定どおりか

サーバーアドレスにはドメイン名とIPアドレスを指定できますが、接続先アドレスとTLSの検証に使うサーバー名が同じとは限りません。ドメイン名を使う場合は、その名前がどう解決されるかも関係するため、リモート接続の失敗がアカウントではなくDNSに起因することもあります。証明書やハンドシェイクのエラーが発生したら、システム時刻、サーバー名、証明書チェーン、トランスポート設定を確認してください。まず証明書検証を無効にするのは避けましょう。検証を省略するとセキュリティ上の条件が変わり、アドレスの誤りも見逃すおそれがあります。検証を有効にしたまま設定を修正することで、実際のサービス障害とローカルの設定ミスを切り分けやすくなります。

コアの対応状況が設定の移行可否を左右する

XrayとV2Flyには共通する設定方法もありますが、すべてのプロトコル機能、トランスポート項目、選択肢が相互に使えるわけではありません。特定のセキュリティ機能や拡張機能を含む接続情報は、インポートやカスタマイズの前に、使用するコアが対応しているか確認してください。クライアント名だけでは、起動時に使われるコアを特定できません。v2rayNでは画面とログで実際の選択を確認します。v2rayNGはXrayを中心に、v2flyNGはV2Fly向けのAndroid代替として使われます。別のコアへ移行する場合は、ルーティングや高度な機能一式を同時に移すのではなく、まずoutboundを1つ検証してください。

サブスクリプションの管理には、設定のライフサイクルという問題もあります。更新時にサーバー情報が置き換わり、手動で変更した内部オブジェクトが維持されないことがあります。また、クライアントが現在の選択内容に応じてoutboundのタグを再生成する場合もあります。固定タグを継続して参照する必要がある場合は、クライアントが明示的にサポートするカスタム設定を使い、更新後に実際の生成結果を確認してください。クライアントのダウンロード先はダウンロードセンター、3つのクライアントの用途比較はクライアント比較を参照してください。このページではリモートサービスを提供していません。接続できるかどうかは、実際のサービス情報とネットワークの到達性によって決まります。

routing:ルールの判定順と通信の振り分け

ルールは順番に判定され、条件の細かさで自動的に並び替えられない

ルーティングは接続に使用するoutboundを選びます。一般的な条件ルールはrouting.rules配列に記述し、コアが上から順に判定します。条件に一致すると対応する処理を適用し、すべてのルールを集めてから「最も具体的な」ものを選ぶわけではありません。そのため、明確な例外ルールは、より広い条件のルールより前に置くのが基本です。先行ルールがすべてのTCP・UDP通信に一致する場合、後続のドメインルールが正しく記述されていても、出口の選択には使われません。振り分けを調べるときは、まず順序、次に条件を確認し、最後にデータファイルの項目不足を検討してください。

同じ項目に複数の候補がある場合、通常はいずれか1つに一致すれば条件を満たします。たとえばdomain配列では、いずれかのドメイン条件に一致すれば該当します。一方、同じルール内に異なる種類の条件がある場合は、通常それらすべてが判定に使われます。inboundタグ、ドメイン、ポートを同時に指定すると、いずれか1つではなく、すべての条件を満たす接続が対象になります。互いに独立した要件を1つのルールにまとめると、想定以上に対象が狭まることがあります。別々の例外を表す場合は、ルールを分けたほうが検証しやすく、どのルールが適用されたかも確認しやすくなります。

地理データに依存しないルーティング例

以下のルールは、前の2章で設定した直接接続と遮断のoutboundと組み合わせて使えます。まず例示用ドメインとそのサブドメインを遮断し、次にSOCKS入口からの接続を直接接続します。それ以外の通信には既定のoutboundを使います。ここではdomain:でドメインとサブドメインを指定し、inboundTagで入口を限定しています。この例の目的は、参照方法とルールの順序を示すことであり、実際に使う振り分けリストを推奨するものではありません。検証には対象を明確にしたテスト用の接続を使い、ログでルーティング結果を確認してください。ウェブページが開いたかどうかだけでは、どのルールに一致したか判断できません。

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "domain": [
          "domain:example.org"
        ],
        "outboundTag": "block"
      },
      {
        "type": "field",
        "inboundTag": [
          "socks-local"
        ],
        "outboundTag": "direct"
      }
    ]
  }
}

full:はドメイン名全体との一致に、domain:は指定したドメインとそのサブドメインとの一致に使います。正規表現は、複雑な条件が本当に必要な場合に適しています。通常の文字列による一致は直感より広い範囲に適用されることがあるため、意味の明確な書き方を優先してください。IPルールにはアドレスやCIDR形式のネットワークを指定できますが、プライベートネットワーク、ループバックアドレス、リンクローカルアドレスの意味は異なります。どれも同じ「ローカルアドレス」だと考えてはいけません。ルールで判定する宛先IPが、最初に解決された唯一のアドレスとは限りません。ドメインへの接続では、名前解決の段階によって判定に利用できる情報が変わります。

domainStrategyと地理データの範囲

AsIsは、ルーティングのためにドメインをIPアドレスへ変換せず、現在の宛先情報を使って判定します。IPIfNonMatchはドメイン名で一致しなかった場合に名前解決を試し、その後の判定に利用します。IPOnDemandは、ルーティングの判定にIP情報が必要になった時点で名前解決を試します。これらはルーティング段階で名前解決を行う条件を制御するもので、全体のDNSを有効・無効にする設定でも、各outboundが最終的に使うアドレスファミリーを決めるものでもありません。設定前に、ルールがドメイン名とIPアドレスのどちらに依存するか、IPによる判定のために追加の名前解決を行うかを確認してください。

geositeとgeoipはデータファイルを参照するルールであり、コアが自動で分類を作成するわけではありません。該当ファイルがない、ディレクトリが正しくない、分類名が存在しないといった場合、読み込みに失敗したり想定外の動作になったりすることがあります。データの内容は変化するため、分類を恒久的に正確な業務上の境界として扱うことはできません。重要な接続先には、意味を説明できる明示的なルールを使い、分類ルールの前後どちらに置くかを決めてください。ローカルサービスへの接続では、システムルーティングやファイアウォールも考慮する必要があります。ネットワークアクセスの問題すべてを、コアのドメインルールだけで解決しようとしないでください。

「対象を1つ、想定する出口を1つ、ログを1つ」の組み合わせでルーティングを検証するのがおすすめです。まず関係のないルールを一時的に外し、対象の情報がドメイン名かIPアドレスかを確認してから、データ分類や複雑な条件を戻します。振り分けの具体例はV2Rayルーティング実践ガイドを参照してください。既存ルールを読み込む前に、タグの参照先、ルールの順序、データへの依存関係が現在の設定に合っているか確認しましょう。リスト全体をそのままコピーすると、原因を特定できる問題が条件の中に埋もれてしまうことがあります。

dns:名前解決の経路とドメイン情報

まず、どこが名前解決を行っているか確認する

DNSのトラブルは「ドメインにアクセスできない」とひとくくりにされがちですが、1回の接続でも、アプリ独自の名前解決、OSの名前解決、コア内蔵DNS、リモートサーバー側の名前解決が関係することがあります。それぞれが同じ設定を参照するとは限りません。アプリが先にドメイン名をIPアドレスへ変換し、そのIPアドレスをSOCKS inboundへ渡す場合、コアが受け取る接続の情報は、ドメイン名を直接受け取る場合と異なります。トップレベルにdnsを追加しても、OSやすべてのアプリが自動的にそのDNSサーバーを使うわけではありません。外部DNSサーバーへのリクエストがすべて自動的に取り込まれるわけでもありません。

内蔵DNSは、ルーティング判定や直接接続時の名前解決など、名前解決が必要なコアの機能に結果を提供します。ただし、実際に呼び出されるかどうかは、該当モジュールのポリシーとコアの実装によって異なります。トラブルの原因を調べるときは、ドメイン名が最初にどこで解決されたか、リクエストがどのoutboundから出たか、解決結果が最終的にどこへ渡されたかを記録してください。DNSサーバーだけを変更し、呼び出しの流れを整理しないままでは、ウェブページが一時的に表示されても、別のアプリが失敗し続ける理由を説明できず、設定変更後の再発も防げません。

基本のDNSサーバー、静的マッピング、アドレスファミリー

以下は標準JSON形式の設定断片です。例示用ドメインに静的マッピングを設定し、DNSサーバーを指定して、問い合わせ対象をIPv4に限定しています。これは項目の構造を示す例であり、すべてのネットワークに適したサーバー一覧ではありません。実際のネットワークでは、特定のDNS通信が制限されることがあり、サーバーへ現在の経路から到達できるとも限りません。静的マッピングは、接続先のアドレスが明確な場合にのみ使ってください。サービスのアドレスが頻繁に変わる場合、固定したまま使い続けると、古いアドレスへの接続、証明書エラー、地域別の接続先選択の失敗につながることがあります。

{
  "dns": {
    "hosts": {
      "example.org": "93.184.215.14"
    },
    "servers": [
      "1.1.1.1",
      "8.8.8.8"
    ],
    "queryStrategy": "UseIPv4"
  }
}

queryStrategyは、名前解決で対象とするアドレスファミリーを指定します。一般的な値にはUseIP、UseIPv4、UseIPv6があります。対応状況は使用中のコアで確認してください。IPv4に限定すると、IPv6経路に関する問題を切り分けやすくなる場合がありますが、あらゆるタイムアウトを解決する万能策ではありません。サービスに特定のアドレスレコードしかない場合、アドレスファミリーを制限すると利用可能な結果が得られないことがあります。反対にIPv6アドレスを取得できても、端末に有効なIPv6ルートや対応するoutboundがあるとは限りません。名前解決の成功と接続の成功は別の段階です。

ドメイン別の名前解決と循環依存

servers配列にはサーバーオブジェクトを指定でき、ドメイン条件や対象とするIP範囲を使って、より細かい問い合わせ先を設定できます。ここでのドメイン条件はDNSサーバーを選択するためのもので、routing.rulesによるoutboundの選択とは異なります。DNSリゾルバーがリクエストを受け取った後、どの経路で接続するかは、トランスポート方式やコアの実装にも左右されます。ローカルモードと通常モードでルーティングの挙動が異なる場合があります。暗号化DNSを設定する前に、現在の項目の意味を確認し、すべてのDNSリクエストが自動的にプロキシ経由になると決めつけないでください。

特に注意したいのが、名前解決に起因する循環依存です。リモートサーバーのアドレスを解決する必要がある一方で、DNSサーバーへの接続にも、まだ確立していないリモート接続が必要になる状態です。ドメイン名で指定された暗号化DNSサーバーでも、同様の問題が起こることがあります。まず初期段階の名前解決を独立して行えるようにし、リモートサーバーのドメイン名がどう解決されるかを明確にしてから、複雑な経路を追加してください。セキュリティチェックを無効にしたり、サーバーアドレスを安易に固定したりして循環を隠すのではなく、依存関係を分離し、システムDNS、コア内蔵DNS、outboundそれぞれの役割を確認しましょう。

FakeDNSは、仮想アドレスとドメイン名の対応関係を使い、後続の処理でドメイン名を復元する仕組みです。通常は、入口での通信の取り込み、名前解決の処理、コアの機能を連携させる必要があります。名前を1つ追加したり、設定断片をそのままコピーしたりするだけで、通常のシステムプロキシに完全な通信取り込み機能が加わるわけではありません。関連モードを終了する際は、アプリやシステムのキャッシュに仮想アドレスが残っていないかにも注意してください。詳しい適用範囲はFakeDNSの仕組みと利用シーンを参照してください。通常のトラブル対処では、まずシンプルな名前解決の経路を使って安定性を確認し、必要な場合に限って導入を検討しましょう。

policy・log・stats:実行時の動作設定

policyは接続の動作を制御する。outboundは選択しない

policyでは、ハンドシェイク、アイドルタイムアウト、半閉鎖の処理、通信量の統計などを設定します。ルーティングの代わりにはならず、数値をいくつか追加するだけで接続品質が向上するわけでもありません。levelsのキーはユーザーレベルを示し、プロトコルのユーザーオブジェクトにあるレベル情報に対応します。明示的に指定していない場合、一般的な構成では既定のレベルが使われます。プロトコルによって取得できるユーザー情報は異なるため、すべての入口で同じ方法で統計を取れるとは限りません。設定前に、対象の接続がどのレベルに対応するかを確認してください。そうしないと、実際には使われていないpolicyを変更することになります。

以下の設定断片では、既定レベルに一般的なタイムアウト項目を明示しています。handshakeはハンドシェイクに許される時間、connIdleは接続のアイドル状態、uplinkOnlyとdownlinkOnlyは片方向の通信が終了した後、もう一方の通信を維持する時間を制御します。単位はいずれも秒です。この例は設定の構造を説明するもので、既存クライアントの既定値をすべて置き換える必要はありません。問題なく使えているなら、クライアントに合わせて調整された既定のpolicyを維持するほうが、タイムアウトを根拠なく短くするより管理しやすいでしょう。

{
  "policy": {
    "levels": {
      "0": {
        "handshake": 4,
        "connIdle": 300,
        "uplinkOnly": 2,
        "downlinkOnly": 5
      }
    },
    "system": {
      "statsInboundUplink": false,
      "statsInboundDownlink": false
    }
  },
  "log": {
    "loglevel": "warning"
  }
}

ハンドシェイクの時間が短すぎると、ネットワークの揺らぎや複数層にわたるトランスポートの確立が終わる前に、接続が終了することがあります。アイドルタイムアウトが短すぎると、長時間接続やプッシュ通知の待機、断続的な通信に影響する可能性があります。長く設定しすぎると、使われていない接続が必要以上に残ります。アプリによっては独自のハートビートや再試行機能があり、実際の挙動はアプリ側の処理にも左右されます。再現可能な問題をもとにpolicyを調整し、変更前後のログと接続段階を記録してください。一度だけ成功した結果を、設定変更が有効だった証拠とみなさないようにしましょう。タイムアウト値はサービスの応答速度を測る指標でもありません。

ログレベルと出力先

loglevelで一般的に使われるレベルには、debug、info、warning、error、noneがあります。debugは詳細な情報を記録しますが、ログの容量が増え、プライバシー情報が含まれる可能性も高くなります。通常の利用で最も詳細なログを常時有効にする必要はありません。ファイルパスを設定していない場合、コンソールやクライアントがログを受け取ることがあります。アクセスログやエラーログの出力先を設定する場合は、実行ユーザーに書き込み権限があることと、相対パスの基準になる作業ディレクトリを確認してください。ファイルに新しい内容がないからといって、接続がなかったとは限りません。古いパスや別のログファイルを確認している可能性もあります。

アクセスログとエラーログでは、記録する内容が異なります。前者はリクエストの宛先やoutboundを確認するために、後者は名前解決、接続、ハンドシェイクのどの段階で失敗したかを調べるために使います。ログを読むときは、まずテストした時間帯を合わせてから、入口タグ、宛先アドレス、エラーの流れを確認してください。最終的にタイムアウトになっていても、原因はそれ以前の名前解決失敗かもしれません。最後の1行だけを切り取って判断しないようにしましょう。ログにはドメイン名、アドレス、ユーザー識別情報、ローカルパスが含まれることがあります。他者に共有する前に機密情報を処理し、通信の流れを判断するのに必要な情報だけを残してください。実行ログ全体をそのまま公開するのは避けましょう。

統計機能と管理インターフェースの関係

トップレベルのstatsとpolicy内の統計設定は、別の役割を持ちます。前者は統計関連のモジュールを有効にし、後者はどの項目のデータを集めるかを指定します。空のstatsオブジェクトを追加しただけでは、アクセス可能なグラフィカル画面が自動的に作られるわけではありません。統計を取得するには、通常、管理インターフェース、サービスの定義、入口の分離なども関係します。一度のトラブル調査のために管理インターフェースを公開することは推奨しません。また、統計値だけでネットワーク性能を判断することもできません。クライアントに通信量の表示機能がある場合は、境界が不明確なインターフェースを別途設定せず、既存の連携機能を優先してください。

「接続できるが、しばらくすると切れる」場合は、アプリ側の終了、リモート側の切断、アイドル設定の適用、ネットワーク切り替えをまず区別し、その後でpolicyの変更を検討してください。毎回ハンドシェイクの段階で失敗するなら、アイドル関連の値を変更しても根本原因は解決しません。ログの詳しい読み方はV2Rayの実行ログの読み方を参照してください。原因を特定したら、通常利用に適したログレベルに戻し、不要なデバッグファイルを削除します。必要なpolicyの変更は、設定のバックアップに記録してください。

クライアント設定とコアのJSON設定の違い

v2rayN:画面上の設定とファイルの内容は同じとは限らない

デスクトップではv2rayNが一般的ですが、グラフィカルクライアントを使っても、すべての設定が1つのJSONファイルに保存されるとは限りません。サーバー一覧、サブスクリプションURL、ウィンドウの設定、ルーティングのテンプレート、コアの実行設定は、それぞれ別に保存される場合があります。起動すると、クライアントは現在の選択内容を組み合わせて、コアが読み込める設定を生成します。停止してから再起動する、サーバーを切り替える、サブスクリプションを更新するといった操作で、生成結果が再作成されることがあります。ファイルを読む際は、長期的な設定の元データなのか、一時的な生成物なのかを確認してください。出どころが不明なファイルを唯一のバックアップにしたり、コアの実行中に反映されたか分からないまま編集したりするのは避けましょう。

システムプロキシは、OSとアプリの間で設定を共有するための仕組みです。コアのJSONは、プロセス自身の待ち受けや転送方法を定義します。一般的なデスクトップでの利用には、両者を連携させる必要があります。システムプロキシを解除してもコアが停止するとは限りません。また、コアを停止してもOSに残ったプロキシ設定がすぐに解除されるとは限りません。アプリが停止済みのローカルポートへリクエストし続けると、全体が接続できないように見えることがあります。終了の前後で、システムプロキシの状態とプロセスの状態をそれぞれ確認してください。接続拒否の原因をすべてリモートサービスのせいにしたり、設定の残存を複数のクライアントを重ねて使って解決しようとしたりしないでください。

プラットフォームやコアによる設定の違い

Windows、macOS、Linuxではいずれもv2rayNを利用できますが、権限、実行ディレクトリ、システムプロキシとの連携方法、ネットワークの取り込み方式は同じではありません。ファイルパスの記述、設定フォルダーの書き込み権限、サービスの実行ユーザーは、実際に読み込まれる内容に影響することがあります。Androidでは通常v2rayNGを選び、V2Fly向けの設定を使う場合はv2flyNGも選択肢になります。OSのネットワーク取り込みに必要な権限は、デスクトップのシステムプロキシとは異なる仕組みです。移行時は接続情報を保ちつつ、移行先のプラットフォームで通信の取り込み設定を確認してください。作業フォルダー全体をコピーして、パスや権限がそのまま使えると考えないようにしましょう。

クライアント対応プラットフォーム設定を確認するときのポイント
v2rayNWindows / macOS / Linux実行コア、生成設定、システムプロキシの状態
v2rayNGAndroidXrayの項目対応状況、OSの許可、アプリへの適用範囲
v2flyNGAndroidV2Flyの項目対応状況とインポート形式

同じJSON形式でも、設定モデルがまったく異なる場合があります。v2rayNでは複数のコアを選べることがありますが、ここで示すinbounds、outbounds、routingの例は、V2Fly・Xrayで一般的な構造を前提としています。sing-boxの設定にそのまま適用することはできません。ファイルの拡張子だけで互換性を判断しないでください。項目が認識されない場合は、まず起動中のコアを確認し、次に設定の入口が完全な設定、サーバーオブジェクト、クライアント専用のインポート形式のどれを求めているか調べましょう。異なる形式の項目を継ぎ足し続けないようにしてください。

TUNとシステムプロキシは、1つの真偽値で同じものとして扱えない

TUNの利用には通常、仮想ネットワークインターフェース、ルート設定、必要な権限が求められ、専用の通信取り込み機能や別のコアが必要な場合もあります。クライアント画面で「TUNを有効にする」を選んでも、基本JSONのトップレベルに同名の項目を追加するだけで同じ動作が得られるわけではありません。システムプロキシは適用範囲が比較的明確ですが、アプリ側が設定を使う必要があります。TUNはより広い通信を取り込める一方、ローカルネットワーク、DNS、出口から入口へ戻るループも考慮しなければなりません。モードを切り替えるときは、明確な通信取り込み経路を一度に1つだけ有効にし、リモート接続自体が再び入口へ送られないことを確認してください。

カスタムの完全設定と通常のサブスクリプション利用も、分けて管理してください。完全設定では、inbound、outbound、ルール、データへの依存関係を自分で管理するのが一般的です。一方、通常のサブスクリプション利用では、クライアントがサブスクリプションと画面上の設定から内容を生成します。インポートに成功しても、すべての項目が反映されたとは限りません。クライアントに設定のプレビューや実行ログがある場合は、実際に読み込まれた内容を確認してください。マージ方法が明確に説明されていない限り、カスタム断片が正しい位置に自動で追加されると考えないようにしましょう。互いに上書きし合う一時ファイルを複数管理するより、復元できる通常の設定を1つ保管するほうが確実です。

デスクトップ版を選ぶ際は、システムや操作環境に合わせてv2rayNデスクトップ版とWPF版の違いを確認してください。画面のフレームワークの違いを、プロトコルの対応状況の違いと混同しないようにしましょう。インストーラーはプラットフォームに応じてダウンロードセンターから選び、初期設定は引き続き使い方ガイドの手順に沿って進めてください。画面から実現できない要件があると確認できた場合にのみ、コアのカスタム設定を導入します。サブスクリプション更新、モード切り替え、再起動の後も設定が維持され、次回の起動でも想定した設定が使われるか確認してください。

設定の検証、ログによる原因特定、復旧手順

構文の正しさと動作の正しさを分けて検証する

設定のトラブル対処は、手間の少ない確認から始めます。まず標準JSONであることを確認し、括弧、カンマ、文字列のエスケープが正しいか調べます。次に項目が使用中のコアに対応しているか確認し、タグの参照、データファイル、待ち受けポート、パスの権限を調べます。実際の接続テストは最後に行ってください。構文チェックに通るのは、ファイルを解析できることを示すだけで、リモートへの接続や想定どおりのルーティングを保証するものではありません。リモート出口を含まない直結設定でも構文上は正しいため、「コアが起動すること」と「指定した宛先へ指定したoutboundで接続できること」は、別々の検証項目として扱ってください。

手動でコアを起動している場合は、長時間待ち受ける前に設定のテストモードを使えます。以下のコマンドは、ローカルにあるXrayとV2Rayの実行ファイルをそれぞれ対象にしています。config.jsonには、実際に確認する設定ファイルを指定してください。適切な作業ディレクトリでコマンドを実行するか、実行ファイルの正しいパスを指定します。配布形式によってコマンドの引数が異なることがあるため、認識されない引数が表示された場合は、プログラム付属のヘルプを確認してください。グラフィカルクライアントを使う場合は、ログや設定の確認機能を優先してください。このページを読むために、別途バックグラウンドプロセスを構築する必要はありません。

xray run -test -config config.json

v2ray test -c config.json

設定テストを通過したら、競合するリスナーを停止してから、対象の設定で起動します。プロキシ設定に対応したアプリを1つ選び、今回の検証に必要な入口だけを設定してリクエストを送信し、実行時刻を記録してください。第1章の直結設定を使う場合、確認できるのはローカルの入口であり、リモートプロキシへの接続ではありません。その後、確認済みの情報でリモートoutboundを追加し、最後にルーティングとDNSを戻します。各段階で追加する主な要素を1つに絞ることで、失敗しても、入口、名前解決、リモート接続のすべてを同時に疑わずに済みます。

症状に合わせて該当する層を確認する

コアが起動できない場合は、構文エラー、未対応項目、ポートの競合、データファイルの読み込みを優先して確認します。ローカル接続が拒否される場合は、待ち受けアドレス、ポート、プロセスの状態を確認してください。コアがリクエストを受け取った後に名前解決エラーが出る場合は、DNSの呼び出し経路を調べます。リモートのハンドシェイクに失敗する場合は、アドレス、システム時刻、プロトコルの認証情報、トランスポートとセキュリティの設定を確認してください。タイムアウトが発生しても、すぐに原因の層を決めつけてはいけません。ログをさかのぼり、最後に成功した段階と、最初に明確な失敗が記録された箇所を探してください。

症状最初に確認する項目次に確認する証拠
起動直後にプロセスが終了するJSON、項目の対応状況、ファイルパス起動エラーに記載された具体的な項目名やファイル名
ローカル接続が拒否されるプロセス、待ち受けアドレス、ポート対象の入口で実際に待ち受けているか
名前解決エラーが発生するDNSサーバーと名前解決の依存関係どの段階でドメイン名が解決されているか
ルーティング結果が想定と異なるルールの順序、宛先の形式、タグリクエストに適用されたoutboundのログ

テスト中はアプリのキャッシュによる影響を避けてください。既存の接続が古い経路を使い続けることがあります。ドメイン名のキャッシュに以前の結果が残る場合や、システムプロキシの変更が起動中のアプリにすぐ反映されない場合もあります。必要であれば該当する接続を終了するかテストアプリを再起動し、同じリクエストを試してください。ただし、元の問題と比較できなくなるため、設定をすべて同時に消去するのは避けましょう。ネットワークを切り替えると、接続先への到達性や名前解決経路も変わるため、テスト時のネットワーク環境を記録してください。同じ条件で繰り返し確認できた結果をもとに、設定変更の効果を判断しましょう。

パッチを積み重ねず、復元できる状態を残す

各段階の動作を確認できたら、対応する設定と簡潔な説明を保存してください。使用したコア、inboundのポート、既定のoutbound、依存ファイルを記録します。バックアップにサブスクリプションURLやアカウント情報が含まれる場合は、機密情報として管理し、公開ページや共有記録に載せないでください。新たな問題が起きたら、直近の復元ポイントに戻し、変更を1つずつ適用し直します。動作しない設定に例外ルールやタイムアウトを追加し続けないでください。正常に戻った後は、効果がないと確認できた変更を削除し、後から設定を管理する人が一時的な試行を必須条件と誤解しないようにしましょう。

最後に設定の維持を確認します。クライアントを停止して再起動し、サブスクリプション更新やモード切り替えで必要な設定が上書きされないことを確かめてから、同じ宛先で再テストしてください。デバッグが終わったら適切なログレベルに戻し、一時的に広げた待ち受け範囲を元に戻し、不要なシステムプロキシ設定を解除します。原因を特定できない場合は、機密情報を処理したエラーログの一部と最小限の再現手順を用意してよくある質問・トラブル対処を参照してください。基本の設定をやり直すだけなら使い方ガイドに戻りましょう。設定リファレンスにある任意の項目をすべて必須だと考える必要はありません。

クライアントをダウンロード