CONFIG.JSON / FIELD REFERENCE

V2Ray設定ファイルガイド

inboundsで接続を受け付け、ルーティングでoutboundsを選択します。項目ごとに問題を切り分け、クライアント画面の設定とコアの設定を混同しないようにしましょう。

初めてのインストールやサブスクリプションの追加方法は、まずクイックスタートをご覧ください。このページでは、生成された設定の確認、独自設定の追加、実行ログの分析方法を解説します。デスクトップではv2rayNクライアントのダウンロードからプラットフォームに合ったものを選び、その後このページで各項目を確認してください。

JSON構造の全体像と設定の範囲

クライアント設定とコアの実行ファイルを区別する

V2Rayの設定は通常、2つの層に分かれています。1つ目はGUIクライアントが保存するサブスクリプション、グループ、画面設定、プロキシモード。2つ目はコアの起動時に生成される実行設定です。どちらもJSONを使う場合がありますが、項目の意味は同じではありません。サブスクリプションの更新間隔はクライアントの管理機能であり、コア設定のルートオブジェクトに追加するものではありません。ファイルを確認する前に、クライアントのデータベース、サブスクリプションの内容、コアが実際に読み込む設定のどれなのかを確かめましょう。拡張子が同じでも、互いに置き換えられるとは限りません。

実行設定は、データの流れに沿って理解できます。inboundsがアプリからの接続を受け付け、routingが接続を渡すoutboundを決め、outboundsが直接接続、プロキシ接続、遮断を実行します。dnsは組み込みの名前解決を設定し、policyは接続の動作を調整します。logでは起動時と実行中の状態を確認できます。これらのモジュールは相互に参照しますが、最初からすべての機能を有効にする必要はありません。機能を追加するほど同時に確認すべき条件も増えます。トラブル対処では最小限の経路を維持し、項目を一つずつ戻していきましょう。

最小構成:ローカルSOCKS inboundと直接接続outbound

以下は、リモートのプロキシサービスを使わない基本設定の全体例です。アプリでローカルのSOCKSポートを明示的に指定すると、コアが接続先へ直接アクセスします。設定ファイルの読み込み、ポートの待ち受け、アプリからinboundへの接続を確認するのに適しています。リモートノードの設定ではなく、システム全体の通信を自動的に処理するものでもありません。例のポート番号は説明用です。クライアントがすでにそのポートを使っている場合は、該当プロセスを終了するか、未使用のポートに変更して、待ち受けの競合を避けてください。

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

JSONの構文チェックは最初の確認項目

JSONオブジェクトは波括弧、配列は角括弧で囲み、キーと文字列には半角の二重引用符を使います。ポート番号は引用符付きの文字列ではなく数値で記述し、真偽値にはtrueまたはfalseを使います。実際の設定ファイルにはコメント、末尾のカンマ、シングルクォートを含めないでください。記事中の例は通常、1つのモジュールだけを抜き出したものです。正しい階層に戻して使いましょう。ルートオブジェクト全体をinboundのsettingsに入れると、構文上は正しくてもコアの構造要件を満たしません。

構文チェックの後は、現在のコアが項目に対応しているか、参照先のタグが存在するか、外部ファイルのパスにアクセスできるかも確認します。XrayとV2Flyには共通する設定概念がありますが、新しいプロトコル、トランスポート項目、テスト用パラメーターの対応状況は同じではありません。クライアント名だけで互換性を判断せず、実際に起動しているコアの名称とログを確認してください。画面から共有リンクをインポートできても、選択中のコアがリンク内のすべてのトランスポート設定を実行できるとは限りません。インポート成功と接続成功は別の段階です。

変更前に起動できる設定を別途保存し、変更箇所がクライアント画面なのか独自ファイルなのかを記録しておきましょう。コアの実行ファイルをクライアントが自動生成している場合、直接編集してもノードの切り替えや再起動で上書きされることがあります。通常の設定はまず画面で行い、その後、クライアントが用意する独自設定の入力欄から拡張内容を追加するのが適切です。設定欄が分からない場合は、まず現在の生成結果をエクスポートまたは確認してください。一時ファイルを何度も編集して、永続設定の代わりにしないようにしましょう。以降の章でもこの区分に沿って説明し、上書きの問題を項目が効かない問題と取り違えないようにします。

inbounds:待ち受けアドレス、ポート、プロトコル

inboundsはアプリからコアへ接続する入口

inboundsは配列で、各オブジェクトが接続を受け付ける入口を表します。tagはルーティングから参照する名前、listenはバインドするローカルアドレス、portは待ち受けポート、protocolは入口のプロトコルを指定します。アプリでHTTPプロキシを設定した場合はHTTP inboundに接続し、SOCKSプロキシを設定した場合はSOCKS inboundに接続します。ポート番号が同じでも、2種類の入口を置き換えることはできません。ポートへの接続が確立しても、アプリとinboundのプロキシハンドシェイク方式が一致しているとは限りません。

