この記事は、ノードへの接続ができており、直結とプロキシの振り分けを調整したい方を対象にしています。まずドメインとIPのマッチ方法を確認し、「個別の例外、カテゴリルール、最後のフォールバック」の順に設定します。最後にドメインの名前解決方式と実際のアウトバウンドを確認します。例ではV2Fly V2RayとXrayで一般的なfield形式のルーティング構造を使用します。クライアントの編集画面はカーネル設定全体を表示するものではないため、保存後は生成された設定も確認してください。
ルーティングの基本:マッチ条件とアウトバウンドタグ
ルーティングは、接続をどのアウトバウンドで処理するかを決める機能です。ノードを作成する機能ではなく、ノードで使うVMessやVLESSのプロトコルを変更するものでもありません。V2Rayはカーネルプロジェクト、Xrayは別のカーネルプロジェクトです。v2rayNはデスクトップ向けのGUIクライアントで、画面上の設定を選択中のカーネルが読み込める形式に変換します。
一般的なルールには、type: "field"、マッチ条件、outboundTagが含まれます。タグはoutbounds内に存在するtagと一致させる必要があります。この記事では、プロキシ、直結、ブロックのアウトバウンドをそれぞれproxy、direct、blockと表記します。これらは例として付けた名前であり、すべてのクライアント設定で同じタグが使われているとは限りません。
- 同じフィールド内は基本的に「OR」:
domain配列内の条件のうち、いずれか1つに一致すればそのフィールドを満たします。 - 異なるフィールド間は「AND」:同じルールに
domainとportを指定した場合、ドメインと接続先ポートの両方が一致する必要があります。 - domainとipは二者択一ではありません:同じルールに両方を指定すると、両方の条件を満たす必要があります。「ドメインまたはIP」を条件にする場合は、ルールを分けてください。
- portは接続先のポート:
port: "443"はリモートサービスのポートに一致します。ローカルのプロキシ待ち受けポートではありません。
これらの数値は設定例であり、速度測定の結果やクライアントの既定値を示すものではありません。実際の待ち受けポートはローカル設定で確認してください。HTTPSは別のポートでも利用できるため、443だけを根拠にすべての暗号化通信を判断することはできません。
domainの4つのマッチ方法:部分一致、正規表現、ルートドメイン、完全一致
domainフィールドとdomain:プレフィックスは混同しやすいため注意してください。前者はルールのフィールド名、後者はフィールド内の文字列に使うマッチ方法です。よく使われる書き方は4種類で、プレフィックスなしの通常の文字列と、regexp:、domain:、full:を使う方法があります。通常の文字列に、対称に見せるためだけのプレフィックスを付けないでください。
| 書き方 | マッチ範囲 | 使用時の注意 |
|---|---|---|
example.com | ドメインにこの文字列が含まれる場合 | notexample.comにも一致する可能性があり、ルートドメインのマッチより範囲が広い |
domain:example.com | example.comとそのサブドメイン | www.example.comに一致し、notexample.comには一致しない |
full:api.example.com | api.example.comとの完全一致のみ | cdn.api.example.comは対象外 |
regexp:^api[0-9]+\.example\.com$ | 正規表現に一致する文字列全体 | JSON内ではバックスラッシュをさらにエスケープする必要があります |
サイト単位の振り分けには、通常domain:を使います。特定のホストだけ例外にする場合はfull:を使ってください。ドメイン条件にはドメインだけを指定します。https://、ページのパス、クエリパラメーターは入力できません。また、ルーティングルールで特定の記事ページのパスを使った振り分けはできません。
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:example.org",
"regexp:^api[0-9]+\\.example\\.com$"
],
"outboundTag": "proxy"
}
この正規表現はapi12.example.comに一致します。先頭の^と末尾の$で文字列の境界を指定し、ドットの前のバックスラッシュで文字どおりのドットを表します。ドメインは書き方を示すための例です。実際の設定では振り分けたいサービスのドメインに置き換えてください。
ip・geoip・geosite:アドレス範囲とデータファイル
ipフィールドには、単一アドレス、CIDRネットワーク、またはgeoip:参照を指定できます。192.168.1.10/32はIPv4アドレス1つだけを対象とし、192.168.1.0/24はそのネットワーク全体を対象とします。IPv6の単一アドレスには/128を指定できます。ここでマッチするのは接続先アドレスです。リクエスト元を条件にする場合は、対応する別のフィールドを使ってください。
{
"type": "field",
"ip": [
"192.168.1.0/24",
"geoip:private"
],
"outboundTag": "direct"
}
geoip:privateはデータファイル内のプライベートアドレスカテゴリを参照し、geoip:cnは中国のIPカテゴリを参照します。リアルタイムの位置情報サービスではなく、実際の範囲は読み込んだgeoip.datによって異なります。ネットワークの割り当て状況やデータの更新時期によって判定が変わることもあります。カテゴリに一致したからといって、サーバーの物理的な所在地を示すわけではありません。
- geositeはdomainに指定:たとえば
"domain": ["geosite:cn"]はドメインカテゴリを参照します。IPカテゴリではありません。 - geoipはipに指定:たとえば
"ip": ["geoip:cn"]はアドレス範囲を参照します。Webページのドメイン文字列にはマッチしません。 - カテゴリがデータに含まれている必要があります:
geosite:category-ads-allは一部のデータセットで利用できる広告カテゴリですが、すべてのデータファイルに含まれているわけではありません。 - 属性による絞り込みはデータに依存します:
geosite:geolocation-!cnや@を使うカテゴリ指定は、現在のファイルに該当するカテゴリや属性が含まれているか確認してください。名前だけで意味を判断しないでください。
ルールの優先順位:先に一致したルールで終了
ルールはrules配列の上から順に評価され、条件に一致した最初のルールに応じて接続がアウトバウンドへ渡されます。「完全ドメインがgeositeより常に優先される」「IPルールがドメインルールより常に優先される」といった仕組みはありません。条件を細かく指定しても、前にある範囲の広いルールに先に一致すると評価されません。
- 個別の例外を先に:特定の完全一致ドメインを必ずプロキシに通す場合は、
full:ルールを先に配置します。 - カテゴリルールはその後:プロキシまたはブロックに振り分けるドメインカテゴリと、一般的な直結カテゴリを続けて配置します。
- IPルールは目的に応じて配置:通常、LAN内アドレスは個別に直結させます。ただし、ドメインルールとの前後関係は名前解決の方針も考慮して決めてください。
- フォールバックは最後に:どのルールにも一致しない場合、通常は
outbounds配列の先頭のアウトバウンドが使われます。結果を明示したい場合は、対象ポート範囲をカバーするルールを最後に追加してください。
以下はrouting設定の例であり、そのまま実行できる完全なファイルではありません。proxy、direct、blockの3つのアウトバウンドがすでにあり、参照するカテゴリがデータファイルに含まれていることが前提です。実際のタグがクライアントの生成名と異なる場合は、先にタグを修正してください。
{
"routing": {
"domainStrategy": "IPOnDemand",
"rules": [
{
"type": "field",
"domain": ["full:api.example.com"],
"outboundTag": "proxy"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"port": "1-65535",
"outboundTag": "proxy"
}
]
}
}
この例では、まず完全一致ドメインの例外を処理し、その後にプライベートアドレスを処理します。IPOnDemandを使っているため、先行するIPルールの判定時に名前解決が行われることがあります。広告カテゴリをプライベートアドレスの後に置いているため、プライベートアドレスのルールが優先されます。業務上、広告カテゴリのブロックを優先する必要がある場合は、カーネルに自動で重要度を判断させるのではなく、ルールの順序を変更してください。
domainStrategy:名前解決したドメインをマッチ判定に使うタイミング
ルーティングのdomainStrategyは、ルーティング判定を補助するためにドメインをIPアドレスへ名前解決するかどうかを制御します。DNSサーバーの設定とは異なり、直結アウトバウンド内にある同名のオプションとも別の設定です。接続時に最初からドメイン名とIPアドレスのどちらが渡されるかによっても、利用できる条件が変わります。
AsIs
おすすめルーティング処理中にドメインを積極的にIPアドレスへ名前解決しません。ドメインを宛先とする通信には主にdomainやgeositeなどのルールが使われ、宛先が最初からIPアドレスの場合はIPルールにも一致します。まず動作が分かりやすいドメイン振り分けの基準を作るのに適しています。
おすすめ:ドメインルールを中心に使う場合、マッチ順を初めて確認する場合
IPIfNonMatch
ドメインが最初の判定でどのルールにも一致しない場合、名前解決してから再度判定します。ただし、前の段階ですでに一致する汎用のポートフォールバックルールがあると、最初の判定で処理が終了し、名前解決後の判定には進みません。
おすすめ:ドメインルールに一致しなかった後、IPカテゴリで判定する場合
IPOnDemand
ルールの判定中にIP条件が必要になると、その都度ドメインを名前解決します。前方にあるIPルールによって、後続のドメインカテゴリが判定されるかどうかが変わることがあるため、DNSの動作とルールの順序を合わせて設計してください。
おすすめ:ドメイン宛ての通信にIPカテゴリを使う必要がある場合
要点:名前解決のタイミングを決めてからフォールバックを設定
IPIfNonMatchを選ぶ場合、最初の判定で必ず一致する汎用のポートフォールバックを置きながら、後続のgeoipルールが有効になることを期待しないでください。先頭のアウトバウンドを既定の経路として使うか、ルールの配置を見直します。最終フォールバックより前にIP判定が必要な場合は、IPOnDemandと実際のDNS設定を検討してください。
アプリがIPアドレスへ直接接続する場合、カーネルにはdomainでマッチさせるためのドメイン名が最初から渡されません。対応している通信ではスニッフィングでドメイン名を取得できますが、すべてのプロトコルで使えるわけではなく、ドメインを完全に復元する仕組みでもありません。DNSクエリ自体の送信元は、カーネルのDNS設定、アウトバウンド、クライアントの動作モードを確認してください。ルーティング戦略の変更だけでは判断できません。
v2rayNの設定手順:編集後に実際の設定を確認
v2rayNのルーティング編集画面はバージョンによって変わります。デスクトップ版では通常、「設定」→「ルーティング設定」から開きます。現在の画面が異なる場合は、まず「ヘルプ」→「バージョン情報」でバージョンを確認し、該当する画面に従ってください。カーネル用JSON全体を、ドメイン一覧だけを受け付ける入力欄に貼り付けないでください。
-
現在の設定を記録
「ヘルプ」→「バージョン情報」でクライアントのバージョンを記録し、「設定」→「パラメーター設定」で使用中のカーネルとローカルの待ち受けポートを確認します。既存のルーティング設定をバックアップし、全般プロキシへ切り替えただけではなく、現在のモードがカスタムルーティングを使っていることを確認してください。
-
例外ルールを追加
「設定」→「ルーティング設定」を開き、現在使用中のルールセットを編集します。実際のサービスドメインを使った
full:条件を追加し、対象のアウトバウンドを選択して、範囲の広いカテゴリルールより前に配置します。 -
戦略を確認
ルーティング設定の
domainStrategyを確認し、ドメイン配列、IP配列、アウトバウンドタグも確認します。カテゴリルールを使う場合は、現在のカーネルが対応するgeosite・geoipデータファイルを読み込めるか確認してください。 -
再起動して検証
変更したルールセットを保存して有効にし、現在のカーネル接続を再起動します。実際に生成された設定でルールの順序を確認してから、新しいリクエストを送信し、ログを確認してください。確立済みの接続は、ルールを変更しても通常アウトバウンドが再選択されません。
v2rayNGはAndroidでXrayカーネルを使用し、v2flyNGはV2Flyカーネルを使用します。基本的なルール形式が似ていても、編集できるフィールド、インポート画面、データファイルの管理方法はクライアントによって異なる場合があります。移行時はフィールドの対応状況を確認してください。デスクトップクライアントの設定ファイル全体を、汎用のカーネル設定として使わないでください。
ルーティングが反映されない場合の確認:リクエスト経路、データ、ログ
「Webサイトが開く」ことから分かるのは接続できたということだけで、正しいアウトバウンドが使われた証明にはなりません。検証には、完全一致ドメイン、LAN内の宛先、カテゴリに含まれる宛先を1つずつ選び、それぞれ新しい接続を試してください。まず通信がカーネルに届いているかを確認し、次にマッチしたルールとアウトバウンドタグを見て、最後にDNSとカテゴリの範囲を確認します。
| 症状 | 優先して確認する項目 | 対処方法 |
|---|---|---|
| 完全一致ドメインの例外が直結される | 前にgeositeルールやポートルールが一致していないか | 該当するfullルールを範囲の広いルールより前に移動し、新しい接続で試す |
| ドメイン宛て通信にgeoipが効かない | AsIsまたはIPIfNonMatchでの名前解決条件 | 戦略を確認し、最初の判定でフォールバックに一致していないか確認する |
| 起動直後にエラーが出る | JSON、カテゴリ名、データファイル、アウトバウンドタグ | 追加したカテゴリ参照をいったん削除し、fullルール1件に絞って原因を調べる |
| ブラウザーとコマンドラインで結果が異なる | 同じプロキシ入口を通っているか、ローカルで名前解決していないか | 同じSOCKS入口を明示して、ドメイン指定とIP指定のリクエストを比較する |
| ルールを変更しても結果が変わらない | 有効なルールセット、カーネルの再起動、接続の再利用 | 変更後のルールセットが有効か確認し、既存の接続を閉じてからテストする |
ローカルにSOCKSインバウンドがあり、待ち受けポートが例の10808であることを確認できた場合は、以下のコマンドを使えます。socks5hを指定すると、curlはドメインをローカルで先に名前解決せず、プロキシ側へ渡します。これによりテスト経路の違いを減らせますが、カーネルが設定に従ってさらに名前解決する可能性はあります。
curl --proxy socks5h://127.0.0.1:10808 --head https://example.com/
- まず入口を確認:カーネルに届いていないリクエストには、カーネルのルーティングルールは適用されません。システムプロキシの設定も、すべてのアプリが従うとは限りません。
- 次にログを確認:一時的に適切なアクセスログ、または詳細ログを有効にし、宛先アドレス、インバウンド、アウトバウンドのタグを確認します。調査後は通常のログレベルに戻してください。
- 最後にルールを絞り込む:ドメイン条件を1つ、明示したアウトバウンドを1つだけ残して検証します。動作を確認したらカテゴリ条件やIP条件を1つずつ戻し、複数の要素を同時に変更しないようにしてください。
ログを共有する前に、サブスクリプションURL、ノードの認証情報、業務上のドメインなどの機密情報を隠してください。クライアント、カーネル、アウトバウンドの違いは用語集をご覧ください。接続の入口から設定を確認する場合は、クイックスタートから始めてください。