V2RayとXrayのルーティングモジュールは、プロトコル接続を確立するものではありません。コアに到達した接続情報を受け取り、宛先ドメイン、宛先IP、ポート、ネットワーク種別、入口タグに基づいて、どのアウトバウンドへ渡すかを決定します。サブスクリプションのVMessやVLESSノードが解決するのは「どう接続するか」、ルーティングルールが解決するのは「このリクエストをどの出口から出すか」であり、両者は別の階層にあります。
よくある構成は、ローカルネットワークと普段使う直接接続用ドメインを direct に送り、それ以外のリクエストを proxy へ、広告ドメインを block へ振り分ける方法です。ルール自体がノードの帯域を増やすわけではありません。適切に設定することで不要なプロキシ通信を減らし、プライベートアドレス、LAN機器、指定サイトを想定した出口から接続できます。
サブスクリプションを正常に読み込める状態で、さらに振り分け設定を行いたい方に向けた記事です。domain・ip・geositeのマッチング範囲、同一ルール内の組み合わせ、ルール配列の優先順位、v2rayNで設定を保存・検証する方法を説明します。
まず、リクエストがルーティング判定に入る流れを理解する
アプリがアクセスを開始すると、リクエストはローカルのHTTP、SOCKS、またはTUNの入口に入ります。コアはスニッフィング結果、宛先アドレス、現在の domainStrategy に基づいてマッチング可能な情報を集め、その後 routing.rules を上から順に確認します。すべての条件を満たした最初のルールが直ちにアウトバウンドを決定し、後続のルールは評価されません。
フィールドルールでは通常 type: "field" を使用します。このルールには domain、ip、port、network、inboundTag などの条件を含め、outboundTag でアウトバウンドを指定できます。未設定のフィールドは判定に使われず、設定した異なるフィールドは通常すべて満たす必要があります。
- 異なるルール間:配列の順番どおり上から確認し、先にマッチしたルールが適用されます。
- 同じフィールドの複数の値:通常は「または」の関係です。たとえば2つのCIDRのいずれかに一致すればマッチします。
- 同一ルール内の異なるフィールド:通常は「かつ」の関係です。たとえばドメインとTCPポートを同時に制限できます。
- どのルールにも一致しない場合:コア設定のデフォルトアウトバウンドに入り、通常はアウトバウンド一覧の最初にある利用可能な項目が使われます。
domain・full・regexp・geositeの記述方法
domain 配列では複数のプレフィックスを使用できます。プレフィックスなしの通常の文字列は部分一致となり、想定より広い範囲にマッチすることがあります。domain: は指定ドメインとそのサブドメイン、full: は完全一致、regexp: は正規表現を使います。geosite: はコアに付属するドメイン分類データを参照します。
domain:example.com
- マッチング
- ドメインとサブドメイン
- マッチする例
- www.example.com
- マッチしない例
- example.com.test
サイト全体を振り分けたい場合に適しています。
full:api.example.com
- マッチング
- 完全なドメイン名
- マッチする例
- api.example.com
- マッチしない例
- www.api.example.com
固定された単一のAPIドメインだけを処理する場合に適しています。
regexp:正規表現
- マッチング
- 正規表現の結果
- 柔軟性
- 高い
- メンテナンスコスト
- 比較的高い
通常のドメインルールで表現できない場合だけ使用します。
geosite:cn
- データ種別
- ドメイン分類
- マッチング対象
- ドメイン
- よく使う出口
- direct
分類内容は、ローカルルールデータのバージョンによって変わります。
たとえば domain:example.com は example.com と cdn.example.com にマッチしますが、example.com.test はこのドメインのサブドメインとして扱いません。一方、example.com と直接書くと部分一致になるため、この文字列を含む別のドメインまで対象になる可能性があります。カスタムルールでは、プレフィックス付きの明確な記法を優先してください。
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:static.example.com",
"geosite:category-ads-all"
],
"outboundTag": "block"
}
geosite は domain 配列に記述しますが、オンライン検索サービスではありません。コアがローカルのドメイン分類データを読み込み、その分類項目をマッチングに利用します。新しいドメインが現在のデータバージョンにまだ含まれていない場合は、分類ルールの前に full: または domain: のカスタムルールを追加すればよく、分類データの更新を待つ必要はありません。
| 記法 | マッチング範囲 | 適した用途 |
|---|---|---|
キーワード |
ドメイン文字列にその内容が含まれる | 共通する文字列を持つドメイン群を素早く対象にする |
domain: |
指定ドメインとそのサブドメイン | サイト単位で出口を設定する |
full: |
完全なドメイン名のみ | 単一のホスト名を正確に処理する |
regexp: |
正規表現に一致するドメイン | 複雑な命名パターンを処理する |
geosite: |
ローカルのドメイン分類セット | よく使うドメイン群をまとめて設定する |
ip・CIDRとdomainStrategyの組み合わせ方
ip フィールドは宛先IPにマッチし、単一アドレス、CIDRのネットワーク範囲、geoip: 分類を指定できます。よく使う geoip:private はプライベートネットワークアドレスの識別に利用でき、プロキシルールより前に置いて直接接続へ送ると、ルーターの管理画面、LANストレージ、本機のサービスが遠隔の出口へ送られるのを防げます。
上記の300件のテストサンプルは、100件のドメイン、100件のプライベートまたは予約アドレス、100件のパブリックアドレスで構成されています。ルールログを有効にして1件ずつ接続し、記録されたアウトバウンドタグを確認します。このテストはルールの順序とマッチング範囲を検証するもので、通信速度を示すものではありません。ポート値はv2rayNでよく使われる初期値です。端末側の設定を変更している場合は、現在のクライアントに表示される値を優先してください。
{
"type": "field",
"ip": [
"geoip:private",
"10.20.0.0/16",
"192.168.50.10"
],
"outboundTag": "direct"
}
ドメインリクエストがIPルールの対象になるかどうかは domainStrategy に左右されます。AsIs は元のドメインを優先してマッチングし、IPルールのためにドメインを積極的に解決しません。IPIfNonMatch はまずドメインルールを確認し、マッチしなければIPを解決してIPルールを続けて確認します。IPOnDemand は宛先IPが必要なルールに遭遇すると、より早い段階で名前解決を行います。
AsIs:名前解決が少なく、domainとgeositeを中心に使う設定に適しています。IPIfNonMatch:ドメイン、次にIPの順で確認します。geositeとgeoipを併用する場合の一般的な開始点に適しています。IPOnDemand:より早く名前解決を行う場合があり、宛先IPに依存する細かなルールに適しています。
ルールの優先順位:最初に完全一致したルールを適用
ルーティングルールには独立した数値の優先度フィールドはなく、配列内の位置がそのまま優先順位になります。コアは最初のルールから確認し、あるルールの条件がすべて成立すると、そのルールが指定したアウトバウンドを使用します。範囲の広いルールを先に書くと、後ろに置いたより具体的な例外ルールが隠れてしまいます。
- 最も具体的な単一ドメイン、単一IP、特殊な例外を先頭に置きます。
- 広告やプライベートアドレスなど、明確な分類ルールを一般的な地域ルールより前に置きます。
geosite:cn、geoip:cnなどの大きな集合は中ほどに置きます。- すべてのTCP、UDP、その他のリクエストを対象にするフォールバックルールは最後に置きます。
以下の順序では、まず広告ドメインを処理し、次にプライベートアドレスを直接接続へ通し、その後よく使う直接接続用ドメインと対応するIPを確認し、最後に残ったTCP・UDPトラフィックをプロキシへ送ります。geosite:cn を広告ルールより前に置くと、分類内で直接接続の条件も満たす広告ドメインが先に direct へ入り、後続のブロックルールが実行されない可能性があります。
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"full:intranet.example.com",
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": ["geoip:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
1つのルールに domain と port を同時に記述した場合、リクエストはドメイン条件とポート条件の両方を満たす必要があります。たとえばドメインに一致しても宛先ポートが 443 でなければ、そのルールはスキップされます。ドメインルールとポートルールを別々に適用したい場合は、同じオブジェクトに詰め込まず、独立した2つのルールに分けてください。
結論:「例外、分類、フォールバック」の順に並べる
まず正確に制御したい例外を書き、次にgeositeとgeoipの分類を置き、最後に汎用プロキシルールを1つ残します。ルールを追加するたびに、前にある広範囲の条件に先取りされないか確認してください。
v2rayNでルールを入力・保存・検証する
v2rayN 7.xでは、メイン画面から「設定」→「ルーティング設定」を開いてルーティング設定を確認できます。マイナーバージョンによってボタンの位置は多少異なる場合がありますが、基本操作はルーティング設定を新規作成または編集し、ルールの順序を調整して保存した後、現在のルーティングとして選択することです。ローカルの入口ポートを確認する場合は、「設定」→「パラメーター設定」でSOCKSとHTTPの待受値を確認できます。
基本の直接接続
- domainStrategy
- IPIfNonMatch
- ドメイン分類
- geosite:cn
- IP分類
- geoip:cn
- アウトバウンド
- direct
ドメインルールとIPルールを併用する開始設定に適しています。
LANを許可
- IP分類
- geoip:private
- ルールの位置
- プロキシルールより前
- アウトバウンド
- direct
- 検証対象
- 192.168.1.1
ルーターの管理画面やLANサービスへのアクセスに使用します。
- まず現在利用できる設定を記録し、
proxy、direct、blockなどのアウトバウンドタグを確認します。 - 「設定」→「ルーティング設定」で新しい設定を作成し、現在使用中のルールを直接上書きしないようにします。
- まず
geoip:privateの直接接続ルールを追加し、その後テストするdomain、geosite、CIDRの項目を追加します。 - 保存してそのルーティング設定を選択し、現在のサーバーに再接続してコアに新しい設定を読み込ませます。
- ログパネルを開き、完全一致するドメイン、サブドメイン、LANアドレスをそれぞれ1つずつアクセスして、アウトバウンドタグを確認します。
テストでは、ウェブページが開くかどうかだけで判断しないでください。直接接続でもプロキシでもアクセスできる場合があります。より確実なのは、コアのログで宛先アドレスとアウトバウンドタグを確認する方法です。またはテスト用ドメインのルールを一時的に block へ向け、リクエストがルールに捕捉されたことを確認してから、目的の出口へ戻します。テストが終わったら、すぐに正式な設定へ戻してください。
よくある誤マッチと対処法
ルーティングの問題は、プロトコル接続の失敗ではなく、マッチング対象、名前解決の方針、ルールの順序が想定と異なることが原因である場合が多いです。切り分けでは、まずノード自体が利用できることを確認し、次にリクエストがどのアウトバウンドへ入ったかを確認してください。VMessやVLESSのパラメーターとルーティングルールを何度も交互に変更するのは避けます。
domainルールを書いたのに、なぜプロキシ経由になる?
まず記述が domain:example.com になっているか確認し、次に汎用プロキシルールより前に配置されているか確認します。保存後、現在のサーバーに再接続し、ログでコアが新しいルーティング設定を読み込んでいるか確認してください。
geosite:cnに一致した場合、geoip:cnも続けて確認される?
いいえ。現在のリクエストが前のgeositeルールのすべての条件に一致してアウトバウンドが決まると、後続のgeoipルールは確認されません。ドメインルールに一致せず、かつ設定された方針で名前解決が許可されている場合に限り、IP判定へ進む可能性があります。
LANアドレスがプロキシへ送られる場合は?
汎用プロキシルールの前に geoip:private を追加し、direct に向けます。特殊な内部ネットワーク範囲を使う場合は、10.20.0.0/16 のように明示的なCIDRも追加してください。
同じドメインが直接接続になったり、プロキシ経由になったりするのはなぜ?
geoipに大きく依存していないか、DNSが異なるアドレスを返していないか確認します。結果を固定したい場合は full: または domain: ルールに変更し、具体的なルールを分類ルールより前に置いてください。
ルールを保存してもまったく変化しない場合は?
新しい設定が一覧に保存されただけでなく、現在のルーティングとして選択されていることを確認し、その後サーバーに再接続します。ログに存在しないアウトバウンドタグが表示される場合は、ルール内の outboundTag を修正してください。
保守しやすいルーティング設定は、3つの問いに答えられる状態であるべきです。対象をどのフィールドでマッチさせるのか、なぜこの位置に置くのか、一致した後どのアウトバウンドへ入るのか。これらを軸に確認すれば、domain・ip・geositeを組み合わせた設定も整理された状態を保てます。問題が起きたときは、最初のルールから順番に検証するほうが、ノードを何度も切り替えるより早く原因を見つけられることが多いでしょう。
最終確認:ページの見た目よりログ結果を重視する
設定後は、完全一致ドメイン、サブドメイン、プライベートIP、パブリックIPの4種類を少なくとも検証し、それぞれで一致したアウトバウンドタグを記録してください。4種類すべてが想定どおりなら、ルールの範囲と優先順位が正しく設定されていると判断できます。