ローカルでのみ使う場合は、待ち受けアドレスに127.0.0.1を指定するのが基本です。IPv4のループバックインターフェースだけにバインドされるため、PCが別のネットワークに接続しても、LANに自動公開されません。0.0.0.0は使用可能なすべてのIPv4インターフェースへのバインドを意味します。十分に検討したうえでLAN共有に使えますが、ファイアウォールで接続元を制限する必要があります。待ち受けアドレスはリモートサーバーのアドレスでも、他の端末が入力する接続先でもありません。他の端末からは、クライアントを実行しているPCのLAN内アドレスを指定します。

2種類のinboundを使う例と各項目の意味

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

この例では、アプリの設定画面で見分けやすいように、2つのプロトコルに異なるポートを割り当てています。SOCKSのudpを有効にすると、inboundで対応するUDPリクエストを処理できますが、通信経路全体でUDPが使えることを保証するものではありません。アプリが対応機能を使い、outboundとリモート側も対応している必要があります。途中のネットワークでパケットが制限される場合もあります。Webページは開けるのに特定のリアルタイムアプリで問題が起きる場合は、アプリがinboundに接続しているか、UDPを送信しているか、outbound経路が必要な機能に対応しているかを個別に確認しましょう。inboundのスイッチを何度も切り替えるだけでは解決しません。

項目用途確認ポイント
taginboundの参照名ルーティングのinboundTagと一致させる
listenローカルのバインドアドレスループバック接続とLAN共有を分けて設定する
port待ち受けポート他のプロセスと競合せず、アプリ側の設定と一致している
protocol入口のプロトコルアプリ側のHTTPまたはSOCKS設定に合わせる

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

コアの機能に応じて、inboundにsniffingを設定し、一部のプロトコルハンドシェイクから接続先ドメインなどを識別できます。ドメインに基づくルーティング判断に役立ちますが、あらゆる通信内容を解析する機能ではありません。暗号化されたハンドシェイクの特徴、アプリの実装、コアの設定によって、取得できる情報は異なります。sniffingによって元の接続先と識別されたドメインのどちらを使うかにも影響するため、すべての振り分け問題に対する標準的な解決策として扱わないでください。まずアプリがドメインとIPのどちらを渡しているか確認し、必要な場合にのみ有効にして、利用中のコアで該当項目がどう解釈されるかを確かめましょう。

システムプロキシは、OSがその設定に従うアプリへプロキシの接続先を通知する機能であり、それ自体がinboundを作るわけではありません。TUNは仮想ネットワークインターフェース、ルーティングの取り込み、DNSの連携が関係するため、上記のJSONに同名の真偽値を追加するだけでは設定できません。利用できる機能はクライアント、選択したコア、関連する実装によって異なります。確認する際は、まずローカルポートが待ち受けていること、次にシステムプロキシがそのポートを指していること、最後に対象アプリがシステム設定に従っていることを確認してください。この3段階を分けると、アプリの直接接続をコアのルーティングエラーと誤認しにくくなります。

LANで共有する場合は、端末のアドレス変更、ゲストネットワークの分離、PCのスリープも考慮してください。スマートフォンとPCの名前が似ている、または同じアクセスポイントに接続しているというだけでは、相互に通信できるとは限りません。まず同一サブネット内で通信できることを確認し、必要なポートだけを開放します。テスト後は不要な入口を閉じてください。詳しくはv2rayNでLAN接続を許可する設定をご覧ください。トラブル対処のためにPC全体のファイアウォールを長期間無効にしないでください。ポートと接続元ネットワークを限定したルールを設定し、用途を記録しましょう。

outbounds:接続先への接続とタグ参照

outboundsは接続を実行する機能で、サブスクリプションの管理は行わない

outboundsも配列で、各オブジェクトがコアから外部へ接続する方法を記述します。一般的なfreedomは接続先へ直接接続し、blackholeは通信を遮断します。プロキシプロトコルを使う場合は、リモート側に合った接続パラメーターが必要です。tagはルーティングでoutboundを選択する際に使う名前であり、プロトコルそのものではありません。タグをproxyと名付けても、リモートプロキシの機能が自動的に備わるわけではありません。実際の動作はprotocol、settings、および必要なトランスポート設定によって決まります。

ルールに一致しない場合、通常はoutbounds配列の先頭が使われるため、配列の順序には実際の意味があります。標準でプロキシを使うなら、先頭が想定するプロキシoutboundか確認してください。標準で直接接続するなら、先頭にdirectを置けます。一致しない接続が自動的にproxyという名前のオブジェクトを探すと考えてはいけません。GUIクライアントは現在のモードに応じてoutboundsを並べ替えたり再生成したりすることがあります。実際の既定動作はサブスクリプション一覧の表示順ではなく、実行設定で確認してください。

ローカルの上流サービスでプロキシ、直接接続、遮断を試す

以下の例では、学習用設定に実際のリモート認証情報を混ぜないよう、別のローカルSOCKSサービスを上流として使います。ローカルの127.0.0.1:10810で利用可能なSOCKSサービスが稼働している場合に限り、先頭のoutboundから接続できます。自分自身のinboundポートを指定すると、ループが発生する可能性があります。第1章の直接接続経路を試すだけなら、この例は不要です。上流を設定する前に、上流サービス単体でリクエストを処理できることを確認してください。

