V2Rayのカスタムルーティング設定:domain・ip・geositeの書き方と優先順位

domainの前方一致、ip・geoip、geositeの書き方から、上から順に適用されるルールの優先順位、競合時の対処まで解説します。

この記事のポイント

ノードへの接続ができていて、通信の振り分けを調整したい方向けの記事です。V2Ray / Xrayの基本的なルーティング構造をもとに、ドメインのサフィックス・完全一致、IP範囲、分類データの違いを整理し、順を追って確認できるルール例を紹介します。さらに、v2rayNとv2rayNGで実際の適用結果を確認する方法も解説します。ルールを増やすことではなく、各リクエストの接続先を明確にし、検証できる状態にすることが重要です。

ルーティングの前に、リクエストがコアに届いているか確認

システムプロキシとルーティングルールは、処理する段階が異なります。システムプロキシは、プロキシに対応したアプリがリクエストをローカルポートへ送るかどうかを決めます。コアのルーティングは、コアに届いたリクエストの出力先を決めます。ブラウザーがシステムプロキシを使っていない場合や、アプリが直接接続している場合、geositeルールを正しく設定してもその接続には適用されません。TUNを使うと取り込める通信の範囲は広がりますが、有効化の有無でルールを上から順に照合する基本動作が変わるわけではありません。

アプリのリクエストローカルのインバウンド宛先の識別ルーティング照合アウトバウンド接続

v2rayNはデスクトップクライアントで、コアの設定を生成して起動します。v2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。クライアント画面のルーティングプリセットは、プロトコルそのものではありません。VMess、VLESSはプロキシ接続に使うプロトコルを表し、domain、ip、outboundTagはローカルでの通信振り分けを表します。ノードのプロトコルを変更しても、誤ったドメインルールが自動で修正されるわけではありません。

domainの書き方:サフィックス一致は文字列の前方一致ではない

ルール内のdomainは文字列の配列で、配列内のいずれかに一致すればドメイン条件を満たします。文字列に付けるdomain:、full:、regexp:は照合方法を示すプレフィックスです。特に誤解されやすいdomain:は、指定したドメインとそのサブドメインに一致します。「ドメインがこの文字列で始まる」という意味ではありません。

ルール文字列一致する範囲照合例
domain:example.testドメイン本体とサブドメインexample.test、api.example.testに一致。notexample.testには一致しない
full:api.example.test完全一致api.example.testに一致。img.api.example.testには一致しない
exampleプレフィックスなしの部分文字列一致another-example.testにも一致する可能性があり、範囲が広い
regexp:^api[.]example[.]test$正規表現による一致この書き方ではドメイン全体を指定
geosite:cnデータファイルのcn分類に一致実際の対象範囲は使用中のgeositeデータによって異なる

サービスとそのすべてのサブドメインを直接接続する場合は、domain:を使います。特定のエンドポイントだけを例外にする場合は、full:を使います。プレフィックスのない文字列は、対象範囲を把握したキーワードルールには適していますが、短い語を正確なドメインとして扱う用途には向きません。正規表現の構文はコアが採用する実装にも制限されます。複雑な式は事前に検証し、他のツールで使える機能がすべて使えるとは限らない点に注意してください。

{
  "type": "field",
  "domain": [
    "full:api.example.test",
    "domain:assets.example.test"
  ],
  "outboundTag": "direct"
}

このルールでは指定したエンドポイントや静的リソースのドメインだけが直接接続され、example.test全体が対象になるわけではありません。正規表現をJSONに記述する場合は、バックスラッシュのエスケープにも注意が必要です。\.でピリオドを表すなら、JSON文字列では\\.と記述します。上の表ではピリオドを[.]で表し、エスケープによる記述ミスを減らしています。

ipとgeoip:アドレス範囲・分類・条件の組み合わせ

