ノードへの接続ができており、DNSやルーティングルールを調整したい方向けの記事です。Xrayコアの従来型JSON設定を例に、DNSサーバーの選択、応答の絞り込み、接続の出口という3つの要素を分けて説明し、既存設定に追加できる設定例と確認手順を紹介します。V2Flyで各項目が使えるかどうかは、クライアント名だけで判断せず、実際に使うコアのバージョンで確認してください。
DNSの名前解決と接続の出口を区別する
DNSの振り分けは「どのDNSサーバーに問い合わせるか」を決め、ルーティングの振り分けは「どのアウトバウンドから接続するか」を決めます。両者は関係しますが、同じ設定ではありません。ドメインに中国国内のDNSサーバーを指定しても、そのドメインへの接続が必ず直接接続になるわけではありません。接続にプロキシを選んでも、それ以前にアプリが行ったDNS問い合わせまでプロキシ経由になるとは限りません。
この流れは、この記事で使う routing.domainStrategy: "IPIfNonMatch" に対応します。まずドメインルールを確認し、一致しない場合に限り、IPルールの判定に必要なアドレスを解決します。ドメインルールに一致した場合、ルーティング処理で内蔵DNSが使われないこともあります。その後に名前解決が行われるかは、選択されたアウトバウンドの処理方法によります。そのため、「DNSログが見当たらない」だけで設定が反映されていないとは判断できません。
- アプリがドメイン名をコアに渡す場合:ドメインルールで直接判定でき、コアの内蔵DNSで名前解決される可能性もあります。
- アプリがIPアドレスをコアに渡す場合:元のドメイン名がすでに失われている可能性があり、
geositeだけでは復元できません。 - アプリが独自に暗号化DNSを使う場合:問い合わせがコアの
dns設定を経由しないことがあります。アプリ側の設定も個別に確認してください。 - システムプロキシだけを有効にした場合:通常はプロキシに対応したアプリがプロキシを使うだけで、システム全体のDNS通信がすべて引き継がれるわけではありません。
servers、domains、expectIPs
dns.serversはDNSサーバーの一覧で、サーバーアドレスのほか、条件付きのオブジェクトも指定できます。オブジェクト内のdomainsは、優先的に照合するドメインを指定します。expectIPsは、そのサーバーから返されたアドレスが想定範囲に含まれるかを判定します。前者は問い合わせ先の選択、後者は応答の絞り込みに使うため、互いの代わりにはなりません。
中国国内向けDNSサーバー
- address
223.5.5.5- domains
geosite:cn- expectIPs
geoip:cn- skipFallback
true
中国国内のドメインを優先的に処理し、他のドメイン向けの一般的なフォールバック候補から除外します。
汎用フォールバックDNSサーバー
- address
https://1.1.1.1/dns-query- 通信方式
- HTTPS
- domains
- 指定なし
- アドレスファミリー
- グローバル設定の
UseIPv4を継承
専用ルールに一致しない問い合わせや、専用サーバーの応答が条件を満たさなかった問い合わせを処理します。
skipFallback: trueは「このサーバーを汎用フォールバックに使わない」という意味で、「このサーバーに一致した後はフォールバックを禁止する」という意味ではありません。中国国内のドメインへの応答がexpectIPsを満たさない場合、この例では別のフォールバックDNSサーバーが引き続き試されます。2つの意味を混同すると、実際の問い合わせ先を誤って判断する原因になります。
geosite:cnはドメイン分類データ、geoip:cnはIPアドレス分類データに基づきます。リアルタイムの位置情報サービスでも、ウェブページの表示言語で地域を判定する仕組みでもありません。中国国内向けサービスが中国国外のIPアドレスを使っている場合や、広域CDNの利用、分類データの更新遅れなどにより、厳しいアドレス条件が有効な応答を除外することがあります。
- 特定のドメインを完全一致で指定するには、
full:example.comを使えます。 domain:example.comは、指定したドメインとそのサブドメインに一致します。geosite:cnとgeoip:cnを使う前に、実行中のコアが対応するデータファイルを読み込めることを確認してください。expectIPsは分類に基づく絞り込みであり、応答が正しいことを証明するものではありません。返されたアドレスが特定地域に属するというだけで、正しい応答だとは判断できません。
DNSとルーティングの設定例を統合する
以下のJSONは、ノード設定全体ではありません。既存のoutboundsに、直接接続用のdirectと、接続確認済みのプロキシ用proxyという2つのタグがあることを前提としています。統合するときは既存のdnsとroutingを更新し、同じオブジェクト内でこれらのキーを重複して定義しないでください。
{
"dns": {
"queryStrategy": "UseIPv4",
"servers": [
{
"address": "223.5.5.5",
"domains": [
"geosite:cn"
],
"expectIPs": [
"geoip:cn"
],
"skipFallback": true
},
"https://1.1.1.1/dns-query"
]
},
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": [
"223.5.5.5/32"
],
"port": "53",
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"1.1.1.1/32"
],
"port": "443",
"outboundTag": "proxy"
},
{
"type": "field",
"domain": [
"geosite:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:private",
"geoip:cn"
],
"outboundTag": "direct"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}
最初の2つのルールは、DNSサーバーへの接続に使う出口を指定します。223.5.5.5:53への問い合わせは直接接続し、1.1.1.1:443への接続はプロキシ経由にします。通常のhttps://形式のDoHはコアのルーティング機構を使います。接続処理の経路が異なるため、安易に+local付きの形式へ置き換えないでください。これらのIPアドレスとポートを使うルールは、同じ接続先への他の通信にも一致し、DNS通信だけを識別するものではありません。
ルールの順序は自由に入れ替えられません。DNSサーバーへの接続ルールを先に置くことで、後続のIP分類ルールによってDoHサーバーのアドレスが意図せず振り分けられるのを防ぎます。最後のルールでは、残りのTCP・UDP通信をアウトバウンド配列の既定順に任せず、明示的にproxyへ送ります。既存のLAN、ブロック、アプリ別ルールなどがある場合は、1つずつ統合してください。設定全体を置き換えても従来の動作が保たれるとは限りません。
確認の順序:まずDNSサーバーへの接続経路を固定し、応答を比較する
まず1.1.1.1:443への接続が実際にproxyを使っていることを確認してから、ドメインの名前解決結果を調べます。DNSサーバーのアドレスだけを変更しても、接続の出口を確認しなければ、リモートへの問い合わせが想定どおり送信されたかは検証できません。
直接接続の名前解決方針も確認する
中国国内のドメインがドメインルールに一致すると、接続はdirectに送られます。このアウトバウンドがFreedomプロトコルを使い、既定の名前解決方針のままの場合、最終的な接続にはこの記事の内蔵DNSではなくシステムDNSが使われることがあります。直接接続から内蔵DNSを明示的に使うには、既存のアウトバウンドを確認し、settings.domainStrategyを調整してください。
{
"tag": "direct",
"protocol": "freedom",
"settings": {
"domainStrategy": "UseIPv4"
}
}
これはoutbounds配列内の単一オブジェクトです。同名のアウトバウンドを追加するのではなく、既存のdirectを変更してください。ここでのUseIPv4と前述のDNS問い合わせ方針は、問題を切り分けやすくするためのIPv4設定例です。IPv6を無効にすべきという意味ではありません。
- IPv4とIPv6の両方を使う場合:DNS問い合わせ方針とFreedomの名前解決方針を
UseIPにすることを検討し、ローカルのIPv6接続と対応するルーティングも確認してください。 - プロキシのアウトバウンドにドメイン名が渡される場合:接続先のドメイン名はリモート側で名前解決されることがあります。ローカルで得たDNS結果が、リモート側で実際に使われるとは限りません。
- ノードのアドレスがドメイン名の場合:プロキシサーバー自体の名前解決も考慮する必要があります。まだ確立していないプロキシ接続だけを、ノードのドメイン名を解決する唯一の手段にしないでください。
クライアントで実際の設定を確認する
v2rayNはデスクトップクライアント、v2rayNGはXrayコア、v2flyNGはV2Flyコアを使用します。クライアントの画面上の設定から実行用設定が生成されるため、「編集画面に項目がある」ことは「現在のコアがその項目を使っている」ことを意味しません。この記事では特定の画面やバージョンに依存せず、現在のノード、実行中のコア、最終的に生成されたJSONを確認します。
- 変更前の状態を記録:現在動作している設定をバックアップし、ノード、コアのバージョン、システムプロキシの状態、仮想NICの有効・無効を記録します。ノードや通信方式を同時に変更せず、DNSと関連するルーティングだけを一度に変更してください。
- 実行時の設定ファイルを確認:最終的なJSONに2つの
dns.servers設定、想定したアウトバウンドタグ、正しい順序のルールが含まれていることを確認します。設定が画面から生成される場合は、永続化される設定箇所を変更してください。次回起動時に上書きされる一時ファイルだけを編集しないでください。 - 診断ログを有効にする:一時的に
log.loglevelをdebugに設定し、コアを再起動してからリクエストを再実行します。ログの内容はバージョンによって異なるため、DNSサーバーの接続先、一致したアウトバウンド、エラーメッセージを中心に確認してください。 - 条件を分けてテスト:
geosite:cnに含まれることを確認したドメインを1つ選び、同じ分類に含まれないドメインも1つ選びます。接続の再利用を停止し、必要に応じてアプリを再起動してください。既存の接続が新しいDNSの動作を隠すことがあります。 - テスト後に通常のログ設定へ戻す:確認が終わったら、ログレベルを
warningまたは元の値に戻してください。ログを共有する前に、ノードのアドレス、サブスクリプションURL、アクセス先ドメインなどを削除してください。
利用中のコアに対応するコマンドがある場合は、まず設定ファイルのあるディレクトリで構文と読み込みを確認します。以下はXrayとV2Flyで一般的なコマンド形式です。実際に使っているコアに対応するものを1つだけ実行してください。設定テストに成功しても、上流DNSサーバーへの接続が確認できたことにはなりません。
xray run -test -config config.json
v2ray test -c config.json
nslookup example.com 223.5.5.5の結果を、コアのDNS振り分けが機能している証拠にしないでください。このコマンドは指定したDNSサーバーへ直接問い合わせるため、その問い合わせ経路が使えるかの確認には役立ちます。しかし、この記事のドメイン分類、フォールバック、プロキシ出口のルールは経由しません。システムDNSのテストとコア経由のリクエストは、分けて記録してください。
DNS汚染対策の範囲とよくある問題
ここでいう「DNS汚染対策」は、暗号化したリモートDNS問い合わせ、接続出口の固定、異常なアドレスの絞り込みによって、誤った応答を減らすことです。特定の設定項目だけで完全に防げるわけではありません。DoHはDNSサーバーまでの問い合わせ経路を保護しますが、DNSサーバーの信頼性、アプリ独自の問い合わせ、システムのキャッシュも最終的な接続に影響します。
中国国内のサイトまで表示が遅くなったら、まず何を変更すればよいですか?
まず中国国内向けDNSサーバーのexpectIPsを一時的に削除し、ほかの設定を変えずに再テストしてください。遅延が解消した場合は、実際の応答とgeoip:cnの分類が一致しているか確認します。原因を隠すためにフォールバックDNSサーバーを追加するのは避けてください。
リモートDNSを設定したのに、なぜローカルの問い合わせが見えるのですか?
まず、問い合わせ元がブラウザー、システム、ノードのドメイン名解決、コアのどれかを確認してください。アプリのセキュアDNS、システムプロキシの適用範囲、FreedomのdomainStrategyも確認します。コアのDNS設定だけでは、ほかのプロセスから外部への問い合わせを自動的に防げません。
設定を保存した直後に起動できなくなった場合、どう切り分ければよいですか?
最初のエラーがJSONの構文、未対応の項目、分類データの読み込みのどれを示しているか確認してください。geosite.datとgeoip.datをコアが読み込めることを確認し、directとproxyが実際に存在するアウトバウンドタグかも確認します。
DoHがタイムアウトするのに、プロキシノードには接続できる場合は?
1.1.1.1:443へのリクエストがプロキシのアウトバウンドに一致しているか確認し、ノードからDNSサーバーへの接続も調べてください。システム時刻と証明書エラーを確認します。失敗を回避するために証明書検証を無効にしないでください。必要に応じて、検証可能な別のDoHエンドポイントに個別に切り替えて比較します。
設定を変更したのに、ウェブサイトが古いアドレスへ接続するのはなぜですか?
アプリを終了して再起動し、コアも再起動してから新しい接続で再テストしてください。ブラウザー、OS、コア、リモートDNSサーバーには、それぞれキャッシュがある場合があります。ページを更新しただけでは既存の接続が再利用されることがあり、新しいルールが反映されていない証拠にはなりません。
理由を説明できる最小限の設定を保つ
- まず2つのDNSサーバーと2つのアウトバウンドで動作を確認し、その後カスタムのドメイン分類を少しずつ追加します。
- 誤った振り分けが起きたら、ルール一覧に目的のルールがあるかだけでなく、最初に一致したルールを確認してください。
- 特定のドメインを常に直接接続させるには、DNSの照合、ルールの優先順位、直接接続アウトバウンドの名前解決方針をあわせて確認してください。
- DNSの外部送信を制限するには、システム側での制御やネットワークポリシーを別途設計してください。この記事の設定例だけで、すべての通信を制御できるわけではありません。
保守しやすいDNS振り分け設定では、次の3点を説明できる必要があります。なぜそのドメインがそのDNSサーバーを選ぶのか、DNSサーバーへの接続がなぜそのアウトバウンドを通るのか、最終的な接続先がなぜ直接接続またはプロキシ接続になるのか。ルールを増やす前に、ログと実行時設定でこの3点を確認しましょう。DNSサーバーのアドレスを追加し続けるより、問題を切り分けやすくなります。