{
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "socks",
      "settings": {
        "servers": [
          {
            "address": "127.0.0.1",
            "port": 10810
          }
        ]
      }
    },
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    },
    {
      "tag": "block",
      "protocol": "blackhole",
      "settings": {}
    }
  ]
}

プロトコル設定とトランスポート設定を分けて確認する

VMess、VLESS、Trojan、Shadowsocksは認証構造が異なるため、あるプロトコルの設定オブジェクトを別のプロトコルにそのままコピーできません。サーバーアドレスとポートが同じでも、接続先の入口が同じことしか分からず、認証パラメーターが正しいとは限りません。ノードがサブスクリプションから提供されている場合は、まずインポートした設定をそのまま保持し、クライアントがプロトコルを正しく認識しているか確認してください。次にトランスポートの種類、セキュリティ層、サーバー名を調べます。トラブル対処では、誤りを確認できた項目だけを一度に1つ変更しましょう。プロトコル、トランスポート、ルーティングを同時に変えると、結果を比較できなくなります。

streamSettingsは対応するトランスポートとセキュリティ設定に使いますが、内部構造はプロトコルやコアの機能によって異なります。WebSocketのパス、TLSのサーバー名、REALITYの関連パラメーターは、互いに置き換えられる文字列ではありません。トランスポート方式とセキュリティ層をサーバー側の設定に合わせてください。サーバー名や時刻の誤りを隠すために、証明書の検証を無効にしないでください。まずシステム時刻、サーバー名、サーバー証明書の条件を確認します。ハンドシェイク中に接続が失敗する場合、ルーティングルールを変更してもリモート側のパラメーター不一致は解消しません。

同じリモートノードを異なるコアで使えるかどうかは、プロトコルとトランスポートの両方を確認する必要があります。プロトコル名だけで判断しないでください。たとえばVLESSを認識できても、リンクに含まれるすべてのセキュリティ設定に対応しているとは限りません。2つのコア系列の違いについては、XrayコアとV2Flyコアの違いをご覧ください。互換性を確認してからコアを切り替え、実際に生成された設定をもう一度確認しましょう。クライアントが古い設定を使い続けたり、表現できない項目を失ったりする可能性があります。

outboundの管理では、明確なフォールバック方法も確保してください。プロキシoutboundを追加するときは、検証可能なdirectとblockのタグを残し、対象を限定したルールを1つ使ってテストします。成功を確認してからルールの範囲を広げてください。outboundを削除する前に、ルーティングや他のモジュールに参照が残っていないか検索しましょう。参照先のないタグが残ると、設定エラーや想定外の接続につながることがあります。コネクション再利用や多段転送などの拡張機能は、基本的な接続が安定してから個別に検討してください。最小構成の例に最初から含めるべきものではありません。

routing:ルールの照合順と既定の接続先

説明文から優先順位を判断せず、ルールの順序に沿って照合する

ルーティングは接続をどのoutboundに渡すかを決めるもので、リモートノードに接続できるかどうかは扱いません。通常、rules配列は先頭から順に調べ、条件に一致したルールの接続先outboundを選択します。LAN内の接続、特定のドメイン、さらに広い範囲のルールというように、具体的なルールを広範なルールより前に配置してください。最初のルールがすべてのTCPとUDPに一致すると、その後の細かいルールは機能しません。ルールの数が多いほど振り分けが正確になるわけではありません。条件同士の適用範囲が重複しているかどうかが重要です。

同じルール内の異なる種類の条件は、通常すべてを満たす必要があります。一方、同じ条件配列内の複数の値は、通常いずれかに一致すればよい指定です。たとえばdomainとportを同時に指定すると、対象ドメインとポートの両方が条件に合うことを意味し、どちらか一方でよいという意味ではありません。「ドメインまたはIPに一致」させたい場合は、通常、ルールを2つに分けるほうが明確です。インポートしたルールを読むときは、条件を完全な文章に置き換えると、AND条件をOR条件と取り違えていないか見つけやすくなります。

LANは直接接続し、指定ドメインは遮断する

{
  "routing": {
    "domainStrategy": "AsIs",
    "rules": [
      {
        "type": "field",
        "ip": ["geoip:private"],
        "outboundTag": "direct"
      },
      {
        "type": "field",
        "domain": ["full:blocked.example"],
        "outboundTag": "block"
      }
    ]
  }
}

この設定を使うには、directとblockのoutboundがすでにあり、コアが該当する地域別IPデータを読み込める必要があります。例に登場するドメインは説明用で、実在するサービスを示すものではありません。ルールに一致しない接続には既定のoutboundが使われます。前章のようにプロキシを先頭に置いた場合、残りの通信はプロキシに渡されます。AsIsでは、IPルールに照合するためにドメインを自動で解決しません。そのため、ドメイン名で社内サービスへアクセスする場合、プライベートIPルールだけを根拠に直接接続されるとは限りません。社内ドメイン用のルールを別途設けるか、名前解決の方針を確認してください。

