ノードをインポートしたものの、クライアントが生成した設定の読み方がわからない方に向けて解説します。まず、ローカルの10808ポートと直結のoutboundで構成を確認し、次にVMess outboundとドメインルーティングの例で各項目の関係を見ていきます。読み終えると、ローカルの待ち受け、リモートへの接続、ルール判定、クライアント設定を区別でき、サブスクリプションURLと完全なconfig.jsonを混同しなくなります。
1. config.jsonの基本構造とリクエストの流れ
config.jsonはコアが読み込む設定ファイル名の一つであり、保存場所が固定されているわけではありません。v2rayNなどのクライアントは、一時的な実行用設定を生成することがあります。生成されたファイルを手動で編集しても、次にノードを切り替えた際に上書きされる可能性があります。まず、現在使用中のコアがXrayかV2Flyかを確認し、実際に読み込まれている設定ファイルと起動ログを調べてください。
inboundsとoutboundsはそれぞれ配列で、複数の入口と出口を設定できます。routingはオブジェクトで、その中のrulesがルール配列です。tagは設定内で参照する名前であり、サーバーアドレスではありません。ルールはoutboundTagでoutboundを指定します。
以下はローカルでの直結テスト専用の基本設定例です。ループバックアドレスでSOCKSを待ち受け、ルールに該当しないリクエストは最初のoutboundであるdirectを使います。リモートのプロキシノードは含まれておらず、システムプロキシも自動では変更されません。
{
"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": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": []
}
}
2. inbounds:待ち受けアドレス・ポート・ローカルプロトコル
inboundは「アプリからコアへ通信を渡す方法」を決めます。上の例にある127.0.0.1:10808はローカルのSOCKS入口であり、リモートノードのポートではありません。ブラウザーやコマンドラインツールなど、SOCKSに対応したアプリでこの入口を指定すると、通信がコアに渡されます。
ローカルSOCKS inbound
- tag
- local-socks
- listen
- 127.0.0.1
- port
- 10808
- protocol
- socks
ローカルからの接続のみ受け付けます。アプリ側でSOCKSを選択してください。
HTTP inbound(任意)
- tag
- local-http
- listen
- 127.0.0.1
- port
- 10809
- protocol
- http
使用するにはinboundsに個別に追加する必要があります。SOCKS inboundと一緒に自動で追加されることはありません。
10808と10809はこの記事で使う例の値であり、すべてのバージョンで固定のデフォルト値ではありません。アプリのHTTPプロキシにSOCKSポートを指定すると、プロトコルが一致しません。クライアントに混合プロトコルの入口がある場合は、実際に対応するプロトコルを確認してください。ポート番号だけで判断しないようにしましょう。
listen: "127.0.0.1"はローカルからのアクセスに限定され、個人のデスクトップでのテストに適しています。listen: "0.0.0.0"にすると、すべてのIPv4ネットワークインターフェースで待ち受けます。LANで共有するには認証やファイアウォールの設定も必要です。アドレスを変更するだけで公開しないでください。settings.udp: trueを設定するとSOCKS経由のUDP転送が有効になります。ただし、アプリがSOCKS5 UDPに対応し、後続のoutboundとサーバーも対象の通信に対応している必要があります。- システムプロキシはOSレベルで入口を設定する機能、TUNは仮想ネットワークインターフェースを使って通信を取り込む方式です。どちらも通常のSOCKS inboundとは異なります。
以下のコマンドで、サンプルの入口からアプリがHTTPSリクエストを送信できるか確認できます。Windowsではcurl.exe、macOSとLinuxではcurlを使います。socks5hは接続先のドメイン名をプロキシ側に渡す指定です。プロキシ側での名前解決方法は設定によって異なります。
curl --proxy socks5h://127.0.0.1:10808 --connect-timeout 10 -I https://example.com
3. outbounds:リモートノードと通信パラメーター
outboundは「コアが接続先へどこから接続するか」を決めます。freedomは直接接続、blackholeは通信の遮断、vmessはリモートサーバーとの連携に使います。inboundにSOCKS、outboundにVMessを設定することもできます。それぞれ通信経路の異なる箇所を担うため、同じ名前にする必要はありません。
以下はトップレベルのoutboundsを置き換える例です。192.0.2.10はドキュメント用のアドレスで、UUIDとドメイン名も構造を説明するための例にすぎず、そのままでは接続できません。実際に使用する際は、アドレス、ポート、ユーザーID、トランスポート、TLSの各パラメーターを、利用許可のあるサーバー設定に合わせてください。一つの項目だけを置き換えても動作しません。
{
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "192.0.2.10",
"port": 443,
"users": [
{
"id": "b43b4b90-a710-4ee4-883d-b8c574099d11",
"alterId": 0,
"security": "auto"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "proxy.example.net"
}
}
},
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
| 項目 | 例 | 確認ポイント |
|---|---|---|
settings.vnext[].address | 192.0.2.10 | リモート接続先のアドレスです。ローカルの待ち受けアドレスではありません。 |
settings.vnext[].port | 443 | サーバーが接続を受け付けるポートです。10808ではありません。 |
users[].security | auto | VMessのユーザー暗号化方式です。TLSの有効・無効を切り替える項目ではありません。 |
streamSettings.network | tcp | この例ではTCPを使用しています。ほかのトランスポートには、それぞれ対応する設定が必要です。 |
streamSettings.security | tls | トランスポート層のセキュリティ方式です。プロトコル内のsecurityとは意味が異なります。 |
tlsSettings.serverName | proxy.example.net | TLSのサーバー名です。サーバーの設定と証明書に一致させてください。 |
要点:プロトコルを確認してからトランスポートを確認
VMessからVLESSに変更する場合、protocolだけを書き換えても動きません。使用するコアの設定仕様に沿ってsettingsを確認し、次にstreamSettingsを確認してください。TLS接続に失敗する場合は、ドメイン名、証明書、システム時刻を調べます。証明書検証を無効にする方法を、通常の解決策として使わないでください。
v2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。v2rayNで使えるコアは、実際にインストールして選択したものによります。トップレベルの構造が似ていても、拡張項目がすべて互換とは限りません。特にVLESSの一部のセキュリティ構成には注意が必要です。この記事のTCP設定例は一般的な項目を説明するためのものです。実際の項目名と互換性は、インストール済みのコアのバージョンに合わせて確認してください。
4. routing:ルールの順序・タグ参照・デフォルトの出口
ルーティングはドメインをいくつかのグループに分ければ自動的に有効になるものではなく、ルールを順番に確認します。通常は最初に一致したルールで出口が決まります。一つのルール内にある異なる条件はすべて満たす必要がありますが、同じ条件の配列内に複数の値がある場合はいずれかに一致すれば対象になります。outboundTagは、既存outboundのtagと完全に一致させてください。
以下の例は、前のセクションで設定したproxy、direct、blockの3つのoutboundを使用します。サンプルドメインをブロックし、次にプライベートアドレスを直接接続、それ以外の通信をプロキシに送ります。どちらのドメインもルール説明用の例であり、実際のアクセス先を推奨するものではありません。
{
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": ["full:blocked.example.org"],
"outboundTag": "block"
},
{
"type": "field",
"ip": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["domain:example.org"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
full:blocked.example.orgは、この完全なドメイン名だけに一致します。example.orgのサブドメインでもありますが、ブロックルールが先にあるため、こちらが優先されます。- プライベートネットワーク向けのルールは、接続先IPが該当範囲に含まれるリクエストを処理します。特殊用途アドレスの一覧をすべて網羅するものではなく、IPv6のローカルアドレスも自動的には対象になりません。
domain:example.orgは、このドメインとそのサブドメインに一致します。任意の文字列に含まれるかどうかを判定するものではありません。- 最後の
network: "tcp,udp"は、この例のフォールバックルールです。具体的なルールより後ろに置かないと、それ以前の振り分けが先に処理されてしまう可能性があります。
どのルールにも一致しない場合、通常はoutbounds配列の先頭にあるoutboundが使われます。1つ目のセクションでは先頭がdirect、3つ目のセクションではproxyに変更されているため、配列の順番を変えるだけでもデフォルトの動作が変わることがあります。「配列内にプロキシノードがあるから、すべてのリクエストがプロキシを通る」とは限りません。
5. dns・ログとクライアント生成設定の注意点
routing.domainStrategyは、ルーティングの判定時にドメイン名をどう扱うかを指定します。DNSサーバーのアドレスでも、DNSの振り分け設定全体でもありません。AsIsは元の接続先をできるだけ保持して判定します。IPIfNonMatchはドメインルールに一致しない場合に名前解決を試み、その後IPルールを確認します。IPOnDemandはIPルールの確認時に名前解決を行う場合があります。
以下の例は組み込みDNSの設定を追加するだけで、OSのDNS設定を自動変更するものではありません。また、すべてのアプリのDNS問い合わせがコアに渡るとは限りません。アプリが接続前にローカルで名前解決している場合、コアが受け取るのはIPアドレスだけのことがあります。プロキシプロトコルでドメイン名を渡す場合は、最終的な名前解決の場所がoutboundやサーバーによって変わることもあります。
{
"dns": {
"servers": ["localhost"]
}
}
- サブスクリプション:クライアントがノード情報を取得するための入口です。
outboundsにそのまま記述できる共通のコア設定項目ではありません。 - システムプロキシ:OSのプロキシ設定に従うアプリにローカルの入口を使うよう指示します。すべてのプロセスの通信が取り込まれるわけではありません。
- TUN:クライアントとネットワークコンポーネントが連携して管理します。画面上のTUNスイッチを、汎用的なJSON項目に置き換えることはできません。
- ログ:問題の切り分けでは、
log.loglevelを一時的にinfoへ変更し、再読み込み後に一度再現させてください。確認後はwarningに戻します。
クライアントが書き出した設定を読むときは、まずinbounds[].port、outbounds[].tag、routing.rulesを確認し、その後DNSやトランスポートの詳細を追ってください。内容がわからない管理用の入口や追加項目を、すぐに削除しないでください。クライアントの統計情報、制御用インターフェース、実行時機能に使われている可能性があります。ログを共有する前に、ユーザーID、サブスクリプションURL、サーバー情報も削除してください。
6. 設定変更後の確認手順とよくある問題
変更前に元に戻せる設定のコピーを保存し、一度に変更するのは一つの項目だけにしてください。まずJSONとコアの設定項目を検証し、次にポートの待ち受けを確認してから、リモート接続とルールの一致をテストします。以下のコマンドは、該当するコマンドラインインターフェースを備えた比較的新しいコア向けです。実際の引数はインストール済みプログラムのヘルプで確認してください。クライアントが管理する設定では、実際に読み込まれているファイルのパスを使います。
xray run -test -config config.json
v2ray test -c config.json
テストコマンドが成功しても、ノードが利用できるとは限りません。主に現在のコアが設定を受け付けるかを確認するもので、リモートでの認証、TLSハンドシェイク、接続先へのアクセス確認に代わるものではありません。コアは起動するのにアプリから接続できない場合は、「ローカルの入口」「リモートの出口」「ルーティング結果」の順に問題箇所を絞り込んでください。
「address already in use」と表示されたら、どのポートを変更する?
まず、使用中と表示されているinboundのポートを確認してください。ログに10808とあれば、重複して起動したコアを終了するか、inboundsのポートを10810に変更し、アプリのプロキシアドレスも同じ値に更新します。リモートノードの443ポートは変更しないでください。
起動するのにcurlで接続できない場合は?
まず、1つ目のセクションの直結設定とsocks5hを使ったテストコマンドで入口を確認してください。ローカルポートへの接続自体に失敗する場合は、待ち受けアドレス、ポート、プロキシプロトコルを調べます。接続がコアに届いてからタイムアウトする場合は、リモートアドレス、認証、TLSのログを確認してください。
directルールを設定したのにproxy経由になるのはなぜ?
ルールの順序、outboundTagの綴り、コアが実際に受け取っているのがドメイン名かIPアドレスかを確認してください。フォールバックルールが前に置かれていないかを調べ、変更したファイルが現在のプロセスに読み込まれていることも確認します。クライアントが別の設定を再生成している場合があります。
サブスクリプションの更新後に手動編集したJSONが消えるのはなぜ?
クライアントがノード設定と全体設定から実行用設定を再生成している可能性があります。変更を維持するには、クライアントに用意されたルーティング、inbound、カスタム設定の機能を使ってください。完全なJSONを独立して管理する場合は、ファイルのパスとコアの起動方法も明確にし、2つの設定が互いに上書きしないようにしてください。
要点:変更ごとに一つのリクエストで検証
ローカルの入口を127.0.0.1:10808に固定し、テスト対象も同じものにしてから、直結、プロキシ、ルーティングをそれぞれ確認してください。変更のたびに再読み込みしてログを見ると、ポート、DNS、トランスポートを一度に変更するより、問題の層を見つけやすくなります。