DNSの振り分けでは、「どのDNSサーバーで名前解決するか」と「DNSクエリをどの outbound から送るか」の両方を決める必要があります。ノードには接続できるものの、名前解決がタイムアウトする、ドメイン別の振り分けがうまくいかない場合に向けて、V2Ray形式のJSONで各項目の関係、設定の統合方法、確認手順を解説します。掲載するのは設定例の一部であり、そのまま起動できる完全なクライアント設定ではありません。Xrayコアを使う場合は、使用中のコアが対応する項目を確認してください。
1. DNSの振り分けと接続の振り分けは別
まず押さえておきたいのは、リモートDNSをクライアントに設定しても、すべてのアプリがそのDNSを使うとは限らないことです。ブラウザーが独自の暗号化DNSを有効にしている場合や、OSのキャッシュが使われる場合があります。また、プロキシプロトコルによっては、ドメイン名がそのままサーバー側に渡されて名前解決されます。リクエストが内蔵DNSモジュールに実際に届いた場合に限り、以下のserversルールが適用されます。
この流れは、内蔵DNSが呼び出された場合の処理を示すもので、すべてのプロキシ接続がローカルで名前解決されるという意味ではありません。クライアントが受け取ったドメイン名について、ルーティングでプロキシ outbound が選ばれれば、通常はドメイン名をサーバー側へそのまま渡せます。IPアドレスによるルール判定が必要な場合や、direct outbound の接続先IPが必要な場合には、ローカルで名前解決されることがあります。実際の動作はルーティングポリシーとoutbound設定によって決まります。
- DNSの振り分け:ドメイン名の問い合わせ先DNSサーバーを決めます。設定の中心は
dns.serversです。 - 接続の振り分け:通信を直接接続するかプロキシ経由にするかを決めます。設定の中心は
routing.rulesです。 - DNSクエリの経路:DNSサーバーへの接続を直接接続にするかプロキシ経由にするかを決めます。ルーティングルールも確認してください。
システムプロキシが主に制御するのは、プロキシ設定に従うアプリのリクエストです。端末全体のDNS通信が自動的にプロキシ経由になるわけではありません。TUNを使うと制御範囲を広げられますが、DNSのリダイレクト、ルーティング、除外設定も必要です。スイッチの状態だけで、DNSクエリがコアに届いているかを判断しないでください。
2. servers、domains、queryStrategyの役割
serversはDNSサーバーの候補リストです。各オブジェクトのdomainsで、そのDNSサーバーを優先的に使うドメインを指定します。queryStrategyはIPv4、IPv6、または両方を問い合わせるかを制御します。それぞれ役割の異なる設定項目であり、互いに置き換えることはできません。
| 項目 | 設定例 | 役割 |
|---|---|---|
servers | IPアドレスまたはDoHアドレス | 利用可能なDNSサーバーと、それぞれの適用条件を定義します。 |
domains | geosite:cn | 対象となるドメインを照合し、該当するDNSサーバーを優先して試します。 |
queryStrategy | UseIP | AレコードとAAAAレコードを問い合わせます。両方のアドレスで接続できるとは限りません。 |
queryStrategy | UseIPv4 | IPv4アドレスのみを問い合わせます。IPv6経路の問題を切り分ける場合に使えます。 |
skipFallback | true | このDNSサーバーを、ルールに一致しないドメインの通常のフォールバック候補から除外します。 |
domainsは、厳密なアクセス許可リストではありません。名前解決に失敗したあと、別のサーバーが試されるかどうかは、フォールバック関連の設定にも左右されます。以下ではskipFallbackを使い、ローカルDNSが未照合ドメインの通常のフォールバック先にならないようにしています。ただし、対象ドメインの名前解決に失敗したとき、ほかのDNSサーバーが絶対に試されないという意味ではありません。
ローカルドメイン用DNSサーバー
- アドレス
223.5.5.5- ポート
- UDP 53
- 対象範囲
geosite:cn- フォールバックでの役割
skipFallback: true
この例では中国本土のドメインを対象とします。社内ネットワーク専用のDNSという意味ではありません。
デフォルトのリモートDNSサーバー
- アドレス
https://1.1.1.1/dns-query- ポート
- TCP 443
- 対象範囲
- ローカルドメインの集合に一致しないドメイン
- クエリ経路
- 既存のプロキシoutboundを明示的に指定
DoHはクエリ内容を暗号化します。接続できるかどうかは、実際のネットワーク環境とプロキシoutboundによって異なります。
geosite:cnの利用には、実行ディレクトリにドメインルールのデータが必要です。コアが地域を自動判定するわけではありません。起動ログにルールファイルの読み込みエラーが出た場合は、まずリソースファイルを修復してください。社内ドメインは適切なdomain:ルールで照合し、社内DNSに問い合わせます。社内IPが返ることを期待して公共DNSに問い合わせてはいけません。
3. ドメイン別DNS振り分けの設定例
ここでは、ローカルDNSサーバーとデフォルトのDoHサーバーを1つずつ設定します。中国本土のドメインはローカルDNSを優先し、それ以外のドメインはリモートDNSで名前解決する構成です。まず設定をバックアップし、最上位のdnsオブジェクトを既存のJSONに統合してください。同名のオブジェクトがすでにある場合は、既存の内容を編集し、dnsキーを重複して追加しないでください。
{
"dns": {
"queryStrategy": "UseIP",
"servers": [
{
"address": "223.5.5.5",
"port": 53,
"domains": [
"geosite:cn"
],
"skipFallback": true
},
"https://1.1.1.1/dns-query"
]
}
}
ここではIPアドレス形式のDoHエンドポイントを使い、DNSサーバーのドメイン名を先に名前解決する必要が生じるのを避けています。DoHアドレスをドメイン名形式にする場合は、そのドメインをどのDNSで名前解決するか、また名前解決のリクエストが未接続のDoHサービスに依存する循環状態にならないかも確認してください。
- コアを確認:v2rayNはクライアントのインターフェースであり、V2Rayコアそのものではありません。コアの起動ログでV2RayとXrayのどちらが実行されているかを確認し、各設定項目への対応状況を調べてください。
- ルールファイルを確認:起動時に
geosite:cnの読み込みエラーが出ていないことを確認します。エラーがある場合、ルールの照合条件が満たされていません。 - 生成された設定を確認:インターフェースから生成した設定は、クライアントの再起動時に手動変更が上書きされることがあります。クライアントが提供するカスタム設定の保存先を使い、コアに渡された実際の設定を確認してください。
- アドレスファミリーを確認:通常は
UseIPのままデュアルスタックで使います。IPv6の問題を切り分ける場合に限り、一時的にUseIPv4へ変更し、結果を比較してください。
この設定例にはinbound、プロキシサーバー、outboundの定義がないため、単独では起動できません。Android版のv2rayNGはXrayコア、v2flyNGはv2flyコアを使用します。どちらも画面に「DNS」と表示されていても、設定の優先関係や動作モードはそれぞれ確認してください。
4. DNSクエリのoutboundを正しく設定する
DNSサーバーのアドレスだけを設定し、クエリの経路を指定しないと、「リモートDNSなのに実際には直接接続される」ことがあります。標準のhttps://形式のDoHリクエストはコアのルーティングを経由できます。一部のコアが対応するhttps+local://はローカル接続を意味するため、同じアドレス形式として置き換えることはできません。
{
"routing": {
"domainStrategy": "AsIs",
"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"
}
]
}
}
これは設定の統合例です。既存のoutboundタグがdirectとproxyであることを前提としています。タグは設定内で参照する名前であり、コアが自動作成するオブジェクトではありません。例の名前を実際のタグに置き換え、先に適用される可能性がある包括的なルールより前に、DNSクエリ用の2つのルールを配置してください。この2つのルールで既存の通信振り分けルールを上書きしないようにしてください。
結論:DNSサーバーの応答速度より先に、クエリのoutboundを確認
ログでDoH接続にdirect outboundが選ばれている場合は、まずルールの順序とタグの参照先を修正してください。DNSサーバーのアドレスを変えても、クエリ経路の誤りは解決しません。
AsIsは、ルーティング時にIPルールのための名前解決を積極的に行わない設定です。通信に名前解決が不要になるという意味ではありません。IPIfNonMatchに変更すると、ドメインルールに一致しないリクエストが、IPルールとの照合前に名前解決される場合があります。IPOnDemandでは、IPアドレスが必要なルールに遭遇したときに名前解決が行われる可能性があります。値を変更する前に、IPルールを本当に使う必要があるか確認してください。
プロキシサーバー自体のドメイン名解決も確認してください。プロキシに接続するための名前解決を、そのプロキシ経由のDoHに依存させると、循環依存が発生します。明示的な初期名前解決経路を用意するか、サービス提供元が確認したサーバーアドレスを使ってください。サブスクリプション内のサーバー情報を安易に変更しないでください。
5. DNS汚染対策:暗号化、クエリ経路、キャッシュを確認
DoHはクライアントとDNSサーバー間のクエリ通信を保護しますが、期待どおりの名前解決結果が得られることを保証するものではありません。DNSサーバーの地域別ポリシー、WebサイトのCDNによる振り分け、端末のキャッシュ、IPv6の接続状況によって、IPアドレスが異なったり、名前解決は成功してもサイトに接続できなかったりします。2つのDNSサーバーが返すIPアドレスの違いだけで、DNS汚染と判断することはできません。
- まずクエリの入口を確認:ブラウザー独自のセキュアDNSが、OSの名前解決を経由しない場合があります。切り分け中はいったん無効にし、比較が終わってから使うかどうかを決めてください。
- 次にクエリの出口を確認:コアのログでDNSエラーと接続outboundを確認します。必要に応じて端末上でパケットをキャプチャし、意図しないUDP 53のリクエストが送信されていないか調べてください。
- システムキャッシュを切り分け:Windowsでは
ipconfig /flushdnsを実行して、システムのDNSキャッシュを消去できます。ただし、ブラウザーやコアが個別に管理するキャッシュはすべて消去されるわけではありません。 - 変更する条件は1つに絞る:同じ接続先、同じノード、同じ動作モードで、DNSサーバーかアドレスファミリーのどちらか1項目だけを変更します。プロキシ経路の変化をDNSの改善と誤認しないようにしてください。
この例のローカルDNSサーバーは通常のUDPクエリを使うため、その通信は暗号化されません。暗号化されていないクエリが適さないネットワーク環境では、接続可能なローカルの暗号化DNSサーバーを選び、関連するルーティングも設計し直してください。アドレスをDoHに変更するだけでなく、接続性、証明書の検証、outboundの設定も確認してください。
結論:名前解決の成功と通信先への接続性は別々に確認
AまたはAAAAレコードを取得できたことは、DNSクエリで結果が返ったことを示すだけです。次に、通信で実際に使われたIPアドレス、outbound、エラーの種類を確認し、名前解決の問題か、IPv6経路の問題か、プロキシ接続の失敗かを切り分けます。
6. DNSトラブルの確認手順とよくある質問
まず接続できる設定を保存し、「コアの起動、クエリの送信、結果の受信、通信先への接続」の順に確認してください。一時的にログの詳細度を上げたら、対象を1つだけ選んで再現し、大量の同時リクエストで必要な記録が埋もれないようにします。切り分けが終わったら通常のログレベルに戻し、ログを共有する前にサブスクリプションURLや接続情報を削除してください。
nslookup -type=A example.com 223.5.5.5
nslookup -type=AAAA example.com 223.5.5.5
ipconfig /flushdns
example.comは説明用に予約されたサンプルドメインです。最初の2つのコマンドは指定した通常のDNSサーバーに直接問い合わせ、クエリ経路が使えるかを確認します。V2Ray内蔵DNSを自動的に呼び出すものではなく、DoHがプロキシ経由で送信されたことも証明できません。コアの振り分けを検証するには、実際のアプリからリクエストを送り、コアのログと実際の設定をあわせて確認してください。
DNSを変更したのに、ブラウザーに以前の結果が表示されるのはなぜ?
まずブラウザー独自のセキュアDNSが有効になっているか確認し、次にシステムのキャッシュを消去してブラウザーを再起動してください。そのうえで、コアの実行設定に新しいアドレスが含まれているかを確認します。読み込まれていないJSONファイルを変更しても、現在の接続には反映されません。
通常のDNSは使えるのに、DoHがタイムアウトするのはなぜ?
まずDoHアドレスへのTCP 443接続が、想定したoutboundを選んでいるか確認します。次にノードが利用可能か、システム時刻が正しいかを確認してください。ログに証明書エラーがある場合、証明書検証を無効にせず、時刻、エンドポイント、ネットワーク上の干渉を調べてください。
UseIPv4に変更すると接続できる場合、何が考えられる?
多くの場合、DNS汚染の証拠ではなく、IPv6経路の確認が必要です。AとAAAAの結果を比較し、端末のデフォルトルート、ノードのIPv6 outbound対応状況、接続先のエラーを確認してから、アドレスファミリーを恒久的に制限するか判断してください。
社内ドメインを公共DNSで名前解決できないのはなぜ?
社内ドメインのサフィックスを個別に照合し、社内DNSに振り分けてください。クエリが社内ネットワークへ直接接続されることも確認します。TUNが関連するアドレスを処理する場合は、LAN向けルートと除外設定も確認してください。通常、公共DNSには社内ゾーンの情報はありません。
サブスクリプションの更新後に設定が消えた場合、生成ファイルを編集し直す?
まずカスタムDNS設定が、クライアント全体の設定、設定テンプレート、個別の設定項目のどれに属するかを確認してください。変更内容はクライアントが対応する永続的な保存先に保存し、コアを再起動して生成結果を確認します。実行時に使われる一時ファイルを何度も編集しないでください。
最終的な確認基準は「DNSサーバーを何台設定したか」ではなく、次の3点がすべて満たされていることです。ローカルドメインが想定したDNSサーバーに振り分けられること、リモートDNSクエリが想定したoutboundを使うこと、通信が当初のルーティングどおりに完了すること。画面上の設定場所や設定構造をさらに確認したい場合は、クライアント設定ガイドと技術リファレンスをご覧ください。