設定ファイルの構造とリクエストの流れ
V2Rayの設定ファイルは、JSONオブジェクトをルートとして構成されます。まずinbounds、outbounds、routingを確認しましょう。inboundsがアプリからのリクエストを受け取り、routingが接続先のoutboundを選び、outboundsがその後の接続を担います。dnsはコアが利用する名前解決機能を定義し、policyは接続時間や統計に関する一部の設定を管理します。各項目は相互に参照されますが、ファイルの上から順にすべて実行されるわけではありません。通常、トップレベルのキーの並び順が処理に影響することはありません。
混同しやすいデータを3種類に分けて考えましょう。サブスクリプションには接続先の情報、クライアント設定には画面や動作のオプションが保存されます。コアの実行設定は、クライアントがこれらを組み合わせてコアに渡すものです。サブスクリプションの内容が完全なJSONとは限らず、クライアント独自の設定ファイルをコアが直接読み込めるとも限りません。サーバー一覧、ウィンドウの状態、サブスクリプションの更新日時などが含まれていても、拡張子だけで実行設定と判断しないでください。クライアントのログや設定確認機能、カスタム設定の説明から、ファイルの用途を確認しましょう。
基本構成:ローカルプロキシの入口と直接接続の出口
以下は、V2Ray形式の基本的な設定例です。ループバックアドレスでSOCKSとHTTPの入口を提供し、通常のリクエストはすべて直接接続します。リモートプロキシサーバーは含まれていません。inbounds、outbounds、routingのつながりを確認するための例であり、サブスクリプションから生成されるプロキシ設定の代わりにはなりません。ポート番号は本ページの例で使用する値です。利用前に他のプログラムと競合しないことを確認してください。使用中のクライアントがmixed形式のinboundを生成する場合、実際のポート構成は異なることがあります。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
},
{
"tag": "http-in",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
}
]
}
}
ここで使うdirectとblockは任意の識別子で、予約語ではありません。routingのoutboundTagは、outboundのtagと完全に一致させる必要があります。どのルールにも一致しないリクエストは、デフォルトで最初のoutboundに渡されるため、この例では直接接続されます。プライベートアドレスのルールには、対応する地理データが必要です。実行環境にデータがない場合は、まず読み込みの問題を解決してください。用途を理解したうえで明示的なアドレス範囲に置き換える方法もありますが、起動エラーを無視しないでください。
JSON構文とコアの動作を分けて確認
標準JSONでは、キー名と文字列を二重引用符で囲みます。数値と真偽値には引用符を付けず、配列やオブジェクトの最後にカンマを付けることもできません。本ページのコード例は標準JSONで記述しており、設定内にコメントは含めていません。一部の読み込み方法では拡張構文を使えますが、あるクライアントが受け付ける書き方が、すべてのコアで使えるとは限りません。コピーする際はコード部分だけを選択し、見出しや説明文、コードブロックの境界を含めないでください。
構文が正しくても、項目が有効とは限りません。"port": 10808は数値のポート、"udp": trueは真偽値の設定です。文字列にすると、解析に失敗したり、想定外の動作になったりすることがあります。重複キーも確認してください。パーサーによって扱いが異なる可能性があるため、後の値で上書きされることを前提にせず、重複した定義を削除しましょう。変更後は、構造、参照関係、実行結果の順に確認します。この3段階は相互に代用できません。
以降の短い例は部分的な設定です。該当箇所の置き換えや理解に使うもので、単独では実行用ファイルとして使えません。クライアントが生成した設定がある場合は、コピー上で対象の項目だけを変更し、他の有効な設定は残してください。各項目のつながりを詳しく確認するには、設定ファイルのJSON構造を読み解くをご覧ください。
inbounds:リッスンアドレス、ポート、プロトコル
inboundsは配列で、各要素がリクエストを受け付ける入口を定義します。確認するポイントは、どのアドレスでリッスンするか、ポート番号、受け付けるプロトコル、入口の識別子です。アプリではinboundに合ったプロキシプロトコルとポートを指定してください。ブラウザーでHTTPプロキシを設定する場合は、HTTP inboundに接続します。SOCKS対応アプリではSOCKS inboundを利用できます。システムプロキシに数字だけを入力しても、そのポートがアプリの期待するプロトコルに自動で切り替わるわけではありません。
listenは接続を受け付ける範囲を決めます。単一端末で使う場合は、入口を端末内だけに限定できる127.0.0.1へのバインドを優先してください。すべてのネットワークインターフェースにバインドすると、アクセス可能な範囲が広がり、ファイアウォール、認証、LAN内のアクセス制御も必要になります。Webページが開けない場合の汎用的な対処として設定しないでください。ループバックアドレスにはIPv4とIPv6の違いもあります。アプリがIPv6のループバックアドレスに接続しようとしても、サービスがIPv4のループバックアドレスだけでリッスンしていると接続に失敗することがあります。トラブル対処では、設定上のリッスンアドレスを明示して接続してください。
SOCKS inboundのUDPとドメイン名の受け渡し
以下の例は、ローカルのSOCKS inboundとUDPを有効にします。authがnoauthの場合、この入口ではSOCKSのユーザー名とパスワードを要求しません。リモートノードの認証情報が不要という意味ではありません。ループバックアドレスだけでリッスンするため、個人用PCでアプリを使う場合に適しています。共有用の入口に変更する場合は、リッスンアドレスだけでなく、アクセス範囲も見直してください。
{
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
]
}
udpを有効にすると、inboundで対応するUDP転送リクエストを受け付けられます。ただし、すべてのアプリの通信がコアに入るわけではなく、すべてのoutboundでUDP転送ができるとも限りません。アプリが対応する転送方式を使い、outboundのプロトコルとリモートサービスも必要な機能をサポートしている必要があります。一般的なWebページを開けても、リアルタイム通信などのUDPアプリが使えるとは限りません。
ドメイン名をどこで名前解決するかは、アプリがプロキシ接続をどう開始するかによって異なります。アプリがローカルで名前解決してから、宛先IPをSOCKSに渡すこともあります。ドメイン名をプロキシ側に渡す場合もあります。前者では、ドメイン名を使うルーティングルールで参照できる情報が少なくなることがあります。後者では、コアが元のドメイン名に基づいてルールを適用できる可能性があります。アプリの「プロキシ経由で名前解決」などの設定は、実際の動作を確認してください。SOCKSという名称だけで解決場所を判断することはできません。
HTTP inboundと入口の識別子
HTTPプロキシの入口は、システムプロキシやブラウザーの手動プロキシ設定でよく使われます。HTTPSサイトにアクセスする場合、アプリは通常HTTPプロキシ経由でトンネルを確立します。だからといって、ローカルのHTTP inboundにWebサイトの証明書を設定する必要はありません。ローカルプロキシのプロトコル、接続先サイトのプロトコル、リモートプロキシのトランスポート層を混同しないでください。独立したHTTP inboundを使う場合、システムプロキシに設定するポートをinboundと一致させます。クライアントがmixed形式の入口を使う場合は、画面に表示される現在のポートを確認してください。
| 項目 | 役割 | 確認ポイント |
|---|---|---|
listen | ローカルのリッスンアドレス | アプリが使うアドレスの種類と一致させる |
port | ローカルのリッスンポート | 他のリスナーと競合していないこと |
protocol | inboundのプロトコル | アプリのプロキシ方式に合わせる |
tag | 入口の識別子 | routingからinboundTagで参照する |
inboundのtagはポートの種類を決めませんが、routingの条件として利用できます。たとえば、同じPCにある2つの入口に別々のtagを付け、inboundTagによって異なるoutboundへ振り分けられます。tagは一意で、短く、意味が分かる名前にしてください。変更時は参照先も確認します。inboundのtagとoutboundのtagが自動で対応するわけではありません。名前が同じでも接続は作られず、実際の選択はroutingとデフォルトoutboundのルールで決まります。
ポートの競合を調べる際は、クライアントが重複して起動していないか確認し、ログにバインド失敗が記録されていないか確認します。ポートを変更した場合は、アプリの設定とシステムプロキシも更新してください。JSONだけを変更すると、古い入口アドレスが残ります。クライアントがコアを再起動した後、リッスンが実際に開始されていることも確認しましょう。inboundが存在すること、アプリが接続できること、リモートにアクセスできることは、それぞれ異なる段階です。順に検証し、ローカルの入口設定の誤りを隠すためにサーバーを何度も切り替えるのは避けてください。
outbounds:プロトコル、tag、デフォルトの出口
outboundsは、コアがリクエストを受け取った後の接続方法を定義します。直接接続には通常freedom、通信のブロックにはblackholeを使います。リモートプロキシのoutboundでは、接続情報に応じたプロトコルを指定します。設定の構造はプロトコル名で決まり、他の項目から参照する際にはtagを使います。tagをproxyに変更しても、直接接続がプロキシ接続に変わるわけではありません。動作はprotocolとプロトコル、トランスポートの設定で決まります。
クライアントが生成した設定を読むときは、まず各outboundのtagを書き出し、用途を確認します。よくある名前はproxy、direct、blockですが、クライアントによって別の名前が使われることもあります。routingにoutboundTag: "proxy"とあれば、同じ名前のoutboundが必要です。実際の名前が異なる場合は、実行設定を基準にしてください。大文字・小文字、ハイフン、前後の空白も正確に確認しましょう。
directとblockの最小構成
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
この例では、最初のoutboundが直接接続です。どのroutingルールにも一致しないリクエストは、デフォルトで最初のoutboundに渡されます。そのため、配列の順番を変えると、多くのリクエストの接続先が変わる場合があります。単なる整形として並べ替えないでください。デフォルトでプロキシを使う場合は、最初のoutboundが有効なプロキシ接続であることを確認するか、コアがサポートするroutingの書き方でフォールバックを明示します。名前をそろえるためだけに、内容が空のプロキシoutboundを追加しないでください。
block outboundは、ルールに一致した通信を意図的に拒否または破棄するために使います。これはリモートへの接続失敗とは異なります。前者は想定どおりのrouting結果である場合があり、後者ではネットワークやリモート側の設定を確認します。特定のドメインに常にアクセスできない場合は、DNSを変更する前にblockルールに一致していないか確認してください。ルールが増えるほど、それぞれの用途を記録しておくことが重要です。用途の説明は管理用ドキュメントやクライアントのメモに残し、標準JSONに無理に書き込む必要はありません。
プロトコルとトランスポートを分けて確認
リモートプロキシのoutboundは、いくつかの層に分けて考えられます。サーバーアドレスとポートは接続先を示し、プロトコル設定は認証情報とプロトコルの動作を定めます。streamSettingsは下位のトランスポートとセキュリティ層を設定します。VMess、VLESS、Trojanの項目は互いに流用できません。REALITYは特定のコアがサポートするセキュリティ方式であり、outboundのプロトコル名をREALITYに変更するものではありません。サブスクリプションの読み込み結果を確認するときは、実際のプロトコルを確認してから、各層のパラメーターを点検してください。
ポートと接続先アドレスが同じでも、2つの設定が同等とは限りません。サーバーが要求するトランスポート形式、TLSのサービス名、パス、その他のネゴシエーション用パラメーターが1つでも一致しないと、接続やハンドシェイクに失敗することがあります。別のノード情報から、似ているという理由だけで値を流用しないでください。本ページでは、利用可能なリモート認証情報を提供していません。実際の接続情報は、利用権限のあるサービスから取得してください。ログを共有する際は、認証情報とサブスクリプションURLを隠してください。
サーバーアドレスにドメイン名を使う場合、名前解決も必要です。コアがリモートに接続する前に、アドレスに対応するIPを取得しなければなりません。名前解決が、まだ確立していない同じ接続に依存する設定では、起動時に依存関係のループが生じることがあります。症状は明確なJSONエラーではなく、継続的なタイムアウトとして現れる場合があります。トラブル対処では「リモートアドレスの名前解決失敗」と「接続先サイトの名前解決失敗」を分けて考えてください。リクエストの異なる段階で起きる問題なので、DNS設定を1か所見るだけでは判断できません。
クライアントは、選択中のサーバーに応じてプロキシoutboundを再生成することがあります。その場合、一時的な実行ファイルを手作業で編集して反映されても、サーバーの切り替えや再起動で上書きされる可能性があります。変更を継続して適用するには、クライアントが対応するカスタム設定機能を利用してください。デスクトップとモバイルでの管理方法の違いは、クライアント選びのガイドをご覧ください。異なるクライアントが出力した項目を、すべてそのまま1つのファイルにまとめないでください。
outboundを検証する際は、直接接続されるはずのリクエストと、プロキシ接続されるはずのリクエストをそれぞれ選び、結果を確認します。ページを1つ開いただけではroutingが想定どおりとは限りません。ブラウザーのキャッシュや既存の接続、アプリ独自のプロキシ設定が結果に影響することがあります。変更後は既存の接続を閉じてからテストし、ログに記録された宛先、outboundの識別子、エラーが起きた段階を確認してください。
routing:条件、ルールの順序、フォールバック
routingは、リクエストをどのoutboundに渡すかを決めます。通常、ルールは上から順に確認され、最初に一致したルールの出口が使われます。より正確な条件を探して後続のルールを調べることはありません。そのため、ルールの順番そのものが設定の意味を持ちます。広い範囲に一致するルールを前に置くと、後続の限定的なルールが機能しなくなることがあります。例外ルールを最後に置くと、一度も一致しない場合があります。編集前に、例外、通常の分類、最終的なフォールバックの順で意図を整理してください。
1つのルール内では、異なる条件項目は通常すべて満たす必要があります。同じ条件配列に複数の値を指定した場合は、通常、そのいずれかに一致します。たとえばinboundTagとdomainを同時に指定すると、指定した入口から来たリクエストのうち、宛先ドメインが条件に合うものが対象になります。「入口またはドメインのどちらかに一致すればよい」という意味ではありません。異なる経路を表現する場合は、ルールを分けましょう。関係のない条件を1つのオブジェクトに詰め込まないでください。
まずドメインのルールを定め、次にアドレスのルールを追加
以下の例では、ルールの順序を確認できます。一致した場合の接続先はすべてdirectで、条件の構造を示すためのものです。設定内に同名のoutboundが必要です。例では予約済みのサンプル用ドメインでfull:とdomain:を説明し、地理データファイルに依存しないよう明示的なプライベートアドレス範囲を使っています。地域別に通信を振り分ける完全な設定ではありません。
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:example.com"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["domain:example.org"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
],
"outboundTag": "direct"
}
]
}
}
full:はドメイン名全体への一致に使い、domain:は指定したドメインとそのサブドメインへの一致に使います。後者は同じドメイン配下のサービスをまとめて管理するのに便利ですが、1つのWebサイトでもページ、画像、認証APIが異なるドメインを使うことがあります。メインのドメインだけで依存先をすべて網羅できるとは限りません。プレフィックスのない文字列や正規表現には、それぞれ異なる一致方法があります。一般的なルールでは意図が明確なプレフィックスを優先すると、誤一致や後の説明にかかる手間を減らせます。
geosite:とgeoip:はデータセットへの参照であり、オンライン検索サービスではありません。利用できるか、どの分類が含まれるかは、実行環境のデータファイルや分類内容によって異なります。ルールに分類名が書かれていても、現在のコアが読み込めるとは限りません。外部のルールを取り込む場合は、分類の有無、データの読み込み可否、参照先tagの定義を確認してください。JSONの括弧が正しく閉じているかだけでは不十分です。
domainStrategyはDNSサーバーの設定ではない
AsIsは、通常、既存の宛先情報を使ってルーティングし、IP条件のためにドメインを積極的に名前解決しない設定です。IPIfNonMatchは、ドメインルールに一致しなかった場合に名前解決を試み、IPルールの判定を続けます。IPOnDemandは、ルーティングにIP情報が必要になった時点で名前解決します。どの方式を選ぶかはルールの構成で判断してください。早く名前解決するほど正確とは限りません。追加の名前解決は依存関係を増やし、リクエストの処理タイミングを変えることがあります。
routingのdomainStrategyとDNSのqueryStrategyは、別々の問題を扱います。前者はルーティング用にいつアドレスを取得するかを決め、後者はDNSクエリで優先するアドレスの種類を決めます。直接接続のoutboundにも、独立したドメイン解決方針が設定されている場合があります。トラブル対処では「DNSを有効にした」とひとまとめにせず、どの段階で名前解決が行われるかを整理してください。アプリ側でドメイン名がIPアドレスに変換済みの場合、コアがドメイン名を取得できるかどうかは、アプリが渡す情報やスニッフィングなどの追加機能にも左右されます。
フォールバックは個別に確認してください。どのルールにも一致しない場合、デフォルトで最初のoutboundが選択されます。「最後のoutboundがデフォルト」と誤解すると、逆の結果になります。一部のクライアント画面では、最終的な接続先をfinal → proxyと表すことがあります。これは設定を読みやすくするための説明であり、コアのJSONに共通のトップレベル項目finalがあるという意味ではありません。実際に生成されたルールか、最初のoutboundを確認して、画面の選択がどう反映されるかを確かめてください。
ルールを追加したら、一致するはずの宛先と一致しないはずの宛先を選んで比較します。新しいルールが効かない場合は、上位のルールに先に一致していないか、コアが宛先をドメイン名とIPアドレスのどちらとして認識しているか、tagの参照とデータの読み込みに問題がないかを順に確認してください。システムプロキシの「グローバル」は、アプリが通信を渡す方法に影響しますが、コアのroutingでは引き続き振り分けられる場合があります。両方を個別に確認しましょう。操作手順は使い方ガイドのモード選択をご覧ください。
dns:名前解決サーバー、アドレスの種類、クエリ経路
dnsはコアが利用する名前解決機能を定義しますが、この項目があるだけでPC全体のDNSが自動的に切り替わるわけではありません。アプリ、OS、ブラウザー、コアがそれぞれ名前解決を行う場合があります。まず、どの層がクエリを送っているかを確認してから、変更すべき設定を判断してください。ブラウザーが独自に暗号化DNSを有効にしている場合、システムDNSを変更しても影響しないことがあります。アプリが先にドメイン名をIPアドレスに変換している場合、コアが想定どおりにドメインルールを適用できないこともあります。
設定が想定どおりか判断するには、3つの点を確認します。クエリの送信先、クエリが到達するまでの経路、取得したアドレスの用途です。DNSサーバーのアドレスを変更しても、変わるのは最初の点だけで、残りも同時に変わるとは限りません。リモートプロキシサーバーの名前解決、routingがIP条件を判定するための名前解決、直接接続先の名前解決は、それぞれ別の場所で行われる場合があります。複数のDNSサーバーを一度に追加するより、こうした依存関係を書き出すほうが、安定したトラブル対処につながります。
明示的なDNSサーバーと静的hosts
以下はDNS設定の部分例です。静的なhostsを使ってサンプル用ドメインをループバックアドレスに固定しています。これはローカルテスト専用なので、通常の利用ではこのテスト用マッピングを削除してください。サーバー一覧ではIPアドレスを明示し、DNSサーバー自身のドメイン名解決が先に必要になる状態を避けています。サーバーに到達できるか、クエリがどのoutboundを通るかは、コアの動作とrouting設定を併せて確認してください。
{
"dns": {
"hosts": {
"example.com": "127.0.0.1"
},
"servers": [
"1.1.1.1",
"8.8.8.8"
],
"queryStrategy": "UseIP"
}
}
hostsは、既知のアドレスを一時的に固定したり、管理された環境で名前解決と接続の違いを検証したりするのに使えます。アドレスが変わるサービスの恒久的な代替には向きません。ループバックアドレスに割り当てると、そのドメインへのアクセスはローカル端末に向かいます。端末上に対応するサービスがなければ、接続に失敗するのは想定どおりです。トラブル対処が済んだらテスト用の設定を削除してください。残ったマッピングが、次回の問題の原因になることがあります。
queryStrategyの一般的な値にはUseIP、UseIPv4、UseIPv6があります。実際に利用できる値は、使用中のコアの仕様を確認してください。デュアルスタック環境でIPv6アドレスを取得できても、IPv6で接続できるとは限りません。一時的にIPv4だけに制限すると、アドレスの種類が原因かどうかを確認できます。ただし、特定のアドレスの種類を無効にすることを、すべてのネットワークでの恒久的な解決策にしないでください。リモートアドレス、接続先アドレス、OSのネットワーク機能が一致しているかも確認しましょう。
ドメイン別DNSとフォールバックの範囲
より複雑なサーバー設定では、ドメインの一致範囲や想定するアドレスなどの条件を指定し、ドメインごとに異なるDNSサーバーへ問い合わせることができます。こうした設定を導入する前に、使用中のコアが対応する項目とフォールバックのルールを確認してください。サーバーを複数指定しても、配列の順に成功するまで試すとは限りません。一致条件、フォールバック設定、名前解決結果の判定が選択に影響します。明確な要件がなければ、まず説明しやすい基本経路を維持し、必要に応じてドメイン別の設定を段階的に追加してください。
暗号化DNSを使う場合は、通信の暗号化と出口の選択を分けて考えます。暗号化は該当する経路でのクエリの送信方式を示すだけで、どのプロキシoutboundを通るかまでは決まりません。接続先アドレスの形式によって経路が異なることがあり、通常のUDPクエリに対するroutingの動作を、すべての暗号化DNS方式に当てはめることはできません。設定前に、利用する方式のルーティングと名前解決の要件を確認し、ログと実際のリクエストで検証してください。
名前解決の依存関係がループする例として、DNSサーバーへのアクセスにプロキシが必要なのに、そのプロキシサーバーのドメイン名解決が同じDNSサーバーに依存するケースがあります。構造チェックを通過しても、最初の接続を確立できないことがあります。タイムアウト時間を延ばし続けるのではなく、起動時の名前解決に使える経路を用意してください。プロキシサーバーのドメイン名、DNSサーバーのアドレス、使用するoutboundを記録して図にすると、どこで依存を解消すべきか判断しやすくなります。
DNSをテストするときは、開いているページや既存の接続を閉じ、アプリが想定したプロキシ設定を使っていることを確認してから、対象ドメインの名前解決とアクセス結果を比較します。OSやブラウザーのキャッシュによって変更が反映されていないように見えることがあり、接続の再利用で新しい名前解決処理が行われない場合もあります。どのキャッシュを消すべきかは、実際にクエリを送信する層によって異なります。具体的な検査手順はDNSクエリ経路の確認と設定の見直しをご覧ください。1つの検査ページの結果を、すべてのアプリの動作と同一視しないでください。
policy:ユーザーレベル、接続時間、統計
policyは一部の接続動作と統計機能を管理します。リモートサーバーの選択や地域別の振り分けは担当しません。通常、levelsとsystemに分かれます。前者はユーザーレベルごとのポリシーを定義し、後者はシステム全体に関わる一部の統計を制御します。確認する際は、まず対象の接続がどのレベルを使うかを調べ、そのレベルにどの項目が設定されているかを確認してください。すべてのユーザーがレベル0だと決めつけると、プロトコルのユーザー設定に別のレベルが指定されていることを見落とす可能性があります。
JSONではレベル名をオブジェクトのキーとして記述するため、例では文字列の"0"を使っています。プロトコル設定から参照するlevelは、通常、数値です。レベルはサーバーの優先順位でも、ノードの品質評価でもありません。レベルの数値を上げても接続性能は向上せず、別のポリシーが選ばれるだけです。明確なレベル分けが不要なら、設定はシンプルに保ちましょう。どのユーザーからも参照されないレベルを追加すると、変更したのに反映されないという誤解につながります。
接続時間の設定例
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5,
"statsUserUplink": false,
"statsUserDownlink": false
}
},
"system": {
"statsInboundUplink": false,
"statsInboundDownlink": false
}
}
}
以下の値は項目の構造を示すもので、すべてのネットワークに推奨できる調整値ではありません。handshakeはハンドシェイクに許容する時間で、単位は秒です。connIdleは接続のアイドル時間に関する項目です。uplinkOnlyとdownlinkOnlyは、片方向の通信が終了した後に、もう一方を維持する時間を設定します。接続のライフサイクルに関わる項目であり、経路の混雑、リモートサービスの処理能力、ローカルの無線ネットワークの品質は変わりません。
ハンドシェイクのタイムアウトが短すぎると、ネットワークの揺らぎで、本来なら確立できる接続が途中で終了することがあります。長すぎると、到達できない宛先への応答をアプリが長時間待つことになります。変更が必要かどうかは、エラーがどの段階で発生したかを確認して判断してください。ログにサーバー名やセキュリティ設定の不一致が記録されている場合、時間を延ばしても設定ミスは直りません。ローカルポートのバインド失敗をpolicyで解決することもできません。まず失敗箇所を特定し、そのうえで時間を調整するか決めましょう。
統計設定とクライアント画面の表示を分けて考える
ユーザー統計とinbound統計は、対象範囲が異なります。統計を有効にしても、対応する情報がクライアント画面に自動で表示されるとは限りません。コアの統計モジュール、取得用インターフェース、クライアント側の読み取りも必要になることがあります。一部の統計では、識別可能なユーザー情報も必要です。設定だけをコピーして収集と読み取りの流れを確認しないと、値が常に空のままになることがあります。画面に表示されないからといって、通信がコアを通っていないと判断することもできません。
クライアント独自のアプリ状態、接続履歴、その他の実行情報は、policyだけでは管理されていない場合があります。出力された設定を読む際は、「コアが統計を収集するか」と「画面に表示されるか」を分けて確認してください。トラブル対処のための一時的な統計なら、目的を明確にすれば十分です。見た目を整えるためだけにすべての項目を有効にする必要はありません。実行ログを長期間保存する場合は、ディスク容量とアクセス先が記録に含まれる可能性にも注意してください。
| 項目グループ | 確認すること | 代わりにはならないもの |
|---|---|---|
handshake | ハンドシェイクの待機時間 | リモート側のパラメーター確認 |
connIdle | アイドル接続の解放 | ルーティングとDNSの設定 |
uplinkOnly | 片方向終了後の接続維持 | アプリの長時間接続の設計 |
statsUserUplink | ユーザーごとの送信量統計 | 統計インターフェースと取得設定 |
バッファー関連のポリシーも、一般的な性能改善策とされる設定をそのまま流用しないでください。接続数、アプリのデータ形式、端末のメモリが、必要なリソースに影響します。バッファーを大きくするだけでは、メモリ消費が増えても応答が改善しないことがあります。コアによって、対応項目やデフォルト値が変わる場合もあります。見慣れないpolicy項目があれば、現在のコアのドキュメントを確認してください。古い記事に記載があるからといって、現在のクライアントでも使えるとは限りません。
policyの変更をテストする場合は、同じアプリ、同じoutbound、できるだけ近いネットワーク条件で行い、関連する値を1つのまとまりとして変更します。変更前の設定も保存してください。テストでは、新規接続、短時間のアイドル後の再開、長時間アイドル後の再接続を確認します。アプリにハートビート機能があると、想定したアイドル状態にならないことがあります。長時間のダウンロードだけでは、アイドル接続の解放動作を検証できません。設定項目が実際に管理する状況を試してください。
デフォルト設定で要件を満たせる場合は、policy全体を明示的に記述する必要はありません。項目を省略すると、使用中のコアのデフォルト動作が適用されます。機能が無効になるわけではありません。すべてのデフォルト値を書き出すと、管理の手間が増え、古いコアの設定を新しい環境に固定してしまうこともあります。設定を引き継ぐときは、数値だけでなく、デフォルト値を上書きした理由も記録しておくと、後で必要性を判断しやすくなります。
クライアント生成設定とカスタム設定の境界
v2rayNは当サイトおすすめのデスクトップクライアントで、Windows、macOS、Linuxに対応しています。Androidでは、主にXrayをコアとして使うv2rayNG、またはV2Flyをコアとするv2flyNGを利用できます。クライアントには、サブスクリプション、サーバー、ルーティング、各種パラメーターを管理する画面があります。実際の動作は、選択したコアと生成された設定にも左右されます。インストーラーはクライアントダウンロードページから入手してください。本ガイドでは設定項目の関係を解説し、単独のコアパッケージやリモートサーバー情報は掲載していません。
クライアント設定で重要なのは、「どこが情報を管理しているか」です。サブスクリプションが接続情報を更新し、サーバーの選択が現在のプロキシoutboundを決めます。ルーティングテンプレートは通信の振り分けルールを定め、パラメーター設定はinboundのポートなどの実行オプションに影響します。生成ファイルは、これらの入力を組み合わせた結果です。生成ファイルを直接編集すると、サーバーの切り替え、サブスクリプションの更新、コアの再起動、アプリ設定の変更後に上書きされることがあります。JSONが保存されなかったのではなく、次の生成時に管理元の値が再適用されたためです。
サブスクリプション管理はコアのトップレベル項目ではない
subscriptionはクライアント側の管理機能であり、本ページで扱うV2RayコアのJSONに共通するトップレベル項目ではありません。サブスクリプションURL、自動更新間隔、グループ名はクライアントの管理画面で設定してください。実行ファイルに同名のオブジェクトを追加しても設定できません。サブスクリプションの内容は、エンコードされたテキストやプロトコルリンクの一覧として提供されることがあります。まずクライアントで読み込み、コアに必要なプロトコルとトランスポート設定に変換します。
サブスクリプションの更新に失敗した場合は、まず現在使える接続情報を残したうえで、リンクの有効期限、アクセス経路、応答形式、クライアントのメッセージを確認します。更新できないからといって、すべてのサーバーを削除しないでください。サブスクリプションURLを公開ログに貼り付けるのも避けましょう。自動更新は接続情報の同期を行う機能で、ローカルポートの競合やシステムプロキシの設定を自動修復するものではありません。具体的な対処法はサブスクリプション更新失敗と自動更新の設定をご覧ください。
システムプロキシ、routing、通信制御モードを分けて確認
システムプロキシは、設定に従うアプリのリクエストをどのローカル入口に渡すかを決めます。コアのroutingは、入口に届いたリクエストの接続先を決めます。「システムプロキシを自動設定」を選んでも、すべてのアプリが通信を渡すとは限りません。「システムプロキシを解除」しても、コアのリッスンが停止するとは限りません。アプリ独自のプロキシ設定が残り、ローカルポートを使い続けることもあります。トラブル対処では、OSとアプリそれぞれのネットワーク設定を確認してください。
v2rayNでよく使う関連メニューには、「サブスクリプショングループ」「ルーティング設定」「パラメーター設定」「システムプロキシ」があります。画面の種類によって、実際の名称や場所が異なる場合があります。Androidクライアントは通常、OSの許可を得て通信を制御するため、デスクトップのシステムプロキシと同じ操作手順は使えません。別のプラットフォームに移行する際は、必要な機能と接続情報を引き継ぎ、新しい環境で権限、リッスン方法、ルーティングモードを確認してください。デスクトップが生成したファイルだけをコピーしないでください。
クライアントによっては、仮想ネットワークアダプターを使った通信制御モードも利用できます。通常のシステムプロキシとは、対象となる通信の範囲、必要な権限、DNSの経路が異なります。有効にした後は、LANへのアクセス、名前解決、他のネットワークアプリとの併用を改めて確認してください。HTTPプロキシだけで確認した結果を、そのまま当てはめないでください。権限の引き上げが必要な場合は、そのモードが本当に必要か確認しましょう。ブラウザーで手動プロキシを使えるなら、ポートの設定ミスを直すためだけに、すぐ通信制御方式を変更する必要はありません。
後から管理できる変更元を残す
長期的なカスタマイズを始める前に、クライアントが提供する機能が、ルーティングルールの編集、部分設定の追加、完全なカスタム設定のどれなのかを確認します。それぞれ適用範囲が異なります。部分設定は自動生成設定に統合される場合があり、完全なカスタム設定は一部の自動生成処理を経由しないことがあります。実際の動作はクライアントの説明と生成結果を確認してください。変更前の設定を保存し、変更した画面や機能、対象項目、期待する結果を記録すると、設定が上書きされた際に管理元を特定しやすくなります。
外部の完全な設定ファイルを読み込む前に、追加のリッスン設定、制御用インターフェース、リモートアドレス、不明なルールが含まれていないか確認してください。起動できても、PCの要件に合っているとは限りません。特に、リッスン範囲がループバックアドレスから全ネットワークインターフェースに変更されていないこと、既存のシステムプロキシのポートが正しい入口に対応すること、デフォルトoutboundの方向が想定どおりであることを確認しましょう。用途が分からない項目は、起動させるためだけにセキュリティ設定やrouting全体を削除せず、先に役割を調べてください。
設定ファイルやログを共有する際にも注意が必要です。プロトコルの認証情報、完全なサブスクリプションURL、アクセス先、本機のパスには個人情報が含まれることがあります。公開の場で相談する場合は、問題の再現に必要な項目とエラーが発生した段階だけを残し、機密情報を置き換え、コアの種類を記載してください。異なるコアのエラーは、文面が似ているだけで同じ原因とは限りません。まず実行環境を明確にすると、構文、対応範囲、ネットワーク経路のどれが問題か判断しやすくなります。
設定の検証、ログの確認、元に戻す手順
リクエストの流れに沿って検証しましょう。設定を読み込めるか、inboundがリッスンするか、アプリのリクエストが入口に届くか、routingが正しいoutboundを選ぶか、リモート接続が確立するか、接続先の名前解決とアクセスが完了するかを順に確認します。各段階で失敗する可能性があり、外からは単に「Webページが開かない」としか見えないこともあります。サーバー、DNS、routing、ローカルポートを一度に変更しないでください。複数の条件を同時に変えると、一時的に直っても原因が分からず、次回のトラブル対処にも活かせません。
作業を始める前に、正常に動作しているクライアント設定または設定ファイルのコピーを保存し、現在のモードを記録します。次に1項目だけ変更し、設定を適用して対象のコアを再起動し、明確な宛先でテストしてください。ファイルを保存しただけでコアを再読み込みしていない場合、確認できるのは古い設定の動作かもしれません。クライアント再起動後に変更が消える場合は、同じ一時ファイルを何度も編集せず、前の章を参照して設定の生成元を確認してください。
設定の読み込み失敗と接続失敗を分ける
読み込み段階で起きる問題には、JSON構文の誤り、項目の型の誤り、コアが対応していないプロトコルや設定、ルーティング用データの不足などがあります。まずログに最初に現れた重要なエラーを確認し、最後の「起動失敗」だけを見て判断しないでください。エラー行の近くでは、カンマ、引用符、配列の区切りを確認します。ただし、エラーの位置が実際の原因より後を指すこともあります。1つ前のオブジェクトの終わりも見直してください。
コアが起動しているのにポートへ接続できない場合は、アドレスの種類の不一致、ポートの競合、アプリが古いポートを使っていないかを確認します。システムプロキシの設定が残っていることもよくあります。クライアントを終了しても、OSの設定が存在しないローカルリッスンを参照していると、システムプロキシに従うアプリに影響します。まずシステムプロキシを正しい状態に戻し、クライアントが動作していることを確認してください。リモートのプロトコル設定を先に変更する必要はありません。
ログの詳細度を一時的に上げて確認
以下の例では、接続とルーティングを一時的に確認できるよう、ログレベルをinfoに設定しています。クライアントによって、ログを独自の画面に表示する場合と、指定したファイルに保存する場合があります。ファイルの保存先を明示していない場合は、起動方法によって表示場所が異なります。情報が足りなければ、管理されたトラブル対処の間だけ、さらに詳細なログを有効にできます。作業後は出力量を元に戻し、リクエスト情報を長期間記録し続けないようにしてください。
{
"log": {
"loglevel": "info"
}
}
ログは同じテストの記録を中心に、宛先、inbound、outbound、エラーが起きた段階を確認します。タイムアウトは名前解決、接続確立、ハンドシェイクのいずれでも起こり、それぞれ意味が異なります。接続拒否は、そのアドレスとポートで想定したサービスが動作していないか、接続が明示的に拒否されたことを示す場合があります。セキュリティ層のハンドシェイクに失敗した場合は、サービス名、時刻、プロトコル設定を確認してください。すべてのエラーをノードの障害と決めつけたり、正常な切断ログを原因と見なしたりしないでください。
| 症状 | まず確認すること | 次に行うこと |
|---|---|---|
| コアが起動しない | 構文、項目、データの読み込み | 直近に変更した設定を元に戻す |
| ローカルの入口に接続できない | リッスンアドレス、ポート、プロセスの状態 | アプリが実際に使うプロキシ設定を確認 |
| 一部のサイトだけ開けない | ルールの順序と名前解決結果 | 一致したoutboundとアドレスの種類を確認 |
| サーバー切り替え後に動かない | 生成設定とカスタム設定による上書き | 新しいoutboundの識別子を確認 |
| スリープ復帰後に接続が切れる | ネットワークの変化と古い接続 | 接続を作り直してからテスト |
システム時刻は、一部のプロトコルやセキュリティハンドシェイクにも影響します。ログに認証や証明書の時刻に関するエラーがある場合は、リモート設定を調べる前に、端末の日付、時刻、タイムゾーンが正しいか確認してください。ネットワーク切り替え後に問題が起きた場合は、デフォルトのネットワーク、DNSサーバーへの到達性、既存の接続状態を改めて確認します。有線から無線に切り替えても、以前の接続がそのまま使えるとは限りません。接続を作り直すと、ネットワーク環境の変化と設定ファイルの問題を切り分けやすくなります。
元に戻す際は、エラーの項目だけを削除するのではなく、関連する変更単位全体を復元します。たとえばoutboundのtagを変更した場合は、routingからの参照も併せて戻します。ポートを変更した場合は、システムプロキシとアプリの設定も元に戻してください。復元後にコアを再読み込みし、起動エラーが残っていないことをログで確認してから、最初のテストを繰り返します。保存した設定でも動かない場合は、JSON内に存在しない差分を探し続けず、外部ネットワークやリモートサービスの変化も考慮してください。
問題を再現できる記録には、テストに使ったアプリ、通信制御の方式、コアの種類、対象のルーティング分類、エラーが発生した段階、最後に変更した内容を含めてください。サブスクリプションや全サーバー情報を公開する必要はありません。画面操作に沿ったトラブル対処の手順は接続済みなのにWebページが開けない場合のチェックリストをご覧ください。基本的な手順をやり直す場合は、クイックスタートガイドに戻り、情報の追加、モードの選択、接続の確認を順に進めてください。
設定を保守しやすくするには、各項目の管理元を明確にし、各ルールの用途を説明できるようにし、変更を元に戻す手順を用意しておきます。必要のない項目まで追加して設定を埋める必要はありません。設定が長くても機能が充実しているとは限りません。必要なinbound、outbound、ルールだけを残し、デフォルト動作とコアの対応範囲を把握するほうが、出所の分からない設定を重ねるより確認やトラブル対処が容易です。