この記事は、ノードをインポートでき、直結・プロキシ・ブロックの範囲をさらに細かく制御したい方に適しています。ドメインとIP条件の実際のマッチ方法、geositeとgeoipデータセットの役割、ルール競合時の適用順、既存の出力タグに合わせて調整できるrouting設定を解説します。
まずroutingのマッチング処理を理解する
V2Rayのルーティングは、VMessやVLESSなどのノードプロトコル自体を変更しません。コアがリクエストを受け取った後、どのoutboundに渡すかを処理し、接続をプロキシ、直結、ブロック、その他の定義済み出口のどれに振り分けるかを決めます。結果はリクエストの宛先、ルールの順序、出力タグに左右されるため、ノードに接続できても振り分けルールが正しいとは限りません。
リクエストは通常、ローカルのSOCKS、HTTP、または透過プロキシの入口で受け付けられ、routing.rulesへ進みます。コアは配列の先頭ルールから確認し、条件を満たす最初のルールで判定を止め、そのルールのoutboundTagまたはbalancerTagを使用します。後ろにある、より具体的なルールも、先行ルールにマッチした後は上書きできません。
1つのルール内にある複数のフィールドは、通常「すべて満たす」関係です。たとえば network: "tcp" と port: "443" を同時に指定した場合、TCP 443の接続だけにマッチします。一方、フィールド内の配列は「いずれか1つにマッチすればよい」条件です。domain配列に3つのドメイン条件があれば、そのうち1つに該当するだけでフィールドの条件を満たします。
- ルール間:配列の順番に従って上から確認し、先にマッチしたルールを適用します。
- 異なるフィールド:domain、network、portなどの条件をすべて満たす必要があります。
- 同じフィールドの配列:配列内の複数の値は、通常いずれか1つにマッチすれば適用されます。
- 最終的なoutbound:outboundTagは、outboundsに存在するtagと完全に一致していなければなりません。
domain・full・regexp・geositeの記述方法
domainフィールドは文字列配列を受け取りますが、配列内の文字列には複数のマッチ構文を使用できます。通常の文字列はドメインの部分一致に使い、domain: は指定ドメインとそのサブドメイン、full: は完全一致、regexp: は正規表現、geosite: は外部のドメイン分類データを参照します。日常的な振り分けではdomain、full、geositeを優先し、既存の構文で範囲を表現できない場合に限ってregexpを検討します。
完全一致とサフィックス一致
- 完全なドメイン名
- full:api.example.com
- ドメインとサブドメイン
- domain:example.com
- 通常の文字列
- example
- 正規表現
- regexp:^.+\.example\.com$
固定のホスト名が分かっている場合はfull、サイト全体とサブドメインを対象にする場合はdomainを優先します。
分類データによるマッチング
- 中国本土でよく使われるドメイン
- geosite:cn
- 広告カテゴリ
- geosite:category-ads-all
- 中国本土以外のカテゴリ
- geosite:geolocation-!cn
- データソース
- コアが読み込むデータファイル
利用できるカテゴリ名は、現在のコアが実際に読み込んでいるデータファイルとそのバージョンによって決まります。
domain:example.com は example.com と www.example.com を対象にでき、サイト全体のポリシーに適しています。一方、full:example.com はサブドメインを自動的に対象にせず、1つの固定ホスト名だけを処理する場合に向いています。通常の文字列は範囲が広く、同じ文字列を含む別サイトまで意図せずマッチする可能性があるため、短すぎる単語をルールに使うことはおすすめしません。
{
"type": "field",
"domain": [
"full:api.example.com",
"domain:static.example.com",
"geosite:cn"
],
"outboundTag": "direct"
}
geositeは、リアルタイムでインターネット検索を行うサービスではなく、コアが読み込むローカルのドメイン分類データです。クライアントやコアを更新すると、分類内容がデータファイルによって変わる場合があります。ログにgeositeカテゴリが見つからないと表示された場合は、まずカテゴリ名の存在を確認し、次にクライアントがV2RayとXrayのどちらのコアを使用しているかを確認してください。ルール順を何度も変更して、データ不足を隠そうとしてはいけません。
ip・CIDR・geoipのマッチ条件
ipフィールドは接続先のIPアドレスを判定し、単一のアドレス、CIDRネットワーク、または geoip: カテゴリを指定できます。よく使われる記法には 127.0.0.0/8、192.168.0.0/16、geoip:private、geoip:cn があります。CIDRのサフィックスはネットワークプレフィックス長を示し、1桁間違えるだけでマッチ範囲が広がったり狭くなったりします。
アプリがIPアドレスへ直接リクエストする場合、コアはipルールですぐに判定できます。ドメイン名でリクエストする場合、ルーティングのマッチングで名前解決を行うかどうかはrouting.domainStrategyによって決まります。AsIs は主に元のドメイン名を使って判定し、IPIfNonMatch はドメインルールで結果が出なかった場合に名前解決してIPマッチングを続行します。IPOnDemand は、マッチング中にIP条件が必要になったときに名前解決を行う場合があります。
| 記法 | マッチ範囲 | 主な用途 |
|---|---|---|
127.0.0.0/8 |
ローカルループバックアドレス帯 | ローカルサービスをリモートプロキシへ送らない |
192.168.0.0/16 |
一般的なLANアドレス帯 | ルーター、ストレージ、社内ネットワークサービスへのアクセス |
geoip:private |
データファイルで定義されたプライベートアドレス | 複数のプライベートネットワークをまとめて処理 |
geoip:cn |
データファイルで中国本土向けに分類されたアドレス | ドメイン振り分けを補う条件として使用 |
結論:ドメインルールを主軸に、IPルールで補完する
まずfull、domain、geositeで対象範囲を明確にし、geoip:private、geoip:cn、または明示的なCIDRでIPアドレスへ直接アクセスする接続を処理します。不要なDNS名前解決を減らせるうえ、ログからリクエストが特定のoutboundにマッチした理由も確認しやすくなります。
IPIfNonMatch を使う場合は、名前解決の経路にも注意が必要です。ルーティング判定で得たIPと、実際のリモート接続で使われる名前解決結果は、できるだけ一致させてください。内蔵DNS、システムDNS、リモートDNSで異なる結果が返ると、同じドメインでも時間によって別のアドレス分類に入る可能性があります。振り分けが不定期に変わる場合は、dns設定、domainStrategy、コアログに記録された宛先アドレスを併せて確認します。
ルールの優先順位とよくある競合
V2Rayは、どのルールが「より具体的か」を自動判定しません。配列の前にあるルールほど優先されるため、「例外を先に、広い範囲を後に、最後にフォールバック」という順で構成します。たとえば、あるドメインをプロキシ経由にしたいのに geosite:cn にも含まれる場合は、そのドメインのプロキシルールを先に書き、その後にgeositeの直結ルールを置く必要があります。
- まず、必ずブロックする、または個別に処理する必要がある正確なルールを置きます。たとえば
full:ドメインです。 - 次に、LANとプライベートアドレスの直結ルールを置き、ローカル機器へのリクエストがプロキシへ送られないようにします。
- 続いて、用途別のドメイングループ、geositeカテゴリ、指定ネットワークを配置します。
- 最後に、対象範囲の広いプロキシまたは直結のフォールバックルールを置きます。
- 変更後はコアログでドメイン、IP、TCP、UDPのリクエストを1つずつ確認します。
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"full:service.example.com"
],
"outboundTag": "proxy"
},
{
"type": "field",
"ip": [
"geoip:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
上の1つ目のルールは、geositeの直結範囲に対する例外なので先頭に置いています。2つ目はLANアクセスを保護し、3つ目と4つ目はそれぞれ中国本土向けのドメインとアドレスを処理します。最後のルールは、残りのTCP・UDPリクエストをproxyへ渡します。実際に使用する前に、outboundsに proxy と direct の2つのタグが存在することを必ず確認してください。存在しないoutboundを参照すると、コアの起動に失敗します。
v2rayNでルーティングを設定・検証する
v2rayNのメニュー名はバージョンによって変わる場合があります。一般的な入口は「設定」→「ルーティング設定」です。カスタムルールセットを作成したら、現在のルールセットが選択されていることを確認してから設定を保存し、使用中のコアを再起動します。完全なカスタム設定ファイルを使う場合は、ノード切り替えやサブスクリプション更新時にクライアントが設定を再生成するか確認し、手動編集が上書きされないようにしてください。
| 確認項目 | 具体的な操作 | 期待される結果 |
|---|---|---|
| ローカル入口 | 「設定」→「パラメータ設定」でSOCKS 10808、HTTP 10809を確認 | ブラウザまたはテストプログラムが実際に有効なポートへ接続する |
| outboundタグ | ルール内のproxy、directが既存のoutbound tagに対応しているか確認 | コアの起動ログに不明なoutboundタグが表示されない |
| ルールの順序 | 正確なドメイン、geositeドメイン、直接IP、LANアドレスを個別にテスト | 4種類のリクエストが想定したoutboundにマッチする |
| UDPリクエスト | フォールバックルールにudpが含まれていることを確認し、ノードと入口の関連設定を確認 | DNSなどのUDPトラフィックが取りこぼされない |
検証では、ウェブページが開くかどうかだけを見ないでください。コアログを有効にし、少なくとも6つの対象を用意します。正確なプロキシ対象ドメイン、geositeの直結対象ドメイン、中国本土向けIP、LANのIP、ブロック対象ドメイン、そして前のルールに該当しないドメインです。1つずつリクエストして、マッチしたoutboundTagを記録します。ルール番号を確認できる場合は、それも併せて記録してください。
結論:毎回変更する条件は1グループだけにする
まずdomainStrategyとoutboundタグを固定し、そのうえで1つのルールを移動するか、1つのマッチ項目だけを変更します。DNS、geositeカテゴリ、ルール順を同時に変更すると、ログ結果を単一の原因と結び付けられず、かえって調査に時間がかかります。
- ルールを変更したら設定を保存し、設定画面を閉じるだけでなく、使用中のコアを再起動します。
- ノードを切り替えた後にもう一度ログを確認し、クライアントがデフォルトのルーティングへ戻していないことを確認します。
- サブスクリプション更新がノードデータだけを更新する場合でも、すべてのカスタム項目が保持されるとは限りません。
- ルールが増えたら用途別にグループ分けして記録し、意味が正反対の広範なルールが2つ存在しないようにします。
よくある問題と調査の順番
ルーティングの問題は、特定のサイトが誤った出口を使う、LAN機器にアクセスできない、保存しても変化しない、コアが起動に失敗するといった形で現れます。調査ではまず設定が実際に読み込まれているか確認し、次にタグと順序、最後にDNSの名前解決と分類データを確認します。この順番なら、設定が反映されていないといった基本的な問題を先に切り分けられます。
domainルールを書いたのに、なぜ前のgeositeにマッチするのですか?
正確なdomainまたはfullルールをgeositeルールの前へ移動し、保存してからコアを再起動します。ルールは具体性の順に自動整列されないため、先にマッチしたgeositeで今回の判定はすでに終了しています。
IPでは振り分けられるのに、ドメイン名ではgeoipにマッチしないのはなぜですか?
routing.domainStrategyを確認します。AsIsでは、すべてのIPルールのためにドメインリクエストを一律で名前解決することはありません。ドメインルールにマッチしなかった後でIP判定を試したい場合は、IPIfNonMatchの利用を検討できます。
geositeを追加したらコアの起動エラーが出た場合はどうすればよいですか?
まず追加したカテゴリを削除して起動できる状態に戻し、カテゴリ名と現在のコアが読み込むデータファイルを確認します。カテゴリが存在しない、またはデータファイルを読み込めない場合、ルール順を変えてもエラーは解決しません。
LANアドレスがプロキシへ送られるのはなぜですか?
広範なプロキシルールの前にgeoip:privateを追加するか、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16を明示的に追加します。その後、ルーターやLANサービスのアドレスがdirectにマッチするかテストします。
ルールは正しそうなのに、保存しても変化がありません。
現在有効になっているのが編集したばかりのルーティング設定か確認し、その後コアを再起動して生成された設定を確認します。ノード切り替え後にルールが消える場合は、クライアントがroutingセクションを再生成していないか確認してください。
保守しやすい振り分け設定では、大量の重複ルールを積み重ねる必要はありません。正確な例外、プライベートアドレス、主要なgeositeまたはgeoipカテゴリ、最後のフォールバックを残し、ログを見ながら本当に必要な項目だけを追加します。新しいルールには用途、対象outbound、検証結果を記録しておくと、データファイルの更新やコアの変更時にも、どのルールがまだ必要かすぐ判断できます。
- まず読み込みを確認:コアの起動ログと、生成後のrouting設定を確認します。
- 次にタグを確認:outboundTagの綴り、大文字・小文字、対応するoutboundを確認します。
- 続いて順序を確認:正確な例外を広範なカテゴリより前に置きます。
- 最後に名前解決を確認:domainStrategy、DNS設定、実際の宛先IPを照らし合わせて判断します。