ドメインルール、IPルール、データファイル

full:はドメイン全体の完全一致、domain:は指定ドメインとそのサブドメインへの一致に使います。通常の文字列と正規表現にも、それぞれ異なる意味があります。特定のホストだけを対象にする場合は、完全一致のほうが確認しやすくなります。ドメイン全体を対象にする場合は、domain一致を使いましょう。正規表現は単純なルールで要件を満たせないと確認してから使い、JSON文字列内のバックスラッシュのエスケープに注意してください。正規表現テスターの文字列をそのままJSONに貼り付けると、エスケープの階層の違いで意味が変わる場合があります。

geosite:とgeoip:はデータ上の分類を参照するもので、リアルタイム検索サービスではありません。分類が存在するか、どのレコードが含まれるか、更新後に内容が変わるかは、実際に読み込むデータファイルによって異なります。ルール名のスペルが正しくても、ファイルがない、パスが違う、分類が存在しないなどの理由で起動できない場合があります。クライアントのデータ更新機能を使った後は、該当するコアを再起動してログを確認してください。複数のデータファイルを同時に入れ替え、Webページが開いたかどうかだけで成功を判断しないでください。想定したファイルが想定したパスから読み込まれていることを先に確認しましょう。

ポリシー基本動作確認ポイント
AsIsルーティング照合のためにドメインを解決しないドメインの接続先にIP条件が自動適用されるわけではない
IPIfNonMatchドメインに一致しない場合、照合に使うための名前解決を試みる名前解決の結果が後続のIPルールに影響する場合がある
IPOnDemandIPが必要な条件に照合する際に名前解決を試みる早い段階でDNSへの依存が生じるため、DNSの確認が必要

これらのポリシーはルーティング段階で名前解決を行うタイミングを決めるもので、DNSモジュールのアドレスファミリー設定や、direct outboundが最終的に接続する方法とは異なります。ドメインはルール判定に使われた後、実際の接続先の名前解決をoutboundやリモート側で行うことがあります。トラブル対処では「ルート選択に使うアドレス」と「実際の接続に使うアドレス」を区別してください。名前解決元が異なる場合、ログに表示されたIPアドレスと最終的なアクセス経路が完全に一致するとは限りません。1つの名前解決結果だけで経路全体が固定されたと判断しないようにしましょう。

新しいルールを検証する際は、対象を1つ決め、入力がドメインかIPかを記録したうえで、ルールの範囲を一時的に絞ってください。アクセスログで想定どおりのinboundとoutboundを通っているか確認し、その後ルール全体を戻します。アプリのキャッシュや既存の長時間接続は、新しい接続判断を経由しない場合があります。テスト前に古い接続を終了し、新しくリクエストを送信してください。クライアントがルーティングテンプレートを自動更新する場合は、更新後も独自ルールが保持されているか確認します。ルールの基本的な疑問はよくある質問も参照してください。複数のテンプレートを何度も切り替える必要はありません。

dns設定:名前解決元、アドレスファミリー、接続経路

まず、どこで名前解決しているかを確認する

DNSの問題では、最初にどのサーバーを指定するかではなく、どこで名前解決が行われるかを確認します。アプリがシステムDNSでIPを取得してから、そのIPをプロキシに渡す場合があります。SOCKSまたはHTTPの入口にドメイン名を渡すこともあり、ルーティングポリシーによってコアが名前解決する場合や、リモートプロキシが最終的な名前解決を行う場合もあります。リクエストが実際にコアのDNSを利用するときに限り、dnsモジュールの変更が該当する段階に影響します。システムDNS、ブラウザー独自の名前解決設定、コアのDNSは別々の機能です。設定を一度変更しただけですべてのアプリの動作を説明することはできません。

確認時には、接続先の入力形式、アプリのプロキシ方式、ルーティングポリシーを記録してください。アプリからすでにIPが渡されている場合、コアのDNS設定だけで元のドメイン名を復元することは通常できません。sniffingで一部の情報を取得できる場合もありますが、すべての接続で識別できるわけではありません。一方、アプリがドメイン名を渡していても、AsIsではルーティング段階で名前解決が行われないことがあります。まずリクエストの経路を把握してから、システムDNS、アプリ設定、コアのどれを変更するか判断しましょう。名前解決キャッシュ、ルール照合、リモート接続の失敗をすべて同じDNS障害として扱わずに済みます。

静的マッピングとDNSサーバーの設定例

{
  "dns": {
    "hosts": {
      "full:reference.example": "192.0.2.10"
    },
    "servers": [
      "223.5.5.5",
      "1.1.1.1"
    ],
    "queryStrategy": "UseIP"
  }
}