ip配列には、単一アドレス、CIDRのネットワーク範囲、geoip:分類を指定できます。CIDRのスラッシュ以降の数字はネットワークプレフィックス長です。192.168.0.0/16はプライベートアドレスの範囲を表し、LAN内の1アドレスだけを指すものではありません。IPv6もfc00::/7のように指定できます。分類を使うには、コアがGeoIPデータを読み込める必要があります。

65,536
IPv4 /16ネットワークの総アドレス数
256
IPv4 /24ネットワークの総アドレス数
443
以下の複合ルールで指定する宛先ポート

ここに示したアドレス数はネットワーク内の全アドレス数であり、ホストに割り当て可能な数とは異なります。geoip:privateは、社内ネットワークや特殊なローカルアドレスの振り分けによく使われます。geoip:cnはデータファイルで中国と分類されたIP範囲を指します。中国語のWebサイトを意味するものではなく、ドメイン分類と完全に一致する保証もありません。1つのドメインが複数地域のCDNアドレスを使うこともあり、アドレスの分類は名前解決の結果によって変わります。

{
  "type": "field",
  "ip": ["192.168.0.0/16"],
  "port": "443",
  "network": "tcp",
  "outboundTag": "direct"
}

ポイント:同じルール内の複数フィールドは「AND」条件

上のルールでは、宛先IPが指定範囲内、宛先ポートが443、ネットワークがTCPという3つの条件をすべて満たした場合に直接接続します。「指定したドメインまたはIPを直接接続する」には、ルールを2つに分けてください。1つのルールにdomainとipを記述しても、どちらか一方を満たせばよい条件にはなりません。

geositeとdomainStrategy:ドメイン分類と名前解決のタイミング

geosite:cnはデータファイル内の分類名であり、オンライン検索の指示ではありません。コアが、その分類を含むgeosite.datを読み込める必要があります。データの提供元によって含まれるタグは異なる場合があり、ノードのサブスクリプションを更新しても分類ファイルが更新されるとは限りません。起動ログに「分類が存在しない」「データファイルを読み込めない」と表示された場合は、ルールの順序を検討する前にリソースを修復してください。

ドメインを優先し、追加の名前解決は行わない

項目
routing.domainStrategy
設定値
AsIs
ドメインを含むリクエスト
ドメインルールをそのまま照合
IP条件
ルーティング照合のためにドメインを積極的に名前解決しない

明示的なドメインルールを主な振り分け基準にしたい設定に適しています。ただし、アウトバウンド接続自体にドメインの名前解決が必要な場合はあります。

ドメインルールに一致しない場合、IPを追加で照合

項目
routing.domainStrategy
設定値
IPIfNonMatch
名前解決が行われる条件
最初のルーティング照合でどのルールにも一致しない
その後の処理
名前解決後、IPアドレスを使って再照合

ドメイン分類に加え、IP分類でも振り分けたい場合に適しています。ただし、最初の照合で不一致となる余地を残す必要があります。

よく使われるもう1つの値はIPOnDemandです。照合中にIPを必要とするルールがあると、名前解決が行われることがあります。そのため、後ろにあるドメイン例外より先に、前方のIPルールが一致する場合があります。IPIfNonMatchとの主な違いは、どのタイミングで名前解決が行われるかであり、どちらかが「より強い」ということではありません。

ここで説明しているのは、routing内のdomainStrategyです。DNSモジュールの問い合わせポリシーや、directアウトバウンドのドメインポリシーとは別の設定です。ルーティング時の名前解決は照合の手がかりを提供するもので、DNSリクエストが指定したアウトバウンドを通ることを単独で保証するものではありません。DNSサーバーへの到達性、名前解決の経路、アプリ独自の名前解決方法は別途確認してください。

ルールの優先順位:具体的な例外を先に、広い条件を後に

