すでにノードに接続できているものの、名前解決がどちら側で起きているか分からないユーザー向けです。読み終えると、設計どおりの直結解決と意図しないリークを区別でき、アクセスログと 53 番ポートのフィルタでクエリの行き先を特定し、dns アウトバウンドタグ、ルーティングルール、ドメインスニッフィング、アプリ別プロキシの順に設定を絞り込めます。
判定基準:解決リクエストはどこへ行ったか
DNS リークの正確な定義は「解決がプロキシを通っていない」ことではなく、「使うつもりのないリゾルバに解決を渡し、しかもそれがプロキシトンネルの外で起きている」ことです。V2Ray の動作では、ドメインをそのままリモートノードへ送りノード側でクエリを完了させる方法と、クライアントが先に IP へ解決してから IP で接続を張る方法があります。どちらも正常で、違いは前者が問い合わせ先を露出しないのに対し、後者は問い合わせ内容と発信元をローカルネットワークに残す点です。
判定で見るのは一点だけ、この 53 番ポートのクエリが最終的にどのアウトバウンドで処理されたかです。アクセスログのアウトバウンドタグがプロキシなら解決はノード側、direct なら解決はローカルです。2 つ目は故障とは限りません。「中国本土をバイパス」モードでは中国本土のドメインをローカル DNS で解決するため、応答が速く結果も正確です。
本当に対処すべきは 3 つ目のケースです。ドメインは本来リモートで解決されるはずが、スニッフィングの無効化、アプリ別プロキシの設定漏れ、アプリ独自の暗号化 DNS などの理由で、クエリがローカルリゾルバへ送られてしまいます。こうしたリークはエラーを出さず静かに起きるので、ログとパケットキャプチャで見つけ出す必要があります。
上記が正常な経路です。どこか一環でも迂回されると——アプリがカーネルに入らない、ルールがクエリを直結と判定する、カーネルがスニッフィングしない——クエリは早い段階でローカルリゾルバに落ち、その後の接続がプロキシを通っても取り返しはつきません。
4 つの典型的なシナリオとログの実例
以下はトラブルシューティングで最もよく見るログとエラーで、「クエリが間違った方向へ進む」ケースをほぼ網羅します。自分のログと照らし合わせれば、どの層で問題が起きているかを直接特定できます。
ログ:accepted udp:223.5.5.5:53 [socks-in -> direct]
原因と対処:223.5.5.5 は中国本土の IP なので、「中国本土をバイパス」系のルールでは直結に該当し、クエリはローカルに残ります。中国本土のドメインがこの経路を通るのは設計どおりです。すべてのクエリをノード側から出したい場合は、dns セクションに専用のタグを付け、ルーティングルールでプロキシのアウトバウンドへ向けます。
症状:ログに :53 の記録がまったく出てこない
原因と対処:クエリがそもそもカーネルに入っていません。アプリ別プロキシでそのアプリが除外されているか、ブラウザ内蔵のセキュア DNS が HTTPS アドレスを使っています。まずプロキシ対象リストを確認し、次にブラウザのセキュア DNS を切り、もう一度再現してログに記録が出るか見ます。
エラー:failed to find an available destination
原因と対処:アウトバウンドのアドレス解決で使える結果が得られていません。DNS クエリ自体を利用できないアウトバウンドへ送っている場合によく起きます。まず一時的にローカル解決へ戻してノードが使えることを確認し、次にルーティングルール内の dns_inbound タグの参照先とノードアドレスの綴りを確認します。
エラー:context deadline exceeded
原因と対処:クエリがタイムアウト内に返っていません。多くは UDP 53 が上流で破棄されているか、クエリが通らないアウトバウンドへ送られています。解決アドレスを https で始まる暗号化 DNS に替えてもう一度再現すると、リンクの問題かルールの問題かを切り分けられます。
この 4 つのうち、直結アウトバウンドに関わるものは意図した動作かどうかを先に確認します。エラーに関わる 2 つはルールと解決アドレスが使えるかを確認します。「設計どおりの直結解決」と「意図しないリーク」を分けて見ないと、ログの direct タグに引っ張られます。
確認手順:再現できる 3 つのステップ
確認にオンラインツールは不要で、クライアント自身のログと 53 番ポートのフィルタが一度あれば、解決の行き先をはっきり見られます。手順は v2rayN と v2rayNG のどちらでも使え、デスクトップ側ではパケットキャプチャでの照合が 1 ステップ増えます。
アクセスログを開く
v2rayN は「設定」→「パラメータ設定」→「基本設定」で「ログレベル」を info にしてカーネルを再起動します。v2rayNG はメイン画面右上のメニューから「ログ」ページを開きます。
解決を一度再現する
OS 標準のブラウザで普通のサイトを開きます。セキュア DNS を有効にしたブラウザは使わないでください。クエリ先が HTTPS アドレスになり、53 番ポートのフィルタでは見えなくなります。
53 番ポートでフィルタ
ログで「:53」を検索し、各エントリのアウトバウンドタグを見ます。デスクトップでは同時に Wireshark で udp.port == 53 をフィルタし、物理 NIC 上に平文のクエリが残っていないか照合します。
プロキシ対象リストを確認
「アプリ別プロキシ」を開き、解決を開始するアプリがリストに入っているか確認します。Android 側ではさらにシステムの「プライベート DNS」の設定値と、ブラウザのセキュア DNS が有効かどうかを確認します。
いくつかの証拠が互いに裏づけ合う必要があります。ログでクエリがプロキシのアウトバウンドを通っている、物理 NIC 上で平文の 53 クエリが捕まらない、アプリリストに漏れがない、の 3 点です。1 つしか満たさない場合は、満たしていない点を先に解決してから再テストします。解決アドレスを暗号化 DNS に替えてもう一度実行し、ログのアウトバウンドタグとキャプチャ結果が同時に変われば、変更が実際に効いています。
v2rayN 側:DNS アウトバウンドとルーティングルール
v2rayN の GUI オプションはほとんどの場面をカバーできますが、DNS クエリを正確にプロキシのアウトバウンドへ固定するには、設定の dns セクションにタグを付ける必要があります。比較的新しい Xray カーネル(1.8 以降)は dns セクションに tag を書け、このタグはインバウンドタグとしてルーティング照合に参加します。同時に暗号化解決アドレスを servers の前に置けば、ローカル解決が必要な場合も暗号化された形で送信されます。
{
"dns": {
"tag": "dns_inbound",
"queryStrategy": "UseIPv4",
"servers": [
{ "address": "https://1.1.1.1/dns-query", "domains": ["geosite:geolocation-!cn"] },
{ "address": "223.5.5.5", "domains": ["geosite:cn"] }
]
},
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{ "type": "field", "inboundTag": ["dns_inbound"], "outboundTag": "proxy" },
{ "type": "field", "domain": ["geosite:cn"], "outboundTag": "direct" }
]
}
}
この設定は 2 つのことを行います。海外ドメインは暗号化 DNS で解決し、中国本土のドメインはローカルで解決します。DNS クエリ自体には dns_inbound タグが付き、最初のルールでプロキシのアウトバウンドへ送られます。順序は逆にできません。dns_inbound ルールはドメインルールより前に置かないと、クエリが先に geosite:cn などのルールに取られてしまい、タグを付けた意味がなくなります。
| 設定項目 | 場所 | 推奨値 | 役割 |
|---|---|---|---|
| ルーティングモード | 「設定」→「パラメータ設定」→「ルーティング設定」 | 中国本土をバイパス | 中国本土のドメインは直結、それ以外はプロキシ経由 |
| ドメイン解決ポリシー | 「設定」→「パラメータ設定」→「ルーティング設定」 | IPIfNonMatch | ドメインはまずリモートに任せ、一致しなければ IP で判定 |
| ドメインスニッフィング | 「設定」→「パラメータ設定」→「ルーティング設定」 | 有効化し、種類は HTTP と TLS を選択 | ハンドシェイクからドメインを復元し、IP による誤判定を防ぐ |
| DNS サーバー | 「設定」→「パラメータ設定」→「DNS 設定」 | 暗号化解決アドレスを優先 | ローカル解決が必要なときもクエリは暗号化して送信 |
| アウトバウンドのドメイン戦略 | 設定内の outbound の sockopt.domainStrategy | AsIs | ドメインをそのままノードへ送り、解決はノード側で完了 |
結論:DNS に独立したルートを 1 本与える
暗号化 DNS はクエリ内容が見られる問題を解決するだけで、クエリがどのアウトバウンドを通るかは解決しません。正しい順序は、まず dns タグを付け、ルーティングルールで dns_inbound をプロキシのアウトバウンドへ向け、そのうえで解決アドレスを暗号化形式に替えることです。逆にすると、暗号化クエリでも直結アウトバウンドから出てしまうことがあります。
v2rayNG Android 側:ルーティングモード、スニッフィング、アプリ別プロキシ
v2rayNG は Xray カーネルを使い、接続後はシステムの VpnService がトラフィックを引き受け、アプリの接続はまずカーネルに入ってから分流します。Android 側のリークポイントは 3 か所に集中します。アプリ別プロキシのリスト、ドメインスニッフィングのスイッチ、システムのプライベート DNS です。以下は v2rayNG を基準にします。v2flyNG は設定項目の名称が近いので、照らし合わせて探せます。
- ルーティングモード:「設定」→「ルーティングモード」で「中国本土をバイパス」を選ぶと、中国本土のドメインはローカルで解決されます。これは設計どおりの動作です。すべてのドメインをノード側で解決させたい場合は「グローバル」に切り替えます。
- ドメイン解決ポリシー:「設定」→「ドメイン解決ポリシー」では AsIs のままにし、ドメインをそのままノードへ送ります。IP で分流したい場合に IPIfNonMatch を選びます。
- ドメインスニッフィング:「設定」で「ドメインスニッフィング」をオンにし、HTTP と TLS にチェックを入れて、カーネルがハンドシェイクからドメインを復元できるようにします。直結ルールが IP で誤って通してしまうのを防げます。
- アプリ別プロキシ:「設定」→「アプリ別プロキシ」で、解決を開始するアプリがリストに入っているか確認します。除外されたアプリは DNS すらカーネルに入りません。
- プライベート DNS:Android の「設定」→「ネットワークとインターネット」→「プライベート DNS」で「自動」にするか、ホスト名を入力している場合は解決が DoT 経由になります。引き受けられるかどうかはルーティングルール次第です。
もう一つ見落としやすい点があります。一部のブラウザやアプリはセキュア DNS を内蔵しており、クエリ先は 53 番ポートではなくリゾルバ事業者の HTTPS アドレスになるため、ログで「:53」を検索しても見つかりません。対処法は、リゾルバ事業者のドメインをプロキシルールに書くか、ブラウザ設定でセキュア DNS を切り、解決をカーネルの dns セクションへ戻すことです。
結論:Android 側はまずリスト、次にスニッフィング
アプリ別プロキシの設定漏れは、アプリ全体をその DNS ごとカーネルの外へ出してしまい、影響範囲はスニッフィングのスイッチよりはるかに大きくなります。調査順序はリスト、スニッフィング、プライベート DNS、最後に設定内の dns セクションをおすすめします。
よくある質問
スニッフィングを切るとルーティングは IP ベースのままですが、実際にどんな影響がありますか?
ドメインはまずローカルで IP に解決され、接続は IP で張られるため、直結とプロキシのルールは IP でしか判定できません。中国本土の CDN ドメインが誤ってプロキシへ送られやすくなり、解決リクエストもローカルネットワークに残ります。スニッフィングをオンにするとこの 2 つを同時に解決できます。
「中国本土をバイパス」モードで中国本土のドメインをローカル DNS で解決するのはリークですか?
いいえ。これは設計どおりの直結解決で、問い合わせ先は自分で選んだローカルリゾルバです。中国本土のドメインもノード側で解決させたい場合は、ルーティングモードを「グローバル」に切り替え、それによる解決遅延の変化を受け入れます。
確認結果に表示されるリゾルバが、自分が設定した DNS と違うのはなぜですか?
まずブラウザでセキュア DNS が有効になっていないか、次にシステムでプライベート DNS が設定されていないかを見ます。どちらもアプリ層で解決を別のリゾルバへ渡すため、クライアントの設定では制御できません。1 つずつ切って再テストします。
サブスクリプションの更新がずっとタイムアウトするのは DNS と関係ありますか?
関係あります。サブスクリプションのドメイン解決は既定で直結になることがあり、直結の解決が汚染されたりタイムアウトしたりすると更新が失敗します。サブスクリプション設定で「プロキシ経由でサブスクリプションを更新」にチェックを入れ、リクエストと解決の両方をノード側から出します。
暗号化 DNS アドレスを設定したのに効いていない?
まずカーネルのバージョンがその書き方に対応しているか確認し、次に dns セクションの tag がルーティングルールから参照されているか確認します。設定を変えたらカーネルを再起動してください。ログで DNS クエリのアウトバウンドタグが変わって初めて有効になったと言えます。
DNS を普通のトラフィックの 1 本として扱えば、考え方ははっきりします。どのアウトバウンドで処理されているかを見て、独立したタグとルールを与え、どのドメインをローカル解決のまま残すかを決めます。v2rayNG と v2rayN の GUI オプションでほとんどの場面はカバーでき、残りの精度は設定内の dns と routing の 2 セクションに任せます。