ここで使う静的マッピングのアドレスはドキュメント用で、実際にアクセスできるサービスではありません。ドメインの上書き設定を理解するための例です。2つのサーバーアドレスも設定形式を示すもので、あらゆるネットワークに適するとは限りません。複数のDNSサーバーの選択、並列処理、フォールバックの動作は、設定形式やコアの実装によって異なります。配列をブラウザーのブックマークのように上から順に試すものと考えないでください。実際に使う前に、現在のネットワークからサーバーに接続できることと、リクエストが想定した経路を通ることを確認してください。静的マッピングは対象ドメインの結果を変更するため、テスト後は不要な項目を削除しましょう。

アドレスファミリーのポリシーとIPv6の条件

queryStrategyは、組み込みDNSが問い合わせ、または使用するアドレスファミリーを制限します。UseIPはIPv4とIPv6の両方を対象とし、UseIPv4またはUseIPv6は対象を明示的に限定します。アドレスファミリーは実際のネットワーク機能に合わせて設定してください。端末の画面にIPv6アドレスが表示されているかどうかだけでは判断できません。端末にローカルIPv6アドレスがあっても、接続先ネットワークまでIPv6の経路が確立しているとは限りません。一方、1度のタイムアウトを避けるためにシステム全体のIPv6を永久に無効にすると、他のアプリに影響することがあります。

特定のドメインが名前解決できても接続できない場合は、返されたアドレスファミリーとoutboundからの到達性を比較してください。IPv6のアドレスが返されたときだけ失敗するなら、対象を限定してIPv4での名前解決を試し、ローカルルート、リモート側の出口、サーバーの待ち受け状態を確認します。名前解決自体がタイムアウトする場合は、まずDNSサーバーへの接続経路を確認してください。「アドレスを取得できたこと」と「そのアドレスのサービスが利用できること」は別です。DNSの成功は応答を得たことを示すだけで、後続のポート接続やセキュリティハンドシェイクは個別に検証する必要があります。

ドメインに基づくDNSの振り分けでは、サーバーオブジェクトに対象ドメイン、必要なIP範囲、フォールバック関連の設定が含まれる場合があります。組み合わせの動作は単純なサーバー配列より複雑で、拡張項目もコアによって異なります。まず単一サーバーで正常に動作する状態を確認し、その後ドメイン範囲やフォールバック条件を追加してください。最初から複数の分類、アドレス制限、フォールバックのスイッチを同時に設定すると、空の応答が上流への接続失敗、応答のフィルタリング、条件の不一致のどれによるものか判断しにくくなります。

暗号化DNSを使う場合も、接続を確立できるネットワーク経路が必要です。上流サーバーのホスト名を解決するために、その上流サーバー自身を使う構成では起動時の依存関係が生じることがあります。プロキシノードのアドレスも、まだ確立していない同じプロキシ経路に依存している場合は、問題がさらに複雑になります。設定前に「ノードのアドレスを解決する」「ノードに接続する」「DNS上流にアクセスする」「サービスのドメインを解決する」の順序を整理し、互いに待ち続ける循環がないことを確認してください。暗号化通信の方式名だけで接続可能だと判断せず、実際の名前解決、ルーティング、接続権限も考慮しましょう。

DNS設定を検証するときは、キャッシュも考慮してください。システム、ブラウザー、アプリ、コアがそれぞれ結果を保存する場合があり、既存の接続が古いアドレスを使い続けることもあります。新しい接続とテスト対象のドメインを使い、ログを確認するのが基本です。必要に応じて、プラットフォームの適切な手順でキャッシュを消去するか、アプリを再起動してください。キャッシュの場所が分からないまま、DNSサーバーを何度も変更しないでください。以前の設定が後のテストでたまたま反映され、誤った結論につながることがあります。設定時刻と当時の構成を記録するほうが、ページが開いたかどうかだけを比べるより参考になります。

policy:接続のライフサイクルと統計設定

policyは接続先を選ぶ機能ではない

policyは接続処理や統計の動作を調整するもので、特定ドメインをプロキシノードに割り当てるものではありません。一般的な構造には、ユーザーレベルごとのlevelsと、システム全体の統計設定systemがあります。レベルのキーはJSON文字列で表し、たとえば"0"のように指定します。各ユーザーがどのレベルを使うかは、プロトコル設定とコア側の解釈によって異なります。明確な必要がなければ、設定を埋めるためだけに複数のレベルを追加する必要はありません。まず既定の動作を保ち、ログで再現できる接続問題がある場合に限って、必要な項目を少しずつ調整してください。

policyを理解するには、ハンドシェイク、通常のデータ転送、片方向の終了後という段階を区別します。ハンドシェイクタイムアウトは初期ネゴシエーション、アイドルタイムアウトは一定時間通信のない接続を対象にします。片方向の終了後の待ち時間は、もう一方の方向のデータ転送を続ける必要があるかに関係します。すべての値を小さくすると、正常な長時間接続が切断されることがあります。逆に、すべてを大きくすると、異常な接続がリソースを占有する時間が延びる場合があります。値を大きくすれば安定するわけではありません。アプリの接続方式と実際の症状に合わせて設定しましょう。

ユーザーレベルのpolicyとシステム統計の設定例

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

