設定構造 · 項目の意味 · 動作確認
JSON設定ガイド
接続の流れに沿って確認します:ローカルのinbounds、outboundの選択、ルーティング判定、名前解決、接続ポリシー。
初めて使う場合は、まずクイックスタートガイドに沿ってサブスクリプションを追加し、接続してください。このページでは生成される設定やルーティングルールの変更、設定項目のエラーの見つけ方を解説します。クライアントの日常的な操作を説明するページではありません。インストール方法とプラットフォームの選択についてはクライアントページをご覧ください。
JSONの構造
項目を確認する前に、どの種類の設定を見ているのかを確かめましょう。v2rayNに保存された画面設定、サブスクリプションの内容、コアが実行する設定は別のものです。サブスクリプションにはサーバーへの接続情報が含まれます。クライアントは選択中のサーバーにルーティングのテンプレートや待ち受け設定を組み合わせ、コアに渡す設定を生成します。生成ファイルを直接編集しても、その変更は今回の実行時にしか反映されず、サーバーの切り替えやコアの再起動で上書きされることがあります。設定を継続して使うには、クライアントの該当する設定画面から変更してください。
オブジェクト、配列、値の型
JSONのトップレベルは波括弧で囲まれたオブジェクトです。オブジェクト内の項目は、二重引用符で囲んだ名前、コロン、値で構成され、複数の項目はカンマで区切ります。配列は角括弧で囲み、複数のinboundsやoutbounds、順序のあるルールなどを表します。文字列、数値、真偽値は互いに置き換えられません。待ち受けポートは数値、オン・オフの値はtrueまたはfalse、プロトコル名は文字列で指定します。最後の項目の後にカンマを付けず、厳密なJSONにはコメントを入れないでください。
以下は、一般的なV2RayおよびXrayコアで使えるローカル直接接続の基本設定です。ループバックアドレスで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": {}
}
]
}
トップレベルの設定項目
| 設定項目 | 役割 | 確認するポイント |
|---|---|---|
inbounds | アプリからの接続を受け付ける | 待ち受けアドレス、ポート、入口プロトコル |
outbounds | 接続先への通信を確立する | プロトコル、サーバー情報、outboundタグ |
routing | 接続に使うoutboundを選択する | ルールの順序、条件、タグ参照 |
dns | コアの名前解決機能を提供する | サーバー、ドメインの範囲、名前解決先 |
policy | 接続ポリシーと統計機能を管理する | ユーザーレベル、タイムアウト、統計機能の依存関係 |
各設定項目は、記述された順に実行されるのではなく、互いを参照して連携します。routingのoutboundTagはoutboundのtagを参照し、policyのレベルはプロトコルのユーザーに設定されたlevelに対応します。オブジェクト内の項目の並び順は通常意味に影響しませんが、配列の順序は動作を変えることがあります。特にルーティングルールとデフォルトのoutboundは順序を確認してください。設定を読む際は、個々の値より先に参照関係を確認しましょう。
設定ファイル全体と一部の設定
以降の例の多くはトップレベル設定の一部で、同じ名前の項目を置き換えたり統合したりするためのものです。routingを含むオブジェクトをそのまま連結したり、同名のトップレベル項目を重複して残したりしないでください。パーサーによっては重複キーを受け入れて一方の値を使うことがありますが、そうした挙動に依存するのは避けましょう。統合する際はトップレベルのオブジェクトを一つにまとめ、対象の項目を正しい階層に配置してから、括弧、配列、カンマを確認してください。
コア間で共通する概念はありますが、すべての拡張項目が共通とは限りません。転送方式、DNSオプション、ユーザーレベルの対応状況は、実際に使用するコアで確認してください。まず必要最低限の項目で動作する設定を作り、その後で機能を一つずつ追加すると、異なる配布元の設定を一度に読み込むより原因を特定しやすくなります。クライアントを更新した後も、生成される設定をあらためて確認しましょう。以前の画面キャプチャだけで項目が変わっていないと判断することはできません。
設定を記録するときは、コア名、クライアントでの設定場所、変更の目的も合わせて記録しておくと便利です。サーバーの認証情報を公開された画面キャプチャや文書に載せないでください。エラーは、構文を解析できない、項目がサポートされていない、接続の実行に失敗する、の三段階に分けて確認します。以降ではこの順に説明します。これにより、ポートの競合をプロトコルの問題と誤認したり、ルールに一致しない問題をJSONの記述ミスと取り違えたりするのを防げます。
inbounds:ローカルの待ち受け
inboundsは、アプリからコアへ接続を渡す方法を定義します。デスクトップ環境では、アプリにローカルのSOCKSまたはHTTPプロキシを使わせ、クライアントが対応する待ち受けを起動するのが一般的です。アプリに設定したアドレス、ポート、プロトコルはinboundと一致している必要があります。クライアントのウィンドウが表示されていても、コアの待ち受けが成功しているとは限りません。入口が有効かどうかは、システムトレイのアイコンだけでなく、起動ログや実際のポート使用状況で確認してください。
待ち受けアドレスとプロトコルの選択
listenはローカル端末でのバインド先であり、リモートサーバーのアドレスではありません。127.0.0.1を指定すると、入口はローカルのループバック接続だけを受け付けます。0.0.0.0に変更するとIPv4のネットワークインターフェース全体で待ち受けるため、LAN上の端末からそのポートに接続できる可能性があります。認証、防火壁、ネットワーク境界による制限も必要です。クライアントのLANアクセスを有効にするだけで、他の端末から必ず接続できるわけではありません。
{
"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
}
},
{
"tag": "http-in",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
}
この例では、Xrayの設定仕様に沿ってrouteOnlyを使用します。スニッフィングで取得した情報をルーティングに利用しますが、元の宛先は置き換えません。他のコアに切り替える前に、この項目がサポートされているか確認してください。ローカルの入口が動作するかだけを確認する場合は、まずsniffing全体を外して基本的な待ち受けを残します。入口が安定してからスニッフィングとドメインルールを試すことで、二種類の変数を同時に持ち込まずに済みます。
SOCKSとHTTPは別々の入口プロトコルです。アプリがHTTPプロキシにしか対応していない場合は、HTTP inboundのポートを指定してください。どちらもローカルのポートだからといって、互いに置き換えることはできません。SOCKS inboundでudpを有効にするのは、対応するUDP転送を許可するという意味です。アプリがサポートされた方法でUDP通信を送信し、リモートへの経路もその機能に対応している必要があります。通常のHTTPプロキシ入口は、すべてのUDP通信を取り込むものではありません。
ルールに渡されるドメイン情報
アプリはドメイン名をプロキシに渡すこともあれば、ローカルで名前解決してから宛先IPアドレスを渡すこともあります。前者ではドメインルールをそのまま利用できます。後者では、すでに得られている宛先情報やスニッフィングの結果も考慮する必要があります。スニッフィングが読み取るのは識別可能なプロトコルの特徴であり、一般的なコンテンツ復号ツールではありません。接続からドメインを判別できない場合、ハンドシェイクが別の仕組みで保護されている場合、対象プロトコルがサポート範囲外の場合には、正確なドメイン情報を取得できるとは限りません。
destOverrideのhttpとtlsは、スニッフィングの対象となるプロトコルの種類であり、outboundの転送方式を選ぶ設定ではありません。スニッフィングを有効にしてもTLSが自動で有効になることはなく、サーバー証明書の問題も解決しません。ドメインによる振り分けを確認する際は、アプリがドメインを渡しているか、使用中のinboundでスニッフィングが有効か、ルールが実際にドメインとIPのどちらを受け取ったかを確認してください。一つのスイッチだけを見ても判断できません。
ポートの競合とLANからのアクセス
同じ待ち受けアドレスとポートを複数のプロセスが同時に使用することはできません。クライアントの起動時に「アドレスが使用中」と表示されたら、まず重複して起動したインスタンスを終了し、別のプログラムが同じポートを待ち受けていないか確認してください。inboundのポートを変更した場合は、アプリのプロキシ設定とシステムプロキシ設定も合わせて変更します。変更しないと、新しいコアが正常に動作しても、アプリは古いポートに接続し続けます。保存前に古い値を記録しておけば、テストに失敗したときに元に戻せます。
LAN上の端末から入口を利用する場合は、まず端末同士が通信できるネットワークに接続されていることを確認し、次にバインドアドレス、OSのファイアウォール、アクセス認証を確認してください。認証なしのnoauthを使ったローカル向けの例を、信頼できないネットワークにそのまま公開しないでください。インターフェース全体を開放するより、特定の端末だけにアクセスを許可するほうが安全です。他の端末からの接続が入口に到達した後は、ルーティングルールも適用されます。入口への接続と接続先への到達性は分けて検証してください。
inboundのタグは、安定していて分かりやすく、一意になるように設定します。たとえばブラウザーとテスト用プログラムに別々のタグを割り当て、ルーティングのinboundTagを使って入口ごとの動作を確認できます。タグに認証機能や特別な意味はありません。設定内で参照する名前にすぎないため、綴りを変えると関連ルールにも影響します。トラブル対処では、名前が似ているだけで関連付けられていると判断せず、一字ずつ照合してください。
outbounds:接続先とプロトコルの設定
outboundは、コアが次の接続をどのように確立するかを決めます。直接接続、通信の遮断、リモートプロキシへの接続はいずれもoutboundの役割ですが、それぞれ目的は異なります。outboundが設定されていても、ルーティングで選択されなければ使われません。ルールに一致しない場合にどのoutboundが使われるかも確認してください。通常は想定するデフォルトのoutboundを配列の先頭に置き、ルールから参照するoutboundには一意のタグを付けます。判別しにくい位置関係に依存しないようにしましょう。
プロトコルと転送方式の階層
protocolは、outboundで使うプロキシプロトコルまたは処理方式を指定します。リモートアドレス、ポート、ユーザー情報は通常settingsに記述し、転送方式や接続のセキュリティ設定は通常streamSettingsに記述します。プロトコル、転送方式、セキュリティ層は連携する別々の要素です。プロトコル名だけで接続方式全体が決まるわけではありません。両端のプロトコルが一致していても、転送経路、サービス名、セキュリティ設定が異なると、ハンドシェイクに失敗することがあります。
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
この例にはリモートサーバーが含まれておらず、outboundの参照関係を理解するためのものです。freedomはローカル端末から接続先へ直接接続しますが、ドメインを名前解決するか、どのアドレスを使うかは関連設定にも左右されます。blackholeは一致した通信を破棄し、明確に遮断したい範囲に使います。標準的な動作では、アプリ側に接続失敗やタイムアウトとして表示されることがありますが、接続先のサイトに問題があるとは限りません。原因を調べるには、ルールによって通信が遮断用のoutboundに送られていないか確認してください。
VLESSの設定項目の対応関係
VLESSの接続先情報は、サーバーの設定または信頼できる共有情報から取得する必要があります。vnextはサーバーの一覧を表し、その中のaddressとportで接続先を指定します。users内のidはユーザーを識別します。例をもとに実際の接続情報を作成しないでください。また、サブスクリプションのグループ名をサーバーアドレスとして入力しないでください。アドレス、ユーザー情報、転送とセキュリティの設定は、同じサーバー設定に基づく必要があります。
VLESSでは、encryptionの一般的な値であるnoneはプロトコルのユーザー設定を表し、接続全体にセキュリティ層がないという意味ではありません。TLSやREALITYなどの接続セキュリティ方式は、使用するコアがサポートする転送設定で指定します。それぞれのパラメーターを混同しないでください。サーバー名、証明書の検証、公開鍵、識別子には個別の意味があります。項目の意味が分からない場合は元の共有情報を確認し、エラーを回避するために検証を無効にしないでください。
VMess、VLESS、Trojanでは、認証情報の構造も異なります。あるプロトコルのユーザー設定を、そのまま別のプロトコルにコピーしないでください。最も確実なのは、有効な共有リンクをクライアントに読み込ませ、生成された設定を確認して、各接続情報がどの階層に配置されたかを理解する方法です。プロトコルの概要を比較する場合は用語集をご覧ください。このページでは項目の配置と参照関係を説明し、用途を問わずプロトコルに順位を付けることはしません。
デフォルトoutboundと接続の確認
プロキシoutboundを設定しても、どのルールからも参照されず、デフォルトにも設定されていなければ、そのサーバーが自動的に使われることはありません。反対に、プロキシoutboundを配列の先頭に置くと、他のルールに一致しない接続はプロキシ経由になります。配列の順序を変えると、ルールに一致しなかった場合の動作が変わります。変更前に「どの接続を直接接続し、何を遮断し、それ以外をどこに送るか」を一文で説明できるようにしてください。その説明が実際の配列とルールに対応している必要があります。
リモート接続を確認する場合は、まずローカル端末からサーバーのアドレスとポートに接続できるか、次に転送方式のハンドシェイクが成功するか、最後に接続先へのリクエストが通るかを確認します。サーバーのポートに到達できても、ネットワーク層から応答があっただけで認証の成功を意味しません。証明書名の誤り、転送設定の不一致、無効なユーザー識別子は、後の段階でエラーになります。クライアントに表示される遅延の結果も、アプリからの実際のリクエストの代わりにはなりません。ログに記録されたエラーの段階も確認してください。
コアを切り替えた後は、使用中のコアがプロトコルと転送方式の両方をサポートしているか、生成された設定に必要なオプションが残っているかを確認してください。画面に同じサーバー名が表示されているだけで、内部の接続情報もすべて同じだとは判断できません。カスタムoutboundを使う場合は、元のインポート情報と動作確認済みの設定を保存しておくと、インポート時の変換、コア間の違い、サーバー設定の変更を切り分けやすくなります。
routing:ルール判定と振り分け
ルーティングは接続に使うoutboundを選びます。リモートサーバーの設定を変更するものではありません。ルールは通常、配列の順に評価され、最初に一致したルールで接続先が決まります。一致するルールがなければデフォルトのoutboundが使われます。ルールを設計するときは、対象範囲が狭く意図が明確な例外を先に、範囲の広いルールを後に置きます。前のルールですべての宛先に一致すると、後続のルールは記述が正しくても実行されません。ルールが存在するかどうかだけでは、問題を特定できません。
ドメインルールとIPルール
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": ["full:example.com"],
"outboundTag": "block"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
}
]
}
}
この設定例では、blockとdirectという二つのoutboundが必要です。full:example.comは指定した完全一致のドメインだけに適用され、すべてのサブドメインを自動的に含むものではありません。ドメインとそのサブドメインも対象にする場合は、適切なdomain:形式を使用してください。一般的な実装では、接頭辞のない文字列がキーワードとして扱われることがあります。似た名前まで誤って一致しないよう、ルールでどのように照合するかを明示しましょう。
geosite:cnとgeoip:privateはルールデータのカテゴリを参照するもので、名前から実行時に内容が推測されるわけではありません。コアが該当するデータファイルを読み込めること、必要な項目が含まれていることが前提です。データがないと起動に失敗することがあり、データ更新によって実際の対象範囲が変わる場合もあります。ドメインの振り分け結果が想定と異なるときは、まず明示的なドメインルールで検証し、データの分類とルールの順序のどちらが違いを生んでいるか確認してください。
domainStrategyで制御する範囲
AsIsは、ルーティング時に既存の宛先情報を中心に照合し、IPルールのために積極的な名前解決を行わない設定です。IPIfNonMatchは、ドメインがルールに一致しなかった場合に名前解決を試み、その結果を使って関連ルールを確認します。IPOnDemandは、判定中にIPアドレスが必要な条件に達した時点で名前解決を行います。これらが影響するのはルーティングの判定段階です。システムDNS全体の切り替えではなく、他のアプリからの名前解決要求がコアに届くことを保証するものでもありません。
| 条件 | 主な用途 | 注意点 |
|---|---|---|
domain | ドメインのカテゴリで振り分ける | 接続にドメイン情報が含まれるか復元できる必要がある |
ip | アドレスやネットワーク範囲で振り分ける | ドメイン宛ての接続では、先に名前解決が必要な場合がある |
port | 接続先ポートの範囲を制限する | ローカルの待ち受けポートではない |
inboundTag | ローカルの入口ごとに振り分ける | 実際のinboundタグと一致させる必要がある |
network | TCPとUDPを区別する | 経路が対応する転送機能を備えている必要がある |
一つのルールに異なる種類の条件を記述した場合、通常はすべての条件を満たす必要があります。同じ種類の条件に複数の候補値を指定した場合は、いずれかに一致すればよいのが一般的です。たとえば、一つのルールにドメインとポートを指定すると、そのドメインへの指定ポートの接続が対象になります。ドメインまたはポートのどちらかに一致すればよい、という意味ではありません。独立した二つの条件を表したい場合は、ルールを分けてください。ルールを短く保つと、ログやテスト結果から実際に一致した条件を判断しやすくなります。
フォールバックルールと元に戻す方法
ルーティングテンプレートでよくある問題は、フォールバックルールが早すぎる位置にある、タグの綴りが違う、接続先ポートを入口ポートと取り違える、といったものです。まずテスト用のドメインを一つだけ使った最小ルールを作り、指定のoutboundに送られることを確認してから、データカテゴリや複数条件を追加してください。一度に変更するルール群を一つに絞り、テスト後に一致したoutboundタグを記録します。複数の配布元のルールを一度に統合すると、ルール同士が遮り合った場合、どの変更で動作が変わったか判断しにくくなります。
プライベートアドレスを直接接続する場合も、ネットワークの用途を考慮してください。LAN上のサービスが内部ドメイン名を使い、アプリがそれをプライベートアドレスに解決することがあります。公開ドメインのルールだけでは、そうした接続を対象にできない場合があります。一方、プライベートネットワークの対象範囲を広げる前に、特別な経路が必要な内部通信まで誤って別の場所に送られないか確認してください。ルールは実際のネットワーク境界を表すものです。「プライベート」という名前だけで、すべてのアクセス制御を無視してよいわけではありません。
クライアントのグローバル、バイパス、ルールといったモードは、別々のテンプレートでルーティングを生成する場合があります。名前が似ていても、生成される設定が完全に同じとは限りません。モードを切り替えた後は、切り替え前のファイルではなく、新たに生成された設定を確認してください。ルーティングとDNSの関係も合わせて調べましょう。ルーティングで名前解決が必要になり、DNSサーバーへの接続にもoutboundが必要な場合、両者が依存するため、基盤となるネットワーク経路を明確にする必要があります。
dns:名前解決の経路とアドレス選択
コアのDNSは、DNSを利用する内部処理に名前解決結果を提供します。トップレベルにdnsを追加しただけで、システムの名前解決先が自動的に置き換わるわけではありません。アプリが先にシステムDNSで名前を解決してからIPアドレスをプロキシに渡す場合、コアが受け取るのはIPアドレスだけかもしれません。アプリがドメイン名をプロキシに渡す場合は、ルーティングやoutboundが内蔵DNSを呼び出すことがあります。名前解決の問題を調べるには、まず誰が問い合わせを行い、その問い合わせがどのサーバーに送られるかを確認してください。
静的マッピングとサーバーの対象範囲
{
"dns": {
"hosts": {
"local.test": "127.0.0.1"
},
"servers": [
{
"address": "223.5.5.5",
"domains": ["geosite:cn"]
},
"1.1.1.1"
],
"queryStrategy": "UseIPv4"
}
}
この設定例では、コア内部の静的マッピング、ドメイン別の優先DNSサーバー、問い合わせるアドレスの種類を示します。システムのhostsファイルに項目を書き込むものではありません。local.testはマッピングの階層を説明するためのもので、アプリから接続できるかどうかは、アプリがコア経由で名前解決するかにも左右されます。domainsは該当するDNSサーバーを優先するドメインの範囲を指定しますが、他の名前解決経路を遮断するネットワークファイアウォールルールではありません。
複数のDNSサーバーをどのように選ぶかは、コアの実装やフォールバックのオプションにも左右されます。「最初のサーバーに失敗したら次を順に試す」と単純に考えることはできません。特定の種類のドメインを特定のサーバーで解決する必要がある場合は、使用中のコアのフォールバックと照合の動作を確認し、実際の問い合わせ結果で検証してください。例に示すパブリックDNSアドレスは項目の形式を示すものであり、実際に設定する際は現在のネットワークから到達でき、用途にも合ったDNSサービスを選んでください。
DNSとルーティングの相互依存
ルーティングにIPIfNonMatchを使う場合、ドメイン宛ての接続はまずドメインルールで判定され、一致しなければ名前解決が行われ、その後にアドレスを使って再度判定されることがあります。名前解決に失敗すると、後続の判断に必要な情報が得られず、通常の接続タイムアウトのように見えることもあります。一方、DNSの問い合わせ自体にもネットワーク経路が必要です。名前解決の方法によって、コアのルーティングを通る場合もあれば、ローカル経路を使う場合もあります。DNSアドレスを設定しただけで、その通信に使うoutboundまで決まると思い込まないでください。
暗号化されたDNSサービスを使う場合は、DNSサーバー名の最初の名前解決も考慮してください。DNSサービスへの接続にそのサービスのドメイン解決が必要で、その名前解決がまだ確立していないプロキシ接続に依存すると、循環依存が起きることがあります。まず基礎となる名前解決やサーバーアドレスに到達できる経路を用意し、その後で振り分けを追加してください。トラブル対処では、いったん明示的に到達可能なアドレスを使い、障害が名前解決、転送の確立、接続先サーバーの応答のどの段階にあるか確認できます。
hostsは、少数の明確な内部マッピングやテスト用の上書きに適しています。変化の多いパブリックサービスのアドレスを大量に長期間手動管理する用途には適しません。サービスのアドレスは地域、負荷、ネットワークによって変わることがあり、固定マッピングを長期間使うと適切でない接続先に接続する場合があります。追加する前に目的を記録し、テスト後は不要になった項目を削除してください。残しておくと、サーバー設定を変更した後も古いマッピングが優先され続けることがあります。
IPv4、IPv6と接続先への通信
queryStrategyは、内蔵DNSが問い合わせる、または選択するアドレスの種類を指定します。例にあるUseIPv4は、IPv6経路の問題を切り分けるのに役立ちますが、すべてのネットワークで長期的に最適な選択とは限りません。IPv6アドレスが名前解決で得られても、使用中のoutboundからIPv6で接続できるとは限りません。IPv4アドレスだけが得られた場合も、別の名前解決経路からアプリがIPv6アドレスを取得している可能性があります。問い合わせ結果と接続結果は別々に確認してください。
ルーティングのdomainStrategy、DNSのqueryStrategy、直接接続outboundのアドレス戦略は、それぞれ異なる階層の設定です。名前は似ていますが、適用される対象が異なります。「戦略を変えても動作が変わらない」ときは、まず項目がどの設定ブロックにあるか、対応する処理で実際に使われているかを確認してください。アプリからすでにIPアドレスが渡されている場合、接続処理に関与していないDNSサーバーの項目を変更しても、その接続の動作は通常変わりません。
問題を切り分ける際は、まずサーバー名を解決できるか、次にDNSサービスへ接続できるか、続いて接続先から想定したアドレスが返るかを確認し、最後にルーティングで正しいoutboundが選ばれているかを調べます。DNSサービスの切り替え、アドレスファミリーの変更、全ルールの並べ替えを同時に行わないでください。変更は一度に一つにし、失敗した段階を記録すると、DNSの障害、アドレスへの到達性、outboundのハンドシェイク問題を切り分けられます。
policy、ログ、接続ポリシー
policyは接続のライフサイクルや統計の動作を管理するもので、プロキシサーバーを選んだりネットワーク品質を自動的に改善したりするものではありません。変更する前に、問題が接続の確立、アイドル状態の維持、送受信の終了のどの段階で起きているか確認してください。すべてのタイムアウトを延ばすと失敗が遅れて発生するだけかもしれません。すべてを短くすると、低速なネットワークで正常なリクエストまで早く終了することがあります。policyの値は、具体的に説明できるアプリの動作に合わせて調整してください。一般的な高速化スイッチとして扱わないでください。
ユーザーレベルと接続時間
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false,
"statsOutboundUplink": false,
"statsOutboundDownlink": false
}
}
}
ここで使う時間の単位は秒です。数値はよくある項目の組み合わせを示すもので、あらゆるアプリに適した推奨値ではありません。handshakeはプロトコルのハンドシェイクに許される時間を制限します。connIdleは接続のアイドル状態を許容する時間を表します。上りまたは下りの片方向の通信後に接続を維持する時間には、uplinkOnlyやdownlinkOnlyなどの項目が関わります。実際に適用されるかはプロトコルの実装や接続状態にも左右されます。OS上のすべてのソケットに共通するタイムアウトではありません。
levelsのキーには、レベル番号を文字列で指定します。ユーザーレベルに対応するプロトコル設定内のlevelと一致させる必要があります。レベルの定義を追加しただけで、すべての接続がそのレベルに切り替わるわけではありません。変更後に動作が変わらない場合は、現在のプロトコルでそのpolicyが使われているか、ユーザーレベルが一致しているかを確認してから、数値を調整してください。対応範囲は、使用するコアで確認する必要があります。
統計の有効化と表示までの経路
policy内の統計用の真偽値は、該当する種類のデータを記録するかどうかを決めるだけで、参照可能な統計サービスがすでにあることを意味しません。統計を表示するには、stats、APIサービス、タグ、クライアント側の読み取り処理も関わる場合があります。一部だけが有効な場合、画面にデータが表示されなくても、通信がコアを通っていないとは限りません。デスクトップクライアントが統計に必要な項目を自動生成することもあるため、カスタム設定でその内容を根拠なく上書きしないでください。
ユーザー向けの通信量表示は、課金や完全なネットワーク監査の根拠としてそのまま使うのにも適していません。どの入口を通ったか、直接接続の通信が含まれるか、いつ統計がリセットされるかは、実際の実装によって異なります。トラブル対処では、統計を補助的な情報として利用します。ルールに一致した後、対応するoutboundで通信が発生しているか、サーバーを切り替えた後に新しいoutboundに通信が記録されるかを確認してください。累計値だけで実際のリクエストやログの検証を代用しないでください。
ログレベルと機密情報
{
"log": {
"loglevel": "warning",
"dnsLog": false
}
}
普段は警告レベルを維持し、問題を再現する短い時間だけログの詳細度を上げる方法があります。詳細なログには、接続先のドメインやアドレス、内部ネットワーク情報が含まれる可能性が高くなります。問い合わせを送る前に、サーバーの認証情報、サブスクリプションの完全なURL、不要な個人のアクセス記録を削除してください。エラーの種類、発生順序、関連するタグは残します。状況の説明をすべて削って「接続できない」だけにしても、問題の段階を特定するのは困難です。
ファイルの出力先を指定していない場合、ログはプロセスの標準出力に書き込まれ、クライアントが収集することがあります。ファイルへの出力先を明示した場合は、ディレクトリが存在することと、実行アカウントに書き込み権限があることを確認してください。クライアント自身の設定フォルダーに書き込めても、コアが任意のパスに書き込めるとは限りません。ログのパスが正しくない、ディスクの空き容量が足りない、他のプログラムによってディレクトリへのアクセスが制限されているなどの理由で、想定したログが生成されないことがあります。それだけでコアが実行されていないとは判断しないでください。
長時間接続が切れる場合は、アプリ独自のタイムアウト、サーバー側のアイドル制限、ネットワーク機器の接続維持、コアのpolicyの四つを比較してください。コアのアイドル処理が原因だと分かった場合に限り、connIdleなどの値を調整します。アプリによっては定期的に接続維持のリクエストを送信しますが、そうでないアプリもあります。同じpolicyでも動作が異なることがあるため、一度のテスト結果をすべてのアプリに当てはめないでください。
起動に失敗する場合、最初にpolicyを確認する必要はありません。まずJSONの構文、項目の互換性、待ち受けポートを確認し、その後でリソースのパスと権限を調べます。起動後に特定のリクエストだけが失敗する場合は、outboundのハンドシェイク、DNS、接続タイムアウトを確認してください。障害が起きた段階に合わせて確認すれば、根拠のないパラメーター変更を減らし、説明やロールバックができる設定を維持できます。
クライアント設定とコア設定の違い
クライアントはサーバー、サブスクリプション、ルーティングテンプレート、実行方法を管理し、コアは接続を処理します。デスクトップではv2rayN、Androidでは用途に合わせてv2rayNGまたはV2Flyをコアに採用したv2flyNGを選べます。各クライアントで設定画面の名前や生成手順は異なり、デスクトップの画面にある各スイッチを、そのまま共通のJSON項目に置き換えることはできません。設定を確認するときは、クライアント、OS、現在使用しているコアのどれに属する設定かを先に判断してください。
サブスクリプション管理と生成ファイル
サブスクリプションはサーバー情報を配布する方法であり、V2Rayのトップレベルにあるsubscription設定ではありません。v2rayNのサブスクリプションのグループ、自動更新の間隔、更新時のリクエスト方法はクライアントに保存されます。コアが受け取るのは通常、解析されて生成されたoutboundの設定です。サブスクリプションの更新間隔を変更しても、既存接続のタイムアウト設定は変わりません。outboundのユーザー情報を変更しても、無効なサブスクリプションURLが自動で修正されるわけではありません。
サブスクリプションを更新する前に、現在使える設定を保存してください。更新後は、グループ、サーバー数の変化、現在選択しているサーバーを確認します。特に、選択中のサーバーが削除されたり名前が変わったりしていないか注意してください。サブスクリプションで管理される項目を手動で変更しても、次回の更新で上書きされる場合があります。カスタム設定を長期的に使う場合は、クライアントが対応する永続設定や独立したカスタム設定を使い、実行用ファイルをサブスクリプションのデータベース代わりにしないでください。
更新に失敗した場合は、リクエスト先に接続できない、サーバーがエラーを返す、内容の形式を認識できない、のどれかを確認します。ブラウザーでページを開けても、それがクライアントで解析できるサブスクリプションとは限りません。完全なURLにアクセス認証情報が含まれていることがあるため、公開しないでください。インポート手順と共有リンクの形式はサブスクリプションリンクのインポート方法をご覧ください。初回の設定は、引き続きガイドの手順に沿って進めることをおすすめします。
TUNモードと通信の取り込み
TUNは仮想ネットワークインターフェースを通じてネットワーク層の通信を受け取ります。OSのルーティング、権限、DNSの取り込み、除外ルールが関わるため、一般的なV2Rayのトップレベルオブジェクトにtunを追加する機能ではありません。クライアントが別のコア設定を使って実現する場合があり、その項目の構造はこのページで扱う一般的なV2RayやXrayの設定とは異なります。v2rayNのTUNモードの設定画面から、実際に生成された内容と関連ログを確認してください。
有効にする前に、通常のプロキシ入口が動作することを確認し、次に権限、仮想インターフェース、OSのルーティングが正常に設定されたか確認します。通常のプロキシが使えてTUNだけ使えない場合は、まず通信を取り込む経路を調べ、リモート接続のプロトコル設定をすぐに書き換えないでください。サーバー接続が誤って仮想インターフェースに戻され、ループしていないか、LAN上のサービスを除外する必要がないかも確認します。他の仮想ネットワークソフトと同時に使う場合は、ルーティングの優先順位が結果に影響することがあります。
複数のコアを切り替える
コアの選択は、名前を切り替えるだけではありません。プロトコルの対応状況、転送設定の項目、ルールデータ、クライアントが生成する設定形式に影響します。v2rayNGではXray、v2flyNGではV2Flyが一般的に使われます。v2rayNで実際に選べる項目は、インストール済みのコンポーネントによって異なります。切り替え後はサーバー情報、ルーティング、DNSを再確認し、一方のコア固有の拡張設定を別のコアにそのままコピーしないでください。エコシステムの関係については、このサイトについての背景説明をご覧ください。
システムプロキシとアプリの動作
システムプロキシはクライアントがOSやデスクトップ環境のプロキシ設定を書き換える機能で、コア共通のトップレベル設定項目ではありません。システムプロキシ設定に従うアプリにのみ有効です。アプリが引き続き直接接続する場合は、まず独自のプロキシ設定があるか、次にどの種類の通信かを確認してください。コアを終了してもシステムプロキシが以前のローカルポートを参照したままだと、アプリで接続エラーが続くことがあります。その場合は設定ファイルを削除するだけでなく、システムプロキシも解除してください。
クライアントの更新やリセットの前に、サブスクリプションのグループ、ルーティングテンプレート、カスタム設定をそれぞれバックアップしてください。復元も段階的に進めます。最初に使えるサーバーを復元し、次にルール、最後に通信の取り込み方法を復元してください。古い設定をすべて一度に読み込んで問題が再発すると、古い項目の非互換性、生成処理の変更、システムプロキシや仮想ネットワークの状態が想定どおり復元されなかったことのどれが原因か判断しにくくなります。
設定の検証と段階的なトラブル対処
設定の検証は、「解析できる」状態から始め、「期待どおりの結果になる」ことまで段階的に進めます。構文が正しいのは、ファイルの構造を読み込めるという意味にすぎません。項目がサポートされていても、リモートサーバーに接続できるとは限らず、接続が成功してもすべてのルールが想定どおりに適用されるとは限りません。段階ごとに独立したテスト目標を設定し、前の段階を通過するまでは、次の段階の項目を変更して当たりを探すのは避けてください。
元に戻せるテスト用の基本設定を作る
まず現在使える設定と、それに対応するクライアント設定を保存し、使用中のコアを記録します。テスト用のコピーでは設定項目を一つだけ変更し、ローカルポートでリクエストを受け付けられる、特定のドメインが指定したoutboundを使う、LAN内のアドレスが直接接続される、など成功条件を明確にしてください。テスト中にサブスクリプションを更新し、コアを切り替え、ルールを並べ替えるといった操作を同時に行わないでください。変化する要素を少なくするほど、結果の原因を説明しやすくなります。
クライアントに設定の検証機能や生成設定の表示機能があれば、まずそれを使ってください。実行時の設定に変更内容が反映されていることを確認してから、エラー出力を調べます。クライアントによっては、コアの起動前に一時ファイルを生成します。古いファイルを手動で編集しても、次回起動時の設定には影響しません。保存後に変更内容が消える場合は、設定の保存元を確認してください。上書きされる同じファイルを繰り返し編集しないでください。
障害の段階に沿って範囲を絞る
| 症状 | まず確認する項目 | 次に行う確認 |
|---|---|---|
| 設定を読み込めない | 括弧、カンマ、値の型、重複キー | 最小構成のトップレベルオブジェクトに戻す |
| コアの起動に失敗する | 未対応の項目、ポート、リソースのパス | 最初の有効なエラーを確認する |
| アプリが入口に接続できない | 待ち受けアドレス、ポート、入口プロトコル | ローカルプロキシを明示的に指定する |
| 入口には接続できるが、リモート接続に失敗する | サーバーアドレス、認証、転送のセキュリティ設定 | 接続とハンドシェイクの段階を区別する |
| 一部のドメインだけ異常がある | ルールの順序、DNS、アドレスファミリー | 一つのドメインで最小ルールをテストする |
| 再起動後に変更が消える | 設定の保存元と生成の仕組み | クライアントの永続設定から変更する |
構文エラーでは、エラーが示す項目の周辺を確認するとともに、直前の行でカンマが抜けたり余分に付いていたりしないか確認してください。値が一見もっともらしくても、項目の型に合っていない場合があります。たとえば、ポートの数値を不適切な文字列で記述しているケースです。起動エラーでは、最初に発生した実質的なエラーを優先して対処します。その後に表示される「プロセス終了」は、元の問題の結果であることがよくあります。エラーの最後の一文だけでなく、全体の順序を残しておくほうが原因を調べやすくなります。
コアがすでに動作している場合は、システムの自動プロキシ判定に頼らず、プロキシを確実に使えるアプリからローカルの入口に直接接続してください。このテストに成功し、他のアプリで失敗する場合は、アプリごとの入口設定とシステムプロキシを重点的に調べます。すべてのアプリで接続できない場合は、待ち受けとコアのプロセスを確認してください。ローカル入口には接続できても接続先への通信に失敗するなら、リモートのハンドシェイクとルーティングを調べます。これら二つの段階をまとめて「インターネットに接続できない」と扱わないでください。
狭い範囲のルールで実際の接続先を確認
ルーティングを調べるときは、安定して再現できる接続先を一つ選び、それを一時的に先頭付近の明示的なドメインルールに追加して、動作確認済みのoutboundを指定します。動作が変わることを確認したら、元のカテゴリルールと追加条件を一つずつ戻してください。明示的なルールを使っても変化がない場合は、アプリがドメイン名を渡しているか、想定したinboundを通っているか、現在実行中の設定を確認しているかを調べます。この段階でルールデータをさらに増やしても、根本的な問題は解決しません。
DNSを調べる際は、問い合わせの経路と接続先のIPアドレスを一緒に記録してください。ドメインからアドレスを取得できても接続できない場合は、そのアドレスファミリーとoutboundの接続性を確認します。名前解決そのものに失敗する場合は、DNSサービスと基盤となるネットワーク経路を重点的に調べてください。ブラウザーに表示されたエラーページだけで問題の箇所を判断しないでください。同じタイムアウトの表示が、入口ポート、名前解決、リモート認証、接続先サービスのどこから発生しているかは異なる場合があります。ログの時系列は、各段階を関連付ける重要な手掛かりです。
ロールバックと再現できる記録
テストに失敗した場合は、直近の動作確認済み設定に戻し、関連するコアを再起動して、待ち受けとシステムプロキシの状態が一致しているか確認してください。TUNを無効にする際は、クライアントの手順に沿って仮想インターフェースとシステムルートが元に戻ったことも確認します。クライアント自体が起動しない場合は、起動時のクラッシュを解決する方法を参考に、実行環境の問題とコア設定の問題を切り分けてください。ウィンドウが開かない原因がJSONとは限りません。
最終的に使う設定では、次の三点を説明できるようにしてください。アプリはどの入口から接続するのか、なぜそのルールでoutboundが選ばれるのか、ドメインはどこで名前解決されるのか。説明できない項目は、長期的な設定として残さないでください。検証が終わったら日常利用ガイドで接続とモードを管理し、インストール先のプラットフォームを変更するときはクライアントのダウンロードページをご覧ください。日常的な操作と設定の実験を分けておくと、今後の更新やトラブルからの復旧が分かりやすくなります。