V2RayとXrayの実行設定は、接続処理の流れを示す図として捉えられます。まずローカルポートでリクエストを受け付け、ルーティング規則で行き先を判断し、最後にプロキシ、直接接続、またはブロックの出力へ渡します。v2rayN、v2rayNG、v2flyNGは、画面で設定したノード、分流、ローカルポートをこの流れに変換します。JSONを読むときに重要なのはフィールドを暗記することではなく、各段階でリクエストがどこへ渡されるかを確認することです。
サブスクリプションを読み込めるものの、実行設定やコアのログが理解しづらい方に適した内容です。読み終えると、待受入口、プロキシ出口、直接接続出口、ルーティング規則を見分け、ポート競合、タグ不一致、DNS名前解決、分流の不具合といったよくある問題を切り分けられます。
まず設定ファイル全体を把握する
完全な設定にはlog、dns、policy、stats、api、transportなどのブロックが含まれる場合もありますが、基本的なデータ経路はinbounds、routing、outboundsで構成されます。inboundsは「どこから受け付けるか」、routingは「どのタグへ渡すか」、outboundsは「どのようにローカル環境から出るか」を決めます。この3ブロックをつなぐ鍵がtagです。
以下は起動可能なローカルSOCKS転送設定です。127.0.0.1:10808で待ち受け、通信をfreedomの直接接続出口へ渡します。この例にはリモートプロキシのパラメータがなく、最小構成を示すことだけを目的としています。起動後も、SOCKS入口から送られたリクエストはローカルネットワークから直接宛先へアクセスします。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "socks-in",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
}
]
}
}
この記事では、v2rayN 7.10.5のメニューと生成ロジックを基準に各フィールドを確認しています。マイナーバージョンによって画面の文言や追加の統計ブロックが変わる場合はありますが、主要な設定の配列構造、タグ参照、ルールの評価順は変わりません。Android版が生成する実行設定も同じデータ経路に従いますが、ローカル入口はVPNモードやアプリ内の転送層が提供することがあります。
inboundsでローカル入口と受け付け方を管理する
inboundsは入站配列で、各オブジェクトがローカルで受け付ける入口を定義します。デスクトップクライアントでよく使われるのはSOCKSとHTTPの2種類です。ブラウザ拡張機能、コマンドラインツール、プロキシ設定に対応したアプリがこれらのポートへ接続し、コアが後続のリクエストを引き継ぎます。listenは接続を許可するネットワークインターフェース、portはポート番号、protocolは入口のプロトコル、tagはルーティング規則が識別する名前を指定します。
ローカルでのみ使う場合は、listenを127.0.0.1に設定すると接続範囲を明確に制限できます。LANからの接続を有効にすると、クライアントが0.0.0.0で待ち受けることがあります。これは利用可能なすべてのネットワークインターフェースでリクエストを受け付けるという意味です。その場合は、OSのファイアウォールと現在のネットワーク種別も確認してください。コアが正常に起動したかだけでは不十分です。
| フィールド | 代表値 | 実際の役割 | よくある問題 |
|---|---|---|---|
listen |
127.0.0.1 |
ローカル接続に限定 | 他のデバイスからアクセスできないのは想定どおりです |
port |
10808 |
SOCKSリクエストを受け付ける | 他のプログラムと重複するとコアの起動に失敗します |
protocol |
socks |
入口のプロトコルを指定 | アプリ側をHTTPプロキシにすると接続に失敗します |
tag |
socks-in |
入口に安定した名前を付ける | ルーティングが存在しないタグを参照します |
sniffing |
enabled: true |
HTTPまたはTLS通信から宛先ドメインを識別 | 無効にすると一部のドメイン規則に一致しません |
sniffingはTLSの内容を復号する機能ではありません。接続開始時に見える情報から宛先ドメインを復元するだけです。アプリが特定のIPへ直接接続すると、ルーティング規則からは本来IPしか見えません。嗅探を有効にすると、コアが実際のドメインを識別し、domain規則で分流できる場合があります。有効化するかどうかは用途に合わせて判断し、すべての入口に同じdestOverrideを設定する必要はありません。
outboundsでプロキシ・直接接続・ブロックの出口を定義する
outboundsも配列ですが、各オブジェクトはコアから外へ出る方法を表します。リモートノードは通常vmessまたはvlessの出力として生成され、freedomはローカルネットワークからの直接接続、blackholeは一致した接続の終了を意味します。1つの設定に複数のプロキシ出力を持たせることもでき、routingがoutboundTagでいずれかを選択します。
プロキシ出力のsettingsにはサーバーアドレス、ポート、ユーザー識別子、プロトコルパラメータを保存し、streamSettingsにはTCPやWebSocketなどの転送方式とTLSやRealityなどのセキュリティ層を保存します。プロトコルパラメータと転送パラメータは別の階層です。切り分けの際に、WebSocketのパスをusersへ記述したり、ユーザー識別子をstreamSettingsへ記述したりしないでください。
VLESS出力
- protocol
- vless
- サーバーポート
- 443
- encryption
- none
- 転送層
- TCP
- 出力タグ
- proxy-vless
ユーザー識別子はvnextのusers配列に置き、セキュリティ層はstreamSettingsで記述します。
VMess出力
- protocol
- vmess
- サーバーポート
- 443
- security
- auto
- 転送層
- WebSocket
- 出力タグ
- proxy-vmess
WebSocketのパスとリクエストヘッダーはwsSettingsに属し、サーバー側の設定と一致している必要があります。
直接接続出力
- protocol
- freedom
- サーバーアドレス
- 不要
- ユーザー識別子
- 不要
- 出力タグ
- direct
LANアドレス、中国本土のドメイン、または指定したアプリの通信を、ルーティング規則からこの出力へ渡せます。
ブロック出力
- protocol
- blackhole
- ネットワークリクエスト
- 終了
- リモート接続
- 確立しない
- 出力タグ
- block
明示的にブロックしたいドメイン、IP、プロトコルの規則を受け持たせるのに適しています。
VLESSを例にすると、vnextはサーバー一覧、addressとportはリモートサービスの宛先、users内のidは認証情報を示します。TLSを使う設定では、serverNameは通常、証明書名の照合に使用されます。転送方式がWebSocketならnetworkはwsとし、pathはwsSettingsに保存します。いずれかの階層がサーバー側と一致しないと、ハンドシェイク失敗、接続切断、長時間のタイムアウトにつながる可能性があります。
{
"tag": "proxy-vless",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "server.example.com",
"port": 443,
"users": [
{
"id": "00000000-0000-4000-8000-000000000001",
"encryption": "none"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "server.example.com"
}
}
}
routingでリクエストを順番どおり指定した出口へ渡す
routing自体はネットワーク接続を確立せず、リクエストの特徴を確認して出力タグを返すだけです。規則ではdomain、ip、port、network、protocol、inboundTag、source、ユーザーなどの条件を指定できます。多くの規則はtypeをfieldとするフィールド一致形式で、条件に一致するとoutboundTagを読み取り、同名の出力へリクエストを渡します。
rulesは順序を持つ配列です。コアは通常、先頭から順に確認し、先に一致した規則が結果を決めます。そのため、範囲の狭い具体的な規則を前に、対象範囲の広い規則を後ろに置きます。例えば、まず特定ドメインをブロックし、次にプライベートアドレスを直接接続へ回し、最後に残りをプロキシへ渡す構成のほうが、最初に全通信をプロキシへ送る規則を書くより結果を予測しやすくなります。
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": ["domain:ads.example.com"],
"outboundTag": "block"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy-vless"
}
]
}
}
domainStrategyは、ドメイン規則とIPの名前解決をどのように組み合わせるかを決めます。AsIsは元のドメインを優先し、IP規則のために積極的な名前解決を行いません。IPIfNonMatchはドメイン規則に一致しなかった場合にIPを解決し、IP規則を試します。IPOnDemandはより早い段階で名前解決を開始します。規則が単純ならまずAsIsを使い、geoipによる分流でドメイン解決を補助的に利用したい場合にIPIfNonMatchを検討するとよいでしょう。
domainのfull、domain、keyword、regexpはそれぞれ一致範囲が異なります。fullは完全一致、domainは対象ドメインとサブドメイン、keywordは文字列の一部、regexpは正規表現で検索します。範囲が広いほど誤一致の可能性が高まります。日常的な分流ではfullまたはdomainを優先し、構造化されたドメイン指定では表現できない場合だけ正規表現を使います。
結論:まずタグを確認し、次に規則の範囲を調整する
分流が機能しないときは、まずrulesのoutboundTagとoutboundsのtagが一字一句一致しているか確認します。次に規則の順序とdomainStrategyを確認してください。タグの綴りを誤ると規則全体の宛先が失われ、対象範囲を広げても解決しません。
v2rayNが生成した設定から画面の設定を逆引きする
v2rayNが保存するノード情報、ルーティング規則、最終的にコアへ渡す実行設定は、完全に同一ではありません。クライアントは、現在選択中のサーバー、ローカルポート、DNS、ログレベル、分流規則を統合して実行ファイルを生成します。そのため、サブスクリプション内の単一の共有リンクは通常、1つのプロキシoutboundに対応するだけで、JSON全体を表すものではありません。
問題を確認するときは、まずメイン画面で現在アクティブなサーバーを確認し、次に「設定」→「パラメータ設定」でローカルポートとコアのオプションを確認します。ルーティング関連は「設定」→「ルーティング設定」でルールセット、有効状態、並び順を確認できます。サーバー情報を変更した後はコアの再起動が必要です。旧プロセスの実行設定は自動的に新しい内容へ変わりません。
- システム時刻とタイムゾーンが正しいことを確認し、時刻のずれによるTLSハンドシェイク失敗を避けます。
- v2rayN 7.10.5で「設定」→「パラメータ設定」→「基本設定」を開き、SOCKSとHTTPのポートを記録します。
- 実行ログにポート競合、ドメインを解決できないエラー、接続タイムアウト、ハンドシェイク失敗がないか確認します。
- ログレベルを一時的にinfoへ変更し、リクエストを1回再現した直後に、対応するinboundTagとoutboundTagを確認します。
- 切り分けが終わったらログレベルをwarningへ戻し、長時間の実行で出力されるログ量を減らします。
ローカル環境での確認では、SOCKS入口に127.0.0.1:10808、HTTP入口に127.0.0.1:10809を使用しました。100回連続でアクセスすると、ルールログには入口タグと出力選択がそれぞれ100回記録されました。proxy-vless出力を削除し、同名のoutboundTagだけを残すとリクエストは直ちに失敗しました。これは、ルーティングの一致と出口の存在が独立した確認ポイントであることを示しています。
| ログに現れる症状 | 優先して確認するブロック | 具体的な確認項目 |
|---|---|---|
| ポートが使用中 | inbounds |
listen、port、および旧コアプロセスが残っていないか |
| サーバーへの接続がタイムアウト | outbounds |
address、port、network、現在のネットワーク出口 |
| TLSハンドシェイクに失敗 | streamSettings |
security、serverName、システム時刻、転送パラメータ |
| 中国本土のドメインがプロキシ経由のまま | routing |
規則の順序、domainStrategy、ルールリソース、タグ名 |
| ドメイン規則に一致しない | sniffing |
入口がドメインを識別できているか、アプリが宛先IPだけを送っていないか |
v2rayNGでXrayコアを使用している場合も、ログに現れる入口、宛先、出力の手掛かりからリクエスト経路を判断できます。v2flyNGでv2flyコアを使用している場合、inbounds、outbounds、routingという基本概念は共通していますが、特定のセキュリティ層や拡張フィールドの対応範囲は、実際に使用しているコアのバージョンを基準にしてください。一方のコア固有のフィールドを、そのまま別のコアの設定へコピーしないでください。
よくあるフィールドの疑問と変更時の注意点
JSONの手動編集は、問題の切り分けや構造の理解には役立ちますが、長期的な管理に適しているとは限りません。サブスクリプションの更新やクライアントによる実行設定の再生成で、一時的な変更が上書きされる場合があります。長期的に保持したいポート、ルーティング、DNSの設定は、できるだけクライアントの対応画面で変更してください。画面に用意されていない高度なフィールドだけ、カスタム設定機能の利用を検討します。
設定は起動するのに、ブラウザが直接接続してしまう場合は?
まずブラウザまたはシステムのプロキシが127.0.0.1:10809を指しているか確認します。SOCKSを使う場合はポートが10808です。コアが正常に起動したということは入口が待ち受けているだけで、アプリがその入口へリクエストを渡しているとは限りません。
routingでdirectを指定したのに、なぜプロキシ経由になるのですか?
まずdirectがoutboundsのtagに実際に存在するか確認し、その規則が全通信を対象とするプロキシ規則より前にあるか確認します。ドメイン規則では、sniffingとdomainStrategyによって一致可能な宛先情報が提供されているかも確認してください。
JSONを変更しても再起動すると元に戻るのはなぜですか?
通常は、クライアントが生成した実行ファイルを編集していることが原因です。「設定」→「パラメータ設定」または「設定」→「ルーティング設定」に戻り、元となる設定を変更してから、クライアントに実行ファイルを再生成させてください。
1つの設定に複数のプロキシ出口を置けますか?
可能です。各outboundにproxy-vlessやproxy-vmessなど重複しないtagを設定し、異なるルーティング規則で選択します。規則から参照されていない追加の出口が、自動的にリクエストを分散することはありません。
ポート10808は自由に変更できますか?
1024から65535までの範囲で、使用されていないポートへ変更できます。ただし、アプリのプロキシ設定も同時に更新する必要があります。変更後はログを確認し、新しいポートで待ち受けが始まっていることを確認してください。
設定を読むときは、「入口タグ、宛先の特徴、規則の一致、出口タグ、接続パラメータ」の5段階で確認すると整理しやすくなります。まずリクエスト経路を図にしてから具体的なプロトコルフィールドを確認すると、数百行あるJSONを先頭から一字ずつ調べるより速く問題を見つけられます。クライアントが生成したファイルでは、各フィールドの出所も重要です。サブスクリプションはノードパラメータ、パラメータ設定はローカル入口、ルーティング設定は分流を担当し、コアが最終的に統合後の結果を実行します。
結論:設定はフィールド一覧ではなく接続図として捉える
リクエストがどのinboundから入り、どのruleに一致し、最終的にどのoutboundへ渡されたかを確認できれば、ポート、分流、接続に関する問題の大半を特定のブロックまで絞り込めます。