例にある時間は秒単位です。項目の構成を示すもので、あらゆるアプリに適した調整値ではありません。handshakeは対象接続のハンドシェイク待ち時間、connIdleはアイドル状態の接続、uplinkOnlyとdownlinkOnlyは片方向の通信終了後の待ち時間に関係します。実際にどこまで適用されるかは、プロトコルとコアの実装を確認してください。調整後にアップロード終了と同時にダウンロードが切れる、バックグラウンド接続が定期的に再確立されるといった症状が出た場合は、まず元の値に戻し、接続ログから問題の範囲を絞ります。policyをさらに追加して対処しないでください。

統計の有効化と画面表示は別に考える

統計を有効にしても、クライアントの画面にすべての数値がすぐ表示されるとは限りません。統計モジュール、問い合わせ用インターフェース、クライアント側の読み取り処理が連携する必要があります。ユーザー単位の統計には、プロトコルが対応するユーザー識別子などの条件も関係します。この例ではユーザーごとの送受信統計を明示的に無効にし、システムのinboundとoutboundに関する統計スイッチだけを示しています。クライアントが統計機能やインターフェースを自動生成している場合は、同名のモジュールを追加しないでください。重複設定が競合したり、画面が古いインターフェースを読み続けたりして、コアが動作しているのに表示が変わらないことがあります。

項目対象となる段階よくある誤解
handshake接続の初期ネゴシエーション値を大きくしても認証パラメーターの誤りは直らない
connIdle接続のアイドル中アプリのダウンロード全体にかかる時間の上限ではない
uplinkOnly下り通信の終了後、上りだけが残る状態アップロード速度の制限ではない
downlinkOnly上り通信の終了後、下りだけが残る状態ダウンロード速度の設定ではない

アイドル接続と低速接続も同じではありません。少量のデータを送り続ける接続をアイドルと判定するかは、コアの活動判定によります。アプリがハートビートを送信する方法も、接続の維持に影響します。一定間隔で切断される問題を調べるときは、アプリログの再接続時刻、コアが接続を閉じた理由、システムのスリープ記録を比較してください。PCのスリープ、Wi-Fiの切り替え、モバイル端末のバックグラウンド制限も、似た症状を引き起こすことがあります。特定の時刻に接続が切れたというだけで、connIdleの設定が不適切だと判断することはできません。

統計を確認する場合は、まずクライアントにある状態画面と、アクセスを制限したローカルインターフェースを使ってください。数値を見るために管理インターフェースをすべてのネットワークインターフェースへ公開してはいけません。インターフェースが存在するか、どこで待ち受けるか、誰がアクセスできるかは、それぞれ独立したセキュリティ上の境界です。通常のデスクトップ利用で、この章を読むためにリモート管理用の入口を自分で構築する必要はありません。統計はコアの再起動後にカウントがリセットされる場合もあります。クライアントの累積履歴と今回のプロセスのカウントをそのまま引き算して、設定の消失や通信の迂回を推測しないでください。

policyを変更するときは、まず症状を説明し、次に項目を選び、最後に副作用を確認するのが適切です。たとえば、アイドル後にコアが特定アプリの接続を終了していると確認できた場合に、関連する待ち時間を検討します。認証段階で失敗するなら、outboundのパラメーターを再確認してください。毎回、元の値、変更後の値、テスト条件を記録し、他の設定は変えないようにします。元に戻すときは、検証済みの設定全体を復元するほうが、記憶を頼りに1項目ずつ戻すより確実です。policyの調整は仕上げの段階で行います。inboundへの接続、outboundの動作、ルーティングの正しさという基本条件より先に変更しないでください。

クライアントとの連携:生成ファイル、サブスクリプション、コアの切り替え

クライアントに保存される設定を変更の起点にする

デスクトップではv2rayNが主な選択肢で、Windows、macOS、Linuxに対応しています。Androidでは、設定に応じてv2rayNGまたはv2flyNGを選べます。インストール先はクライアントのダウンロードページにまとめています。これらのクライアントは、ノード、モード、ルーティング設定を組み合わせて実行可能な設定を生成するため、画面の構成とJSONの項目が一対一で対応するとは限りません。このガイドを参照する際は、まず現在のクライアントに設定プレビュー、ログ、独自設定の機能があるか確認し、変更を画面と独立したファイルのどちらに保存するか判断してください。

サブスクリプションを追加すると、通常はクライアントが配信元情報とノード一覧を保存し、現在の選択に基づいて実行設定を生成します。ノードグループ、フィルター用キーワード、自動更新はクライアント層の機能であり、汎用のroutingやpolicy項目ではありません。コアのファイルにグループ名を追加しても、サブスクリプション一覧が自動で分類されるわけではありません。サブスクリプションから生成されたノードの設定を直接変更すると、次回の更新時に置き換えられることがあります。継続的に調整する場合は、配信元のデータとローカルの上書き設定を明確に分け、サブスクリプション更新によって検証中の設定が意図せず変わらないようにしましょう。

生成結果で確認する4つの対応関係

