サブスクリプションを追加済みで、主要な設定項目を理解したい方向けの記事です。ローカルSOCKSの入口、直接接続とブロックのoutboundだけを含むJSONで構造を確認し、ログ、DNS、ポート、タグ、ルールの順序を解説します。読み終えると、「コアの起動に失敗する」「ローカルポートに接続できない」「ルールに一致しない」ときに、どこを確認すべきか分かります。
クライアント設定とコア設定を区別する
v2rayNは、サブスクリプション、サーバー項目、ルーティングプリセット、コアプロセスを管理するデスクトップクライアントです。V2RayやXrayは、コア設定を読み込んで接続を処理するプログラムです。クライアントに保存される画面表示の設定やサブスクリプションのグループ情報は、コアに渡される実行時のJSONとは異なります。問題を調べる際は、今回の起動で実際に読み込まれたファイルを確認してください。拡張子が.jsonだからといって、すぐに編集するのは避けましょう。
Android版のv2rayNGはXrayコアを、v2flyNGはV2Flyコアを使用します。この記事ではV2Rayで一般的な設定構造を解説しますが、すべての項目が両方のコアで使えるわけではありません。たとえばREALITYはXray関連の機能であり、該当する設定をそのままV2Flyに渡すことはできません。同じstreamSettingsという項目でも、利用できるトランスポート名やオプションは使用中のコアで確認してください。
この流れが設定を読む際の基本です。DNSはドメイン名の解決が必要な場面で使われ、ログには一連の処理が記録されます。システムプロキシの影響を受けるのは、その設定に従うアプリだけです。設定にSOCKS inboundがあっても、すべてのアプリの通信がコアに渡るとは限りません。入口が接続されていない状態では、ルーティングを変更しても通常は結果が変わりません。
- コアを確認:クライアント名だけで判断せず、起動ログでV2RayとXrayのどちらが動作しているか確認します。
- 設定ファイルを確認:起動ログまたはプロセスの起動引数で設定ファイルのパスを確認します。パスやファイル名はクライアントのバージョンによって変わることがあります。
- 元のファイルを保管:実行中の設定を読み取る前にコピーしておきます。サブスクリプションの更新、ノードの切り替え、コアの再起動でファイルが再生成される場合があります。
完全なJSON例:inbound 1つ、outbound 2つ、ルール2つ
以下は構造を学ぶための設定例で、リモートのプロキシサーバーは含みません。127.0.0.1:10808でSOCKSを待ち受け、example.orgへの完全一致リクエストとTCPポート25への接続をブロックし、それ以外はデフォルトで直接接続します。既存のサブスクリプション設定の代わりに使うと、元のプロキシoutboundが失われるため注意してください。
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": [
"1.1.1.1"
]
},
"inbounds": [
{
"tag": "socks-local",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIP"
}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"inboundTag": [
"socks-local"
],
"domain": [
"full:example.org"
],
"outboundTag": "block"
},
{
"type": "field",
"network": "tcp",
"port": "25",
"outboundTag": "block"
}
]
}
}
トップレベルオブジェクトのキーの並び順は、通常、処理順を左右しません。この記事では読みやすさを優先して並べています。一方、配列の順序は動作に直接影響する場合があり、特にoutboundsの先頭項目とrouting.rulesの順番が重要です。「書式を整える」目的で、この2つの配列を安易に並べ替えないでください。
log:ログから起動エラーと接続エラーを切り分ける
logはログ出力を制御する項目で、接続先ノードを選択するものではありません。この例ではloglevelのみ設定し、ログファイルは指定していません。実際の出力先はコアの起動方法によって異なり、クライアントがログ画面に出力を集約する場合もあります。問題の切り分けでは、まず起動直後の最初のエラーを確認し、次にアクセスを試したときに追加された記録を確認します。
| 項目・現象 | 内容 | 次に確認すること |
|---|---|---|
loglevel: warning | 警告とエラーを記録し、通常利用時のログ出力を抑えます。 | 接続の詳細を確認したい場合は、一時的にinfoへ変更します。 |
loglevel: debug | デバッグ情報が多く出力され、ログの増加も速くなります。 | 問題を一度再現したら、ログレベルを元に戻します。共有する前に機密情報を削除してください。 |
address already in use | 待ち受けアドレスまたはポートが別のプロセスに使用されています。 | 10808を別のコアプロセスがすでに待ち受けていないか確認します。 |
| フィールドの解析または設定ファイルの読み込みエラー | コアが接続を正常に処理する段階まで起動していません。 | フィールド名のスペル、データ型、使用中のコアがそのオプションに対応しているかを確認します。 |
コアが起動直後に終了する場合は、DNSを変更する前に設定ミスやポートの競合を解消してください。コアが正常に動作していて特定のリクエストだけ失敗する場合は、対象、ルーティング結果、接続エラーを確認します。ログにはアクセス先のドメイン名やサーバーアドレス、ローカルパスが含まれる場合があります。実行中の設定ファイルやログを、そのまま公開ページに掲載しないでください。
dns:DNSサーバーとルーティング方針は別の設定
dns.serversでは、コア内蔵DNSが使用するDNSサーバーを指定します。例の1.1.1.1は通常のDNSサーバーアドレスで、一般にUDP 53番ポートで問い合わせます。ここでは暗号化DNSを設定しておらず、問い合わせが自動的にプロキシ経由になるわけでもありません。DNSサーバーに到達できるかは、実際のネットワーク環境で確認してください。
特に混同しやすいのが、同じような名前の2つのフィールドです。routing.domainStrategyはルーティングの照合時にドメイン名をどう扱うかを決めます。一方、freedom outbound内のsettings.domainStrategyは、直接接続を確立する際に接続先をどう名前解決するかを決めます。別々のオブジェクト内にあり、値の種類も役割も異なります。
ルーティングの照合段階
- 設定場所
routing.domainStrategy- 例の値
AsIs- 役割
- ルーティングの照合のために接続先ドメインを能動的に解決しません。
- その他の一般的な値
IPIfNonMatch、IPOnDemand
AsIsでも、接続処理全体でDNS問い合わせが発生しないという意味ではありません。
直接接続の段階
- 設定場所
freedom.settings.domainStrategy- 例の値
UseIP- 役割
- 内蔵DNSで接続先ドメインをIPアドレスに解決してから接続します。
- 名前解決に使うDNS
- この例の
dns.servers
routingのIPIfNonMatchをここに指定しないでください。
IPIfNonMatchはドメイン名がルールに一致しない場合に名前解決を試し、その後IPルールを確認します。IPOnDemandは照合中にIPアドレスが必要になった時点で名前解決します。どちらも「すべての通信を強制的にプロキシ経由にする」設定ではありません。IPルールを設定していない場合は、ドメインルールの説明に余計な名前解決処理を持ち込まず、シンプルな方針を保ちましょう。
- ブラウザー自身が行うドメイン名の解決は、コアに
dnsオブジェクトがあるだけで、すべて自動的にコアへ渡るわけではありません。 - アプリがSOCKS入口にIPアドレスだけを渡すと、コアが元のドメイン名を取得できない場合があります。その場合、ドメイン名ルールに一致しないことがあります。
- 内蔵DNSの設定はOSのDNS設定を変更するものではありません。それぞれ別に確認してください。
inbounds:アプリが接続する入口を確認する
inboundsは配列で、各項目が接続を受け付ける入口を表します。この例では、listenをローカルのループバックアドレスに限定し、portに数値の10808、protocolにsocksを指定しています。この3つのフィールドで、アプリがどこへ、どのプロトコルで接続するかが決まります。
- 待ち受けアドレスを確認:
127.0.0.1は同じ端末からの接続に限られます。0.0.0.0に変更すると待ち受け範囲が広がります。問題の切り分けのために、認証のない入口を不用意に公開しないでください。 - プロトコルを確認:SOCKSポートはHTTPプロキシのポートとは異なります。HTTPプロキシにしか対応していないアプリを、この例の10808に接続しても、ノードが利用可能かどうかは判断できません。
- 実際のポートを確認:10808はこの記事の例で指定した値で、すべてのクライアントで共通の値ではありません。v2rayNでは「設定」→「パラメーター設定」でローカル待ち受けの項目を確認できます。最終的には実行中の設定とログを確認してください。
- UDPを確認:
udp: trueを指定すると、このSOCKS inboundでUDPを処理できます。ただし、アプリがSOCKSのUDP機能を使う必要があり、後続のoutboundとネットワークも該当する通信に対応している必要があります。
tag: socks-localは入口を識別する内部名であり、ドメイン名やサブスクリプションのノード名ではありません。待ち受けプロトコルを変えるものではなく、他の設定から入口を参照するために使います。この例の最初のルールでinboundTagが配列なのは、1つのルールで複数の入口タグを指定できるためです。
"inboundTag": [
"socks-local"
]
入口のタグを変更したら、それを参照するルールも合わせて変更してください。inboundのsocks-localだけをlocal-socksに変更し、ルールをそのままにすると、そのルールは入口の通信に一致しなくなります。
outbounds:タグ、プロトコル、デフォルトの接続先
outboundsでは、次に接続をどう送信するかを定義します。この例のfreedomは直接接続、blackholeはブロックを意味し、どちらもリモートプロキシのプロトコルではありません。実際のサブスクリプションから生成された設定には、VMessやVLESSのoutboundが追加され、サーバーアドレス、ポート、ユーザー識別情報、トランスポートの設定などが含まれる場合があります。
| 項目 | この記事の例 | 確認ポイント |
|---|---|---|
tag | direct、block | ルールから参照する名前です。大文字・小文字やスペルを含め、完全に一致させます。 |
protocol: freedom | 直接接続のoutbound | コアを実行している端末から接続先へ直接接続します。 |
protocol: blackhole | ブロック用outbound | 指定した通信を拒否します。自動的に別のoutboundへ切り替わることはありません。 |
| VMess、VLESS | この例には未設定 | 有効なサーバー情報と認証パラメーターが必要です。プロトコル名を変更するだけでは使えません。 |
streamSettings | この例では不要 | トランスポートとセキュリティ層を定義します。サーバー側の設定と一致させる必要があります。 |
他のデフォルト振り分け機能を設定していないこの例では、ルーティングルールに一致しない接続はoutboundsの先頭項目を使うため、デフォルトで直接接続されます。blockを先頭に移動すると、該当しない接続の処理が変わります。タグ名を変更しても、配列の順序は自動で変わりません。
まとめ:例外ルールより先にデフォルトoutboundを確認
実行中の設定を開いたら、まずoutboundsの先頭項目のtagを控え、その後routing.rulesのoutboundTagを1つずつ確認します。設定を生成した側がタグ名を決めるため、「proxy」という文字列を検索するだけより確実です。
実際の設定でプロキシoutboundのタグにproxyを使っている場合、ルーティングのoutboundTag: proxyに対応するoutboundが必要です。この例にproxy宛てのルールを追加しても、プロキシ接続が自動で作られるわけではありません。まずクライアントが生成した有効なプロキシoutboundを残し、その内容を確認してください。
routing:ルールは上から確認し、条件の「AND」と「OR」を区別する
routing.rulesは通常、上から順に確認されます。ルールに一致すると指定されたoutboundが使われ、それ以降の通常ルールは確認されません。そのため、具体的なルールは対象範囲の広いルールより前に置きます。設定にルールを書いても、必ず評価されるとは限りません。
同じルール内の異なる条件フィールドは通常「AND」の関係になり、同じフィールドの配列にある候補値は通常「OR」の関係になります。この例の最初のルールでは、入口がsocks-localであり、接続先ドメインがexample.orgであることの両方を満たすと、blockへ送られます。
full:example.org:このドメインに完全一致します。www.example.orgは含まれません。domain:example.org:このドメインとそのサブドメインに一致します。ドメイン全体を対象にする必要がある場合に使います。network: tcpとport: "25":この例の2つ目のルールは、TCP通信かつ接続先ポートが25の場合に一致します。ローカルの待ち受けポートではありません。outboundTag: block:ブロック用outboundへ送ります。次のルールを引き続き試すわけではありません。
| ローカルSOCKSに送られるリクエスト | 照合結果 | 処理結果 |
|---|---|---|
| ドメイン example.org、TCP 443 | 最初のルールの入口と完全一致ドメインの条件を満たします。 | block |
| ドメイン www.example.org、TCP 443 | 完全一致ドメインではなく、接続先ポートも25ではありません。 | デフォルトのdirect |
| その他のドメイン、TCP 25 | 最初のルールには一致せず、2つ目のルールに一致します。 | block |
| その他のドメイン、TCP 443 | どちらのルールにも一致しません。 | デフォルトのdirect |
この判定例は、アプリがドメイン名をSOCKS inboundに渡すことを前提としています。アプリが先に名前解決し、IPアドレスだけを渡す場合、最初のドメイン名ルールは利用できないことがあります。一部のプロトコルではスニッフィングでドメイン情報を識別できますが、元のドメイン名を必ず復元できる機能ではありません。この例ではスニッフィングを有効にしていないため、まずドメイン名を明示したリクエストでルールをテストしてください。
設定の確認手順とよくある質問
設定を読むときは、一度に変更する項目を1つに絞り、変更前後のログを記録してください。まずコアが起動することを確認し、次に入口への接続、最後にルールとoutboundを確認します。ポート、DNS、タグ、トランスポートの設定を同時に変更すると、成功・失敗の原因を特定しにくくなります。
- 構文とデータ型を確認:ポート
10808は数値、udpはブール値のtrue、inboundsとoutboundsは配列です。 - すべての参照先を確認:
inboundTagとoutboundTagを1つずつ検索し、対応するinboundまたはoutboundに同じ名前のtagがあることを確認します。 - アプリが入口を使っているか確認:この例をテストするときはSOCKSアドレスを明示し、ブラウザーのシステムプロキシ設定の影響を避けます。
- ルーティングを検証:最初のルールから順に、接続先ドメイン、ポート、ネットワーク種別、入口タグを照合します。
- クライアント管理に戻す:仕組みを確認したら、継続して使う変更はクライアントが対応するルーティング設定または設定項目に反映し、実行設定を再生成して確認します。
SOCKS対応のcurlがインストールされている場合、コアでこの設定例を読み込み、ポートが使用中でないことを確認したうえで、次のコマンドを実行できます。socks5hは接続先ドメインの処理をSOCKSサーバーに任せます。この例ではドメイン完全一致ルールによりリクエストがブロックされます。失敗はテストの想定どおりであり、リモートプロキシの障害を意味しません。
curl --proxy socks5h://127.0.0.1:10808 --connect-timeout 10 https://example.org/
JSONを変更したのに、v2rayNを再起動すると元に戻るのはなぜ?
実行用ファイルはクライアントによって再生成される場合があります。まず変更内容を記録し、「設定」→「ルーティング設定」で該当するルールを確認するか、使用中のバージョンが正式に対応しているカスタム設定の入口を使ってください。一時的な実行ファイルを永続設定の保存先として扱わないようにしましょう。
outboundTagにproxyと書いたのに、なぜ起動時にエラーになる?
outbounds配列で、tagがproxyの項目を探し、スペルや大文字・小文字の違いがないか確認します。該当項目がなければ、freedomの名前だけを変更するのではなく、有効なプロキシoutbound設定を復元してください。
DNSを1.1.1.1に変更したのに、ドメイン名ルールに一致しないのはなぜ?
まずアプリがドメイン名を渡しているかを確認し、次にルールの順序とfull、domainのプレフィックスを確認します。DNSサーバーを変更しても、アプリから失われたドメイン情報は復元されず、ルールの優先順位も変わりません。
VLESSのoutboundでVMessのprotocolフィールドをそのまま置き換えられる?
できません。2つのプロトコルでは認証フィールドとプロトコルパラメーターが異なり、トランスポートとセキュリティ層もサーバーの設定に合わせる必要があります。正しいサブスクリプションまたは接続情報を再度読み込み、使用中のコアが対応するフィールドを確認してください。
設定の詳しい解説はルーティングの技術解説をご覧ください。クライアント画面で名前解決の設定を確認する場合は、チュートリアルのDNS設定手順に沿って操作してください。コア設定の構造を理解してからクライアント画面と照らし合わせることで、サブスクリプション、入口、ルーティングを同じ設定と誤認するのを防げます。