1. DNSの出口・Web通信の出口・ルールの想定を切り分ける
Webサイトにプロキシ経由のIPアドレスが表示されても、ドメインの名前解決までプロキシを通っているとは限りません。アクセス時には少なくとも2つの経路が使われます。アプリがドメインを名前解決し、その後、接続先のアドレスに接続します。システムプロキシが対象にできるのは、通常、プロキシ設定に従うアプリだけです。システムのリゾルバー、アプリ内蔵のDNS、ブラウザーのセキュアDNSは、それぞれ別の経路を使う場合があります。
この記事では「DNSリーク」を、指定した名前解決経路を通るはずの問い合わせが、想定外のリゾルバーに渡されたり、ローカルネットワークから直接送信されたりする状態と定義します。ルール上、ローカルドメインをローカルDNSで直接解決する設定なら、ローカルのリゾルバーが検出されても必ずしも問題ではありません。一方、通常の問い合わせをすべてプロキシ経由にする方針なら、同じ結果でも調査が必要です。
| 確認項目 | 分かること | それだけでは分からないこと |
|---|---|---|
| Webサイトに表示されるグローバルIP | そのWebサイトへのリクエストが出ていく経路 | 他のアプリやDNSも同じ経路を使っているか |
| テストサイトに表示されたDNSのIPアドレス | 再帰問い合わせを処理したサーバーの出口 | 端末からリゾルバーまでの通信がプロキシを通ったか |
| 198.18.x.xが返る | 今回の問い合わせで、一般的なfake-ipのアドレス範囲に含まれる値が返された | システムのすべての問い合わせが取り込まれているか |
| 契約中のISPのリゾルバーが表示される | 確認が必要なローカルDNS経路が存在する | すべての接続がプロキシを迂回している |
2. テストサイトでは国名だけでなく3つの条件を比較する
テスト条件をそろえて記録する
dnsleaktest.comのStandard testとExtended test、さらにbrowserleaks.com/dnsを使って比較できます。テスト用ドメインの名前解決を発生させ、問い合わせが権威サーバーに届いた際の再帰リゾルバーの出口を記録する仕組みです。ブラウザーからOSのDNS設定を直接読み取っているわけではありません。
- 家庭のWi-Fiなど、利用中のネットワークを記録します。クライアントのモード、選択中のノード、TUNの有効・無効、ブラウザーのセキュアDNSの状態も記録してください。
- プロキシを無効にしてテストを1回実行し、基準値としてグローバルIP、DNS事業者、リゾルバーのアドレスを控えます。スクリーンショットを公開する場合、全情報を載せる必要はありません。
- ノードを変えずにプロキシを有効にし、もう一度テストします。システムプロキシモードとTUNモードは別々に記録し、複数の条件を同時に変更しないでください。
- ブラウザーのセキュアDNSを一時的に無効にし、ブラウザーを再起動して再テストします。結果が変わる場合は、まずブラウザー独自のDoH経路を確認してください。
ここで紹介するのは推奨する操作手順であり、本サイトによる実測データではありません。「設定を切り替える前後で変化したか」「設定したポリシーに沿っているか」を比較しましょう。国名の表示だけで判断するのは避けてください。パブリックDNSはエニーキャストネットワークを使うことがあり、地理情報データベースにも遅れがあります。リゾルバーの登録上の所在地と、実際に応答した拠点が一致しない場合もあります。
結果から原因を絞り込む
- WebのIPは変わったが、DNSは自宅のISPのまま:システムDNSがコアに取り込まれているか、ブラウザーに独自の名前解決設定がないかを確認します。
- 特定のブラウザーだけDNSが異なる:まず、そのブラウザーのセキュアDNS、拡張機能、個別のプロキシ設定を確認します。
- 2つのパブリックDNSが表示される:複数の上流DNSやフォールバックが設定されている可能性があります。表示数だけでリークと判断することはできません。
- TUNを有効にして初めて想定どおりの結果になる:システムプロキシでは以前の名前解決経路をカバーできていなかった可能性があります。アプリへの適用範囲とIPv6も確認してください。
3. fake-ipでドメインをマッピングし、上流DNSを確認する
fake-ipはアプリに仮想アドレスを返し、コアがドメインとの対応関係を保持する機能です。後続の接続がコアに届くと、その対応関係を使ってドメインルールを適用できます。暗号化プロトコルではなく、OSのDNSを自動的に取り込む機能でもありません。設定を有効にしていても、システムが引き続きルーターに問い合わせていれば、この経路を迂回する可能性があります。
以下は、既存設定に統合するDNS設定の抜粋であり、設定ファイル全体ではありません。既存のノード、プロキシグループ、ルールは残してください。既存のトップレベルにあるdns:セクション全体を確認してから編集し、同じファイルに同名のセクションを追加しないでください。
dns:
enable: true
listen: 127.0.0.1:1053
ipv6: false
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
fake-ip-filter:
- '+.lan'
- '+.local'
respect-rules: true
default-nameserver:
- 223.5.5.5
proxy-server-nameserver:
- 223.5.5.5
nameserver:
- https://cloudflare-dns.com/dns-query
listenはコアのDNSリスニングアドレスです。例の1053は特定の経路をテストするためのポートで、設定しただけでシステムが自動的にこのポートを使うわけではありません。default-nameserverはDNSサーバー自身のドメインを名前解決するための設定で、起動時の名前解決経路の一部です。通常の問い合わせに使う上流DNSの一覧ではありません。proxy-server-nameserverはプロキシノードのドメインを名前解決するために使います。「ノードの名前解決にはプロキシ接続が必要だが、プロキシ接続にはノードの名前解決が必要」という循環依存を防ぎます。nameserverに指定するDoHアドレスは、通常の上流DNSとして使われます。暗号化されるのはDNSサービスまでの通信であり、その通信が必ずプロキシ経由になるという意味ではありません。fake-ip-filterに登録したドメインにはfake-ipのマッピングが適用されません。このリストは直接接続ルールではなく、登録したドメインのDNS問い合わせがなくなるわけでもありません。
4. respect-rulesは上流への接続経路を決める。システムDNSは取り込まない
respect-rules: trueを設定すると、対象となるDNS上流への接続にルーティングルールが適用されます。解決するのは「コアから上流へ問い合わせる際に、どの出口を使うか」です。「システムからの問い合わせがコアに届いているか」とは別の問題です。分けて検証すると、トラブルシューティングの手戻りを減らせます。
最終的に適用されるルールを確認する
- 現在のモードがルールモード、つまり
mode: ruleになっていることを確認します。グローバルモードや直接接続モードでの動作を、ルールモードの検証の代わりにすることはできません。 - DNSサービスのドメインが、先行ルールやルールセットによって
DIRECTにマッチしていないか確認します。直接接続にマッチしている場合、respect-rulesを有効にしてもプロキシ経由にはなりません。 - クライアントの接続パネルとログで、上流接続に適用されたルールと出口を確認します。必要な場合のみ短時間ログレベルを上げ、調査後は元に戻してください。ドメインが過剰に記録され続けるのを防げます。
- DNSサービスのドメインに個別の出口を指定する場合は、既存のプロキシグループ名を正確に使い、先にマッチする包括的なルールより前に配置します。設定に存在しないグループ名を追加しないでください。
既存設定にnameserver-policy、direct-nameserver、fallbackがある場合は、それらも確認してください。nameserverだけを変更しても、ドメインによって実際に使われるリゾルバーが変わらないことがあります。原因を切り分ける際は、まず変数を減らしましょう。最小構成で正常に動作することを確認してから、ポリシーを1つずつ戻します。
fallbackは「メインDNSがタイムアウトしたら起動する」だけの単純なスイッチではありません。フォールバック結果を採用する条件にはfallback-filterなどが関係します。リーク対策としてリゾルバーをむやみに増やしても、テスト結果が複雑になるだけです。
5. システムDNSの取り込み:TUNと53番ポートの役割
多くのデスクトップOSのネットワーク設定で指定できるのはDNSサーバーのアドレスであり、1053のような任意のポートは指定できません。そのため、システムDNSを127.0.0.1に設定し、コアが127.0.0.1:1053だけで待ち受けると、ポートが一致しません。システムからローカルDNSへ直接接続する構成では、53番ポートで待ち受け、権限とポートの競合にも対処する必要があります。安易に待ち受けアドレスをLAN全体に公開しないでください。
もう1つの一般的な方法は、TUNでネットワーク通信を取り込み、TUNに入った通常のDNS問い合わせをコアに処理させることです。以下も既存設定に統合する抜粋です。クライアントの画面から別のTUN設定が生成されていないことを先に確認してください。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
- tcp://any:53
any:53とtcp://any:53は、それぞれTUNに入るUDPとTCPの53番ポート宛てDNS問い合わせを対象にします。auto-routeは関連するルートを自動設定します。起動に失敗した場合は、DNSアドレスを何度も切り替えるのではなく、サービスの権限、ルートの競合、他のVPNを先に確認してください。- ローカルリンク宛てのDNS問い合わせや、ルーティング対象から除外された問い合わせは、TUNに入らない場合があります。ルーターのDNS、他の仮想ネットワークアダプター、ローカルのループバックリゾルバーは、それぞれ個別に確認してください。
- DoHは通常HTTPSの443番ポートを、DoTは通常853番ポートを使います。53番ポートを横取りしても、これらが自動的にコアのDNS問い合わせに変換されるわけではありません。
6. Windows・macOS・Linux・Androidで個別に再テストする
Windows:コアの待ち受けテストとシステム経路のテストを分ける
管理者権限でクライアントに必要なサービスまたはTUNを起動してから、次の2つのコマンドで確認します。1つ目はローカルの1053番ポートを指定して問い合わせ、2つ目はシステムのデフォルトDNSを使います。検証する経路はそれぞれ異なります。
nslookup -port=1053 example.com 127.0.0.1
nslookup example.com
ipconfig /all
ipconfig /flushdns
ドメインがフィルターリストに含まれていなければ、1つ目のコマンドでは通常、設定したアドレスプール内のfake-ipが返ります。2つ目はTUNによる横取りが動作していても、画面に元のDNSサーバー名が表示される場合があります。その表示だけで失敗と判断しないでください。返されたアドレス、ログ、テストサイトの結果を組み合わせて確認します。キャッシュを削除してからテスト用ドメインに再アクセスし、古い応答の影響を避けてください。
macOS:Wi-Fiの画面だけでなく、システムのリゾルバー一覧を確認する
scutil --dns
dig @127.0.0.1 -p 1053 example.com A
dscacheutil -q host -a name example.com
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
scutil --dnsでは、インターフェースやドメインごとに分かれたリゾルバー設定を確認できます。digで宛先を指定した問い合わせを行うと、コアの待ち受けを確認できます。dscacheutilはシステムの名前解決経路を調べる補助に適しています。TUNに必要な権限を許可してからブラウザーでも再テストしてください。digが成功しただけで、システム側の確認を省略しないでください。
Linux:systemd-resolvedとループバックアドレスに注意する
resolvectl status
resolvectl query example.com
dig @127.0.0.1 -p 1053 example.com A
sudo resolvectl flush-caches
/etc/resolv.confに127.0.0.53が記載されている場合、アプリはいったんローカルのスタブリゾルバーに問い合わせています。最終的な上流DNSがローカルにあるとは限りません。resolvectl statusでインターフェースごとのDNSも確認してください。systemd-resolvedを使用していないディストリビューションでは、NetworkManagerまたは実際にDNSを管理しているサービスを調べます。サービスが自動生成するファイルを直接上書きしないでください。
Android:プライベートDNSとブラウザーのセキュアDNSを分けて確認する
標準的なAndroidでは、一般に「設定」→「ネットワークとインターネット」→「プライベートDNS」から設定できます。指定中のプライベートDNSを一時的に無効にして、同じ条件でテストを再実行してください。メーカーによってメニュー名は異なる場合があります。クライアントにVPN権限が付与されていること、アプリ別プロキシの対象からテスト用ブラウザーが除外されていないことも確認してください。Androidで同時に動かせる通常のVPNサービスは、通常1つです。他のVPNやローカルフィルタリングアプリが経路を使用している可能性があります。
デスクトップ版Chromeでは、「設定」→「プライバシーとセキュリティ」→「セキュリティ」→「セキュアDNSを使用する」から設定できます。切り分けのために無効にした場合は、テスト後に元に戻し、DoH接続が実際にどの出口を通るか確認してください。ブラウザーのDoHを有効にしていても、必ずしもリークとは限りません。重要なのは、名前解決とルーティングの方針に合っているかどうかです。
7. fake-ipが有効でも問題が残る場合に確認する4項目
- IPv6が別の経路を通っている:
dns.ipv6: falseは、コアのDNSでAAAA問い合わせをどう処理するかを設定する項目で、システムのIPv6を無効にするものではありません。アプリのキャッシュや内蔵リゾルバー、すでに取得済みのIPv6アドレスで接続される可能性があります。IPv6のルートとTUNの適用範囲を確認してください。 - サブスクリプション更新で手動変更が上書きされた:再読み込み後は、エディター上のファイルだけでなく、実際に適用されている設定を確認してください。長期的に維持する項目は、クライアントが対応する上書き、マージ、永続化の仕組みで管理します。
- フィルターリストが大きすぎる:多くの一般ドメインを
fake-ip-filterに追加すると、実IPアドレスが返されますが、DNSの出口が自動的に修正されるわけではありません。互換性の問題が実際にあるドメインだけを例外に追加し、追加するたびに再テストしてください。 - キャッシュや既存の接続が残っている:システム、ブラウザー、コアのマッピング、確立済みの接続には、それぞれ異なる有効期間があります。再読み込み後はテスト用のタブを閉じ、必要に応じてブラウザーを再起動してから新しいテストを行ってください。古い接続で新しい設定を評価しないようにしましょう。
最後にチェックリストで設定を確認する
127.0.0.1:1053を指定した問い合わせに応答があり、通常のテスト用ドメインで想定どおりのfake-ipマッピングが返る。- システムのデフォルトDNSと実際のブラウザーテストを確認済みで、コアのポートをテストしただけではない。
- DNS上流への接続出口がルールと一致し、ノードのドメインと起動時の名前解決に関する例外も明確に記録されている。
- 通常のDNS、ブラウザーのDoH、IPv6、アプリ別の除外設定をそれぞれ確認し、53番ポートの横取りをすべてのプロトコルの取り込みと混同していない。
- サブスクリプションの更新、クライアントの再起動、Wi-Fiの切り替え後にもテストし、結果が設定したポリシーに合っている。
確認の流れは3段階です。まず問い合わせがコアに届いていることを確認し、次に上流への接続が正しい出口を使っていることを確かめ、最後に普段使うアプリが別経路を使っていないか確認します。fake-ipはドメインのマッピング、respect-rulesは上流へのルート選択、システムDNSの取り込みは問い合わせの入口を担当します。役割を分けて確認すれば、ログを見ながら推測に頼る必要がありません。