1つ目は、画面で選択中のノードが実際のoutboundに対応しているか。2つ目は、システムプロキシやアプリの設定が実際のinboundポートを指しているか。3つ目は、現在のルーティングモードが想定したルールと既定outboundを生成しているか。4つ目は、画面で選んだコアと起動ログに記録されたコアが一致するかです。この4点を確認してから、プロトコルの詳細を調べてください。ノードを切り替えたのに既存の接続が古い出口を使い続ける、別のバックグラウンドプロセスがシステムプロキシの接続先ポートを占有しているといった、「設定は正しそうなのに動作が違う」ケースの多くを説明できます。

{
  "inbounds": [
    {
      "tag": "local-http",
      "listen": "127.0.0.1",
      "port": 10809,
      "protocol": "http",
      "settings": {}
    }
  ],
  "outbounds": [
    {
      "tag": "direct",
      "protocol": "freedom",
      "settings": {}
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "inboundTag": ["local-http"],
        "outboundTag": "direct"
      }
    ]
  }
}

この独立した例では、HTTP inboundをdirect outboundに明示的に対応付け、画面のポートとタグの関係を示しています。現在のサブスクリプションを置き換えるための設定ではありません。クライアントの独自設定モードが実行ファイル全体を置き換える場合は、そのモードでもシステムプロキシの設定、ポートの更新、統計インターフェースの生成が自動で行われるか確認してください。機能ごとに設定欄の役割は異なります。ルーティングの追加欄に、inboundsとoutboundsをすべて含む設定ファイル全体を貼り付けないでください。保存前に欄の説明を読み、保存後は画面に成功と表示されたかだけでなく、実際の生成結果も確認しましょう。

コアの切り替えと通信の取り込みモードを分けて検証する

共通の項目名だけから、XrayとV2Flyの設定互換性を完全に判断することはできません。コアを切り替える前に、必要なプロトコルとトランスポート機能を確認し、古い設定を保存してください。切り替え後は再起動し、ログに表示されたコアの識別情報を確認してから、生成された設定に変更があるか調べます。独自ファイルを使っている場合、クライアントが一方のコア専用の項目を別系列で対応する構造に自動変換するとは限りません。不明な項目やプロトコルが表示されたら、まず元のコアに戻して基本接続が復旧することを確かめます。エラー項目をすべて削除するのではなく、互換性のある設定を一つずつ作成してください。

システムプロキシとTUNも、それぞれ別のテスト基準を設けます。まずすべての通信を取り込まない状態でローカルプロキシポートを確認し、次にシステムプロキシを有効にして、その設定に従うアプリをテストします。最後にTUNを検討してください。TUNでは追加の権限、仮想インターフェース、ルーティング、DNS設定が必要になる場合があり、利用できる機能は現在のクライアントと関連するコアによって異なります。有効化後にLANアクセスに問題が出たら、取り込み範囲とプライベートネットワークのルールを確認してください。特定のアプリがシステムプロキシを使わないだけなら、サブスクリプションの破損を最初に疑う必要はありません。

設定内容主な管理場所確認する場所
サブスクリプションの配信元、グループ、フィルタークライアントの管理層サブスクリプションとノード一覧
待ち受けポート、outboundのパラメーターコアの実行層生成ファイルと起動ログ
システムプロキシの接続先クライアントとシステム設定システム設定とアプリの実際の接続
TUNによる取り込みと権限クライアント、システム、関連する実装権限の状態、インターフェース、ルーティング

複数のサブスクリプションを使っている場合は、複雑な独自設定に取りかかる前に配信元とグループを整理してください。ノード更新後にパラメーターの出所をすぐ確認でき、動作確認済みの状態に戻すのも簡単になります。詳しくはv2rayNのサブスクリプショングループとノードフィルターをご覧ください。デスクトップの権限に関する問題は、macOSのインストールとネットワーク権限など、プラットフォームの導入手順に戻って確認してください。必要な権限がない状態でJSONを何度変更しても、システムによる通信の取り込み拒否は解消されません。

設定を移行する場合は、サブスクリプションの配信元、独自ルール、現在のプラットフォーム固有の項目を分けて記録してください。プラットフォームによって設定ディレクトリ、ファイル権限、ネットワーク権限は異なります。絶対パスをそのままコピーして使えると考えないでください。移行後はまずノードを1つ検証し、その後ルーティングとDNSの拡張設定を戻して、最後に通信の取り込みモードを確認します。最初の操作手順はクイックスタートガイドに沿ってください。このページでは項目を解説しますが、現在のクライアント画面の操作説明に代わるものではありません。

検証とトラブル対処:ファイルの読み込みから接続先まで

失敗した段階から原因を絞り込む

設定のトラブル対処は、起動、待ち受け、inboundへの接続、ルーティング、名前解決、リモート接続の順に進めます。コアが起動していない段階では、Webページが開くかどうかでルーティングの正しさを判断できません。アプリがinboundに接続していない場合も、outboundを変更して検証する意味はありません。まずクライアントのログを開き、コアを1度再起動して、今回の起動で最初に発生したエラーを見つけてください。後続の再試行ログから適当に1行選ぶのは避けます。最初のエラーが複数の警告を連鎖的に引き起こすことがあるため、すべての警告を同時に直すより、最初に確認できる失敗点を解消するほうが効果的です。