コアはrules配列を上から順に照合し、最初に条件を満たしたルールで経路を決定します。後ろのルールにより長いドメインがあっても、自動でそちらが優先されることはありません。「より具体的なルールを先にする」のは、順序を決めるための考え方であり、コアが自動計算する優先順位ではありません。ルール内のタグは、定義済みのアウトバウンドを指している必要があります。どのルールにも一致しない場合、通常はoutbounds配列の先頭が使われ、proxyという名前のタグが自動選択されるわけではありません。

  1. 用途別の例外:プロキシ経由または直接接続が必要な完全一致ドメイン、狭い範囲のサフィックス、特定のネットワークを先に記述します。
  2. LANの保護:次にプライベートアドレスを処理し、ローカル機器へのリクエストがデフォルトでプロキシに送られないようにします。社内ネットワークに特別な接続先が必要な場合は、より具体的な例外を先に記述してください。
  3. 分類ルール:geosite、geoipなど、広い範囲に適用される振り分け条件を配置します。
  4. フォールバック:最後に、残りの接続先を明示し、名前解決ポリシーの発動条件が変わらないか確認します。

以下はroutingの設定例です。api.example.testだけをプロキシ経由にし、同じ親ドメインへのその他のリクエストは直接接続します。プライベートアドレスと中国の分類も直接接続し、残りのTCP / UDPはプロキシ経由にします。ドメイン分類に含まれないリクエストもIPルールで照合できるよう、IPOnDemandを指定しています。この設定例は既存のコア設定に組み込むもので、単独で完全な設定ファイルとして起動することはできません。

{
  "routing": {
    "domainStrategy": "IPOnDemand",
    "rules": [
      {
        "type": "field",
        "domain": ["full:api.example.test"],
        "outboundTag": "proxy"
      },
      {
        "type": "field",
        "domain": ["domain:example.test"],
        "outboundTag": "direct"
      },
      {
        "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"
      }
    ]
  }
}
入力条件一致したルール接続先
ドメイン api.example.test1番目の完全一致ルールproxy
ドメイン img.example.test2番目のドメインサフィックスルールdirect
宛先IPが192.168.1.103番目のプライベートアドレスルールdirect
ドメインが前述の分類に含まれず、解決したIPがgeoip:cnに一致5番目のIP分類ルールdirect
上記に一致しないその他のTCPリクエスト6番目のフォールバックルールproxy

2番目のルールを1番目より前に移動すると、api.example.testは先に親ドメインのルールに一致し、直接接続に変わります。フォールバックを配列の先頭に移動すると、後続のルールはほぼ機能しなくなります。競合を調べる際は、適用したいルールだけを見るのではなく、実際の宛先をもとに1番目から順に照合してください。

クライアントでの設定:生成された設定を確認し、最小限のテストを行う

v2rayNでは「設定」→「ルーティング設定」から現在のルーティング設定を確認できます。メニュー名や場所はバージョンによって異なる場合があります。現在有効な設定を編集しているか確認してください。未選択の別プリセットを編集しても反映されません。「設定」→「パラメーター設定」でローカルの待ち受けポートも確認します。以下のテストではSOCKSの待ち受け先を127.0.0.1:10808としています。実際の値が異なる場合は置き換えてください。このポートがすべてのバージョンで固定のデフォルト値というわけではありません。

  1. 現在のルールをバックアップします。使用中のコア、ルーティングプリセット、ドメインポリシー、アウトバウンドタグを記録し、まずは識別しやすいドメイン例外を1つだけ追加します。
  2. 保存して設定を再適用します。クライアントの手順に従ってコアを再起動するか再接続し、設定を再生成します。編集画面で保存しただけでは、実行中の設定に反映されていない場合があります。
  3. 実行ログを確認します。まず、JSONの解析エラー、分類データの不足、存在しないアウトバウンドタグ、待ち受けポートの競合を確認します。必要に応じて一時的にログレベルを上げ、テスト後に元へ戻してください。
  4. 実際の宛先と照らし合わせます。接続ログやアクセスログで、宛先ドメイン、宛先IP、アウトバウンドタグを確認します。ログの形式はコアとログレベルによって異なります。
  5. 確認できてから対象範囲を広げます。1つの例外ルールが正しく適用されることを確認してから、geosite / geoipの分類やフォールバックを追加します。複数の項目を一度に変更すると、原因を特定しにくくなります。
curl --socks5-hostname 127.0.0.1:10808 \
  --connect-timeout 10 \
  --max-time 20 \
  -I https://v2rayworld.com/

--socks5-hostnameは宛先ドメインをSOCKS側に渡すため、ドメインルールの検証に適しています。--socks5は通常ローカルで先に名前解決するため、コアにはIPアドレスが渡される可能性があります。接続タイムアウト10秒、全体のタイムアウト20秒は、テストの待ち時間を制限するための設定であり、遅延や速度の測定値ではありません。HTTPリクエストが成功しても、そのリクエストが指定ルールに一致したことの証明にはなりません。アウトバウンドの記録も確認してください。

v2rayNGでは、まず現在のルーティングモードを確認し、「設定」内にある対応するルーティング設定画面を開きます。メニュー階層はバージョンによって異なる場合があります。AndroidのVPNによる通信の取り込み範囲は、アプリごとのプロキシ設定にも左右されるため、テストするブラウザーが対象に含まれていることを確認してください。v2flyNGでは、コアの機能とリソースファイルを実際のV2Fly設定に基づいて確認します。Xray専用のフィールドをそのまま流用しないでください。この記事で扱う基本的なフィールドルールも、最終的には使用中のコアが正常に起動するかどうかで判断してください。

よくある問題:ドメインが一致しない、分類エラー、ルールの上書き

ドメインルールは正しいのに、なぜIPルールが適用される?

まず、インバウンドがドメインとIPのどちらを受け取っているか確認します。前述の--socks5-hostnameを使ったテストと比較してください。アプリ側ですでに名前解決されている場合、ドメインルールを照合するための情報がないことがあります。スニッフィングで一部のHTTP / TLS通信からドメインを抽出できる場合もありますが、すべての接続で使えるわけではなく、あらゆる通信を安定してカバーする方法ではありません。

geosite:cnを保存すると起動できなくなる場合の対処法

コアのログにgeositeファイルが見つからない、またはcn分類が存在しないというエラーが出ていないか確認します。リソースファイルの場所と読み取り権限、クライアントが参照するデータの提供元も確認してください。まずバックアップしたルールに戻してコアを起動し、クライアントに用意されたリソース更新機能でデータを更新します。リソースの問題を隠すために、ルーティング設定をすべて削除しないでください。

domainとipを追加したら、直接接続の範囲が狭くなったのはなぜ?

2種類の条件を同じフィールドルールに記述していないか確認してください。「ドメインに一致する、またはアドレスに一致する」条件にするには、ルールを2つに分け、同じアウトバウンドをそれぞれ指定します。1つのルール内の複数フィールドはすべて同時に満たす必要があります。また、ドメインリクエストがIP条件を満たすかどうかは、名前解決ポリシーにも左右されます。

コア設定を変更したのに、次の接続時に元に戻るのはなぜ?

クライアントが起動時に一時的なコア設定を再生成している可能性があります。実行中の一時ファイルだけを編集せず、現在のルーティングプリセット、またはクライアントが対応するカスタム設定画面で変更してください。保存後に設定を再適用し、生成されたルールの順序を確認して、プリセットのルールに上書きされていないか確かめます。

最終確認は、リクエストがコアに届いているか、宛先にドメイン情報が含まれているか、分類リソースを読み込めるか、ルールが意図した順序になっているか、アウトバウンドタグが有効か、の順に行います。ブラウザーが既存の接続を再利用することがあるため、設定変更後は新しいリクエストを送るか、テスト用アプリを再起動してください。一致結果を確認したら、一般的なドメイン、LAN内のIP、未分類の宛先をそれぞれテストします。1つのWebサイトだけで全体が正しく振り分けられていると判断しないでください。

v2rayNをダウンロード対応プラットフォームとインストーラーを確認