ファイルの読み込み段階では、JSON構造、項目の型、パスを重点的に確認します。特定の項目付近がエラーとして示されても、原因がその前にある場合があります。たとえば、直前の行のカンマ不足、閉じていない文字列、配列の終了位置の誤りです。エラー行だけを削除せず、まず最外層のオブジェクトと各モジュールの階層を整理し、最近変更した部分を比較してください。エディターで確認する場合は、ノード情報を含むファイルをローカルで扱いましょう。設定全体を、データ処理先が不明なWebページにアップロードしないでください。ログを共有する前に、アドレスと認証情報も削除します。

長時間運用の前にテストモードで確認する

コアのファイルを自分で管理している場合は、現在のコアがサポートする設定テスト用コマンドを先に実行できます。次の例はXrayのコマンド形式です。システムから対象の実行ファイルを呼び出せることと、作業ディレクトリに対象ファイルがあることが条件です。V2Flyではコマンド引数が異なる場合があるため、手元のプログラムのヘルプを確認し、別のコアの引数をそのまま使わないでください。GUIクライアントを使う場合は、まずクライアントのログと用意された検証機能を利用しましょう。コアを個別管理する必要がなければ、コマンドを実行するためだけに別の実行環境を追加する必要はありません。

xray run -test -config config.json

テストに成功しても、設定ファイルを現在のプログラムが受け入れたことが分かるだけで、リモート接続の可否やアプリがプロキシを使っているかまでは確認できません。次にポートの待ち受けを確認します。アドレスの使用中というエラーが出た場合は、クライアントの重複起動、古いコアプロセス、他のローカルサービスがないか確認してください。競合を避けるためにJSONのポートだけ変更し、システムプロキシやアプリの設定を更新し忘れないでください。コアは正常に起動しても、アプリが古いポートへ接続し続けることがあります。ポートを変更した後は、リクエストを新しく送信し、inboundログを確認してください。

記録できるログで通信経路を確認する

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

ログレベルを一時的にinfoにすると、実行情報を増やせます。ただし、実際に確認できる内容は、クライアントがコアの出力をどう取得するか、アクセスログを別途設定しているかによって異なります。ルート選択を確認するには、クライアントの接続履歴やアクセスログを見て、inboundタグ、接続先の形式、outboundタグを区別してください。問題を解決したら、普段使いに適したログレベルへ戻します。詳細ログにはアクセス先、端末のアドレス、接続時刻が含まれる場合があります。目的なく長期保存せず、公開の場に共有するときは必ず内容を確認・削除してください。

症状最初に確認する項目優先して変更しない項目
コアがすぐ終了する構文、項目の互換性、データファイルのパスシステムプロキシモード
待ち受けに失敗するアドレスの有無、ポートの競合、権限リモートの認証パラメーター
アプリの接続記録がないアプリの入口、システムプロキシ、ポートの対応ルーティングルールの順序
接続先が誤ったoutboundを通るルールの順序、条件の関係、タグ参照接続タイムアウトのpolicy
ドメインの名前解決がタイムアウトする実際に使われる名前解決層、上流経路、キャッシュサブスクリプショングループ名

inboundとルーティングが正しい場合は、名前解決とリモートハンドシェイクを確認してください。接続タイムアウトは、リモートポートへの接続でも、サービスの接続先へのアクセスでも起こり得ます。認証失敗、サーバー名の不一致、名前解決の失敗には、それぞれ異なる対処が必要です。ログに記録された接続先と失敗した段階を確認し、「タイムアウト」という言葉だけでノードの障害と判断しないでください。同じ設定でもネットワークによって動作が違う場合は、ネットワークの切り替え、アドレスファミリー、権限の条件を記録し、設定を変えずに比較しましょう。ネットワークの違いと設定変更を一度のテストに混在させないでください。

項目を一つずつ戻すことが、修正を検証する最後の手順です。まず動作確認済みの最小設定で接続し、次に接続先outbound、ルールを1つ、その後にDNSとpolicyの拡張設定を追加します。各段階の結果を保存しておけば、問題が起きたときに直近の変更を特定できます。テストルールでは、想定どおりに一致する接続先と、一致しない接続先の両方を確認してください。広範なルールによって特定のWebページだけ開けても、他の通信がすべて誤った出口を通ることがあります。既存の接続を終了してから再試行し、新しい設定が実際の判定に使われることを確認しましょう。

ログの詳しい読み方はログからconfig.jsonのエラーを特定する方法をご覧ください。繰り返し出てくる基本的な疑問はよくある質問、用語の意味は用語集で確認できます。最終的には、検証済みの設定を基準として保存し、サブスクリプション更新、クライアント生成、ローカル管理の各部分を明確に分けてください。アップグレードや移行の前に基準設定と比較し、項目の変更が必要か判断します。設定ファイル全体を最初から見直して原因を推測する手間を減らせます。