DNS リークとその誤解についての解説

DNS リークにまつわるよくある誤解をできるだけ整理し、システムプロキシおよび TUN 透過プロキシモードにおけるリークの原因を解説した上で、分流ルールの最適化と fake-ip モードによってリークを根本から回避する実践的な方法を紹介します。

この記事をクリックした方は、おそらく DNS リークという概念について一度は耳にしたことがあるでしょう。中には DNS リークという言葉を聞くだけで顔色を変える人も少なくありません。コメント欄や Issue で関連する質問をしてきた方がすでに何人もいたので、今回この問題をできるだけ明確に説明する記事を書き、この概念についてよくある誤解を整理し、皆さんが自分でプロキシ設定を書く際の参考にもなればと思います。

この概念は、一部の VPN ベンダーや大量の YouTuber によってすでに散々語られ尽くしています。基本的な意味はこうです:プロキシを使っている最中でも、パソコンはローカルネットワーク経由でローカル DNS にアクセス先のドメイン名を問い合わせてしまい、通信事業者は DNS クエリの記録からあなたの閲覧履歴を把握できてしまう、というものです。

まず何が必要なのかをはっきりさせる

まず考えておくべきなのは、そもそも私たちが苦労して DNS リークを防いでいるのは一体何のためなのか、ということです。多くの人の第一反応はおそらく「そんなの当然、検閲者にプロキシ経由でどのサイトにアクセスしたかを知られないためでしょう!」というものでしょう。

実はこの説明は完全には正確ではなく、状況によって変わってきます。少し考えてみてください:検閲者にあなたが Douyin1 を見たり WeChat でチャットしたりしていることを知られたところで、実質的な害があるでしょうか。おそらくないでしょう。しかし、あなたが Wikipedia にアクセスしたり、X(旧 Twitter)を見たり、あるいは明確に政治的な傾向を持つセンシティブなコンテンツを閲覧していることを検閲者に知られてしまったら、それはかなり大きな問題になります。DNS リークを防ぐ目的は、決していわゆる「DNS リークテスト」サイトで全項目グリーンの満点を取ることでも、国内でよく使うサービスを利用している事実を隠すことでもなく、封鎖されている、あるいはセンシティブとみなされているサイトやサービスへのアクセスを検閲者に知られないようにすることなのです。

「壁」の内側で暮らす私たちにとって、何がセンシティブなコンテンツかを見分けるのは実はとても簡単です。GFWList23 を直接参照すればいいのです。グレート・ファイアウォール(GFW)がわざわざ目をつけて重点的に対処してくるものであれば、当然センシティブなコンテンツだということになります。

これらの DNS リークテストサイトが使うランダムなドメイン名は、GFWList の端にも引っかからないほどで、そもそもセンシティブ性など皆無です。うまく最適化されたプロキシ設定であれば、このようなドメインはまともに目もくれられず、通常はそのまま最後のフォールバックルール(例えば MATCH, DIRECT)に流されて処理されます。この過程で自然にローカル DNS 解決が発生するわけです。すると、テストサイトはまるで大発見をしたかのように赤信号を灯し、「DNS リークが存在します」と警告してきます。しかし仕組みを理解している私たちからすれば、こうしたいわゆる「リーク」の多くは実際には何の痛痒もないものだと分かります。設定が適切であれば、本当に保護すべきセンシティブなアクセス履歴は、すでに前段の分流ルールにマッチして安全に暗号化トンネルへ送り込まれているからです。

さらに悪いことに、Surfshark や ExpressVPN といった海外の商用 VPN ベンダー、そしてスポンサー案件で稼ぐ質の悪い YouTuber の一群は、こうした実質的な意味のないテスト結果を使って、事あるごとにプライバシーへの不安を煽り立てています。滑稽なのは、こうした従来型の商用 VPN クライアントの多くが、そもそも最も基本的なドメイン単位の分流ルール機能さえ持たず、すべてのネットワークリクエストを力任せに仮想ネットワークアダプタへ丸ごと押し込んでいるだけだということです。さらに皮肉なのは、このような単純で粗雑な全体プロキシ方式であっても、彼ら自身のクライアントソフトの欠陥によって、過去に本物の DNS リークを実際に引き起こしたことがあるという点です。ですから、こうした不安を煽るだけのマーケティングを鵜呑みにするより、プロキシソフトの動作原理を自分で理解しておく方がよほど有益です。

リークが発生する場面

実際、現在主流のプロキシソフトはかなり成熟しており、適切に設定すれば DNS リークをまったく心配する必要はありません。問題は、多くの設定がそもそも適切ではないという点にあります。次に、システムプロキシモードと透過プロキシ(仮想ネットワークアダプタ)モードにおいて、プロキシソフトで DNS リークが発生し得る場面を簡単に説明します。

プロキシソフト自体の問題

システムプロキシを使用する場合(プロキシアドレスが socks5://127.0.0.1:78904 だと仮定します)に、ブラウザで https://www.example.com にアクセスすると、以下のようなリクエストの流れになります。

  • 第一段階:ブラウザがネットワークリクエストをパッケージ化し、socks5://127.0.0.1:7890 に送信する
  • 第二段階:プロキシソフトがリクエストを受け取り、設定された分流ルールに従ってノードをマッチングする
  • 第三段階:プロキシソフトがマッチング結果に基づいてリクエスト全体をノードへ転送する

このリクエスト全体の過程において、ブラウザはネットワークリクエストをパッケージ化してプロキシに渡すだけで、ローカル DNS へクエリを発行しないため、この段階では DNS リークは発生しません。プロキシソフトがネットワークリクエストをサーバーへ転送する過程も全体が暗号化されているため、こちらも DNS リークは発生しません。実際に DNS リークが発生するのは、分流ルールのマッチング過程においてです。

ローカル DNS にドメイン名の問い合わせを発行すること自体は必ずしも悪いことではありませんが、設定が適切でない分流ルールは、プロキシソフトがドメイン名を取得した時点で早々にローカル DNS へ問い合わせを発行させてしまい、本来漏らすべきでないプライバシー情報を漏らす結果につながります。極端な仮定の話ですが、たとえばゲシュタポ5が通信事業者からすべての人の DNS クエリ記録を取得し、GFW の封鎖リストに含まれるドメインを問い合わせたことがある者は全員銃殺する、という状況を想像してみてください。こうした状況において自分の身を守るためには、分流ルールを適切に設定しておく必要があるわけです。

広く使われている Mihomo カーネルを例に挙げると、クライアントとしてシステムプロキシモードを有効にし、Chrome が前述の第二段階に到達した時点で、カーネルが既に把握している情報は次のとおりです。

  • ホスト6example.com
  • 対象ポート:443
  • ネットワークプロトコル:TCP
  • リクエストを発行したプロセスの名前と具体的なパス:C:\Application\chrome.exe
  • インバウンド IP:127.0.0.1
  • インバウンド名:DEFAULT-MIXED
  • インバウンドポート:ランダムな高位ポート

カーネルは余計な DNS リクエストを発行しません。既知の情報に基づいて、DNS 解決を行わなくても、ドメイン名・ポート・プロセス名・ネットワークプロトコルに基づくすべてのルーティングルールをマッチングできます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
rules:
  # ドメイン名ベースのマッチングルール
  - DOMAIN,ad.com,REJECT
  - DOMAIN-SUFFIX,google.com,auto
  - DOMAIN-KEYWORD,google,auto
  - DOMAIN-WILDCARD,*.google.com,auto
  - DOMAIN-REGEX,^abc.*com,PROXY
  - GEOSITE,youtube,PROXY
  # ポートベースのマッチングルール
  - DST-PORT,80,DIRECT
  - SRC-PORT,7777,DIRECT
  # プロセス名ベースのマッチングルール
  - PROCESS-PATH,/usr/bin/wget,PROXY
  - PROCESS-PATH,C:\Application\chrome.exe,PROXY
  - PROCESS-NAME,curl,PROXY
  - PROCESS-NAME,chrome.exe,PROXY
  # ネットワークプロトコルベースのマッチングルール
  - NETWORK,UDP,REJECT
  # どの情報にも依存しないマッチングルール
  - MATCH,DIRECT

したがって、上記のような種類のルールは DNS リークを引き起こしません。カーネルがこれらをマッチングする際、そもそも DNS 解決を行う必要がないからです。

残りの種類のルールについては、第二段階で対象の IP 情報を把握してからでないとマッチングを進められません。

1
2
3
4
5
rules:
  - GEOIP,cn,DIRECT
  - IP-CIDR,127.0.0.0/8,DIRECT
  - IP-SUFFIX,8.8.8.8/24,PROXY
  - IP-ASN,13335,DIRECT

デフォルトでは、マッチングの精度を保証するため、第二段階に進んだ時点でカーネルは対象の IP を知らず、対象のホストアドレス www.example.com しか知りません。そのため、カーネルは www.example.com の IP アドレスを問い合わせるしかなく、これが DNS リークを引き起こす原因になります。ルールの末尾に no-resolve7 を付けておけば、IP ベースのルールにマッチする際にそのルールを直接スキップするようになるため、no-resolve は Telegram などのソフトの裸 IP リクエストを分流するのに非常に適しています。

透過プロキシの問題(TUN モード8

透過プロキシとは、その名の通り、プロキシされる側のシステム/ソフトウェアが自分がプロキシされていることに気づかない方式のプロキシです。この方式は非常に手間がかからず、TUN モードを一度オンにすればすべてのソフトが使えるようになり、システムプロキシに従わないソフトを一つひとつ煩わしく設定する必要がありません。その代償は、この手軽さそのものにあります。対象のシステム/ソフトウェアは自分がプロキシされていることを知らないため、通常のネットワーク上での本来の挙動をそのまま続けます。当然そこには DNS 解決も含まれます。しかし対象のシステム/ソフトウェアは自分がプロキシされていることを知らないので、リモート側と接続を確立するにはまず IP を手に入れる必要があります。この問題を解決するため、Mihomo を例にとると、redir-hostfake-ip という 2 つの DNS ハイジャックモードが用意されています。

redir-host モード:

fake-ip モード:

このうち redir-host はいわば「素直」な方式です。対象のシステム/ソフトウェアが DNS クエリを発行したのであれば、律儀に上流 DNS へ問い合わせを行い、得られた実際の IP をそのまま対象のシステム/ソフトウェアへ返します。このモードでは必ず一度、実際の DNS 解決による問い合わせ過程が発生してしまうため、構造的に先天的な欠陥を抱えており、DNS リークを避けられません。もともとの Clash カーネルは、後のバージョンアップで redir-host モードを完全に切り捨ててしまいました。

とはいえ、Clash Meta カーネルを継承した Mihomo カーネルはこれを残す選択をし、さらに sniffer9 を追加してこれを強化しました。redir-host モードにおいて、sniffer はデータパケット中の特徴(例えば TLS の SNI フィールド10など)を嗅ぎ取ることで、裸 IP に解決されてしまったトラフィックから接続先のドメイン名を復元しようと試み、復元したこのドメイン名を使って改めて分流ルールのマッチングを行うことで、redir-host モードの分流面における多くの弱点を補っています。ただし、ここで特に注意すべき点があります:sniffer が解決するのは分流精度の問題であり、DNS リーク自体を解消するものではありません。DNS クエリのリクエストは sniffer が介入する前にすでに発行されてしまっており、通信事業者が記録すべきものはすでに記録済みなのです。

なお、ここで一つ注意しておきたいのは、透過プロキシの環境下でどうしても redir-host モードを使い続けたい場合は、汚染されていない DNS のセットを別途構築する必要があるということです。具体的な例については、私の別記事を参考にしてください。そうしなければ、あなたの DNS アクセス履歴は依然として漏れてしまいます。

一方、fake-ip モードはこれとはまったく異なる解決アプローチを採用しており、透過プロキシ環境下での DNS リーク問題を完璧に回避するだけでなく、ブラウザのウェブページ応答速度をついでに向上させることさえできます。

DNS リークを回避する方法

プロキシソフトに与える分流ルールの最適化

前述の通り、不適切な分流ルールはプロキシソフトに早々と解決を発生させてしまいます。典型的な悪い例を挙げます。

1
2
3
4
5
rules:
  - GEOIP,cn,DIRECT
  - GEOSITE,telegram,Telegram
  - GEOIP,telegram,Telegram
  - MATCH,Proxy

問題は 1 行目の GEOIP,cn,DIRECT にあります。デバイスが telegram.org というドメインをリクエストすると、カーネルは上から下へ順にマッチングを行い、最初に来るのが IP ルールです。しかしドメイン名は IP ではないため、それが中国大陸の IP レンジに含まれるかどうかを判定するには、カーネルはまず telegram.org を解決してみるしかありません。この解決の瞬間に DNS クエリが発行されてしまいます。たとえ次の 2 行目 GEOSITE,telegram が本来そのまま直接マッチできたはずで、IP を知る必要すらなかったとしても、です。

解決リクエストが一度発行されてしまえば、その時点で通信事業者側に記録が残ります。その後どのルールにマッチしようと、プロキシを経由しようとしまいと、もはや関係ありません。どうであれ、あなたが Telegram にアクセスしていることは通信事業者に知られてしまっているのです。

ルールマッチングは上から下へ順番に行われます。カーネルはリクエストを受け取るたびに、マッチするまで一行ずつ照合していきます。つまり、あるドメイン名がより前にあるルールにマッチしてしまえば、その後のルール、2 行目、3 行目、たとえ 1000 万行目であっても、二度と実行されることはありません。

まさにこの理由から、ルールを書く際にはドメインルールを先、IP ルールを後にする原則を守るべきです。ある特定のサービス専用のルールセットであっても、その中で先頭に近い位置にある IP ルールには no-resolve フラグを付け、そのルールにマッチしなければスキップする、解決のために動く必要はないと、カーネルに伝えるべきです。典型的な例を示します。

1
2
3
4
5
6
7
DOMAIN-SUFFIX,e-hentai.org
DOMAIN-SUFFIX,ehgt.org
DOMAIN-SUFFIX,ehwiki.org
DOMAIN-SUFFIX,exhentai.org
DOMAIN-SUFFIX,hath.network
DOMAIN-SUFFIX,hentaiverse.org
IP-CIDR,178.175.128.0/21,no-resolve

GeoSite や GeoIP のデータベースを使う場合も同様で、先頭に近い IP ルールにはすべて no-resolve を付ける必要があります。

1
2
3
4
5
6
rules:
  - GEOSITE,telegram,Telegram
  - GEOIP,telegram,Telegram,no-resolve
  - GEOSITE,gfw,Proxy
  - GEOIP,cn,DIRECT
  - Match,Proxy

このルールセットを先ほどの悪い例と比較すると、違いは DNS 解決がいつ発生するかというタイミングにあります。

同じく telegram.org へのリクエストですが、今回は 1 行目が GEOSITE,telegram で、ドメイン名が直接マッチし、リクエストはそのままプロキシへ渡され、DNS には一切触れません。GFW リストに載っている他のサイトへのアクセスも同様で、先に GEOSITE,gfw,Proxy にヒットし、解決を避けられない GEOIP,cn,DIRECT に到達する前に、リクエストはすでにノードへ送り込まれています。プロキシを通すべきものはすでに早々とプロキシを通っていて、後段の IP ベースのルールには順番すら回ってこず、DNS が漏れる機会そのものがなくなるわけです。

Fake-IP を使って透過プロキシの問題を回避する

fake-ip モードは透過プロキシ下での DNS リーク問題を解決し、ついでにブラウザのウェブページ応答速度も向上させます。

fake-ip モードで透過プロキシを行う場合、対象ソフトが DNS クエリを発行しても、プロキシソフトは律儀にローカルやリモートの上流へ実際の IP を問い合わせにいくことはしません。代わりに、その場で即座にローカルから偽の内部予約 IP(例えば 198.18.0.211)を返します。対象ソフトはこの偽の IP を本物だと思い込み、すぐにこの偽の IP を使って接続を確立しようとします。

一方プロキシソフト側では、自分が発行したこれらの偽 IP 宛てのリクエストをすべて傍受するだけで済みます。プロキシソフトは内部に「偽 IP と実際のドメイン名の対応表」を詳細に保持しているため、対象ソフトから送られてくるパケットの宛先が偽 IP であっても、プロキシソフトはあなたが実際にアクセスしたいドメイン名を正確に把握しています。そこでプロキシソフトは元のドメイン名を取り出し、ネットワークリクエストを暗号化プロキシトンネル経由でリモートノードへ送って処理させます。

この仕組みによって、redir-host モードにおける「透過プロキシ下では必ずドメイン名の問い合わせ記録が外部ネットワークへ露出してしまう」という構造的な欠陥が解決されます。ただし指摘しておくべきは、fake-ip が回避しているのは、対象ソフトが自ら DNS クエリを発行することで生じるリークのリスクだけだという点です。前述したように、分流ルールの設定が不適切であれば、プロキシカーネル自身が依然として上流に対して実際の DNS 解決を能動的に発行してしまい、リークにつながります。分流ルールが適切に設定されている前提であれば、fake-ip モードは検閲者にあなたの本当のアクセス先を覗き見る手段を与えないだけでなく、ローカル端末が実際の DNS レスポンスを待つ時間そのものが不要になるため、ページアクセスの Time To First Byte(TTFB12)を大幅に短縮するというおまけの効果までもたらしてくれます。まさに一石二鳥です。

長すぎて読みたくない人向け(まとめ)

DNS リーク自体は怖いものではありません。本当に怖いのは、仕組みを理解せずに不安を煽るマーケティングに振り回されてしまうことです。仕組みを理解すれば、対処の方針はかなり明確になります。

  • システムプロキシモード:「ドメインルールを先、IP ルールを後」の原則に従い、すべての IP 系ルールに no-resolve を付けることで、センシティブなドメインは DNS 解決が発生する前にすでに分流されているようにします。
  • TUN 透過プロキシモードfake-ip を優先的に採用することで、DNS クエリの外部への漏出を根本から断ち、さらに TTFB の低減という恩恵も得られます。どうしても redir-host を使い続けたい場合は、汚染されていない上流 DNS を必ず組み合わせ、sniffer は分流の精度を改善するだけで、DNS リクエスト自体の漏出を防ぐことはできない点を理解しておく必要があります。
  • リークテストサイトを過信しない:テストで使われるランダムなドメイン名はそもそも GFW の封鎖リストに載っていないため、ローカル解決が発生するのは正常かつ無害な挙動です。緑のチェックが並ぶかどうかは、設定の質を測る基準にはなりません。

  1. 訳注:Douyin は ByteDance が中国国内向けに提供する短編動画アプリで、同じく ByteDance が運営する海外向けの TikTok とは別のアプリです。両者はコンテンツやユーザー層も異なる独立したサービスです。 ↩︎

  2. 訳注:GFWList とは、中国のグレート・ファイアウォールによって封鎖されているドメインをまとめた公開リストで、プロキシソフトがどのサイトをプロキシ経由でルーティングすべきかを判断する際によく利用されます。 ↩︎

  3. 中国大陸のグレート・ファイアウォール(Great Firewall, GFW)によって封鎖されているドメインのリスト。 ↩︎

  4. SOCKS5 はネットワークプロキシプロトコル(RFC 1928)で、セッション層で動作し、TCP と UDP の両方の転送をサポートします。また、クライアントがドメイン名をそのままプロキシサーバーに渡して解決させることができ、ローカルで解決してから接続するのではありません。これこそが、通常の HTTP プロキシ(CONNECT トンネルモードを除く)に比べて、DNS リーク防止の点で優れている核心的な特徴です。 ↩︎

  5. 訳注:これは笑いを狙った意図的に極端かつ非現実的な仮定であり、実際の比較を意味するものではありません。著者は VPN マーケティングの不安煽り(フィアモンガリング)を、極端に誇張することで風刺しています。  ↩︎

  6. ドメイン名だと理解して構いません。 ↩︎

  7. no-resolve は IP 系ルールの末尾に付加するフラグで、トラフィックの対象がドメイン名であって IP でない場合に、そのルールをマッチさせるために能動的に DNS 解決を発行しないよう、カーネルに指示する役割を持ちます。ただし、トラフィック自体が直接 IP に接続するもの(例えば Telegram クライアントがサーバーの IP へ直接接続する場合)であれば、このルールは通常どおりマッチング処理に参加します。 ↩︎

  8. いわゆる仮想ネットワークアダプタモードのことです。 ↩︎

  9. トラフィックスニッフィング(Sniffer)とは、プロキシソフトがデータパケットのプロトコル的特徴を検査することで、対象のドメイン名を復元する技術です。例えば、HTTPS 接続はハンドシェイク段階で対象のドメイン名(SNI)を平文で送信し、HTTP リクエストヘッダーにも Host フィールドが含まれています。プロキシソフトはこうした特徴から実際の対象ドメイン名を抽出できます。 ↩︎

  10. Server Name Indication、TLS プロトコルの拡張フィールドです。同じ IP 上に複数の HTTPS サイトがホストされている場合があるため、クライアントは TLS ハンドシェイクの ClientHello 段階で、どのドメインにアクセスしたいのかを平文でサーバーに伝える必要があり、それによってサーバーは正しい証明書を返すことができます。これが、HTTPS を使っていても、途中経路にいる者があなたがアクセスしているドメイン名を見ることができてしまう理由です(ただし具体的なパスや内容までは見えません)。 ↩︎

  11. Mihomo はデフォルトで 198.18.0.0/15 のアドレス帯を使って偽 IP を割り当てます。この帯は IANA が RFC 2544 で予約しているもので、ネットワーク機器のベンチマークテスト専用とされており、通常のインターネットのルーティングテーブルには一切出現しないため、実在するパブリックアドレスと衝突することはありません。この /15 帯全体では、マッピング用として約 131,072 個のアドレスを提供できます。 ↩︎

  12. Time To First Byte、クライアントがリクエストを発行してからサーバーのレスポンスの最初の 1 バイトを受信するまでにかかる時間のことです。従来の方式では、ブラウザはまず DNS 解決の完了(通常 20〜120ms 程度かかる)を待たなければ TCP 接続を開始できませんが、fake-ip モードでは DNS レスポンスがほぼ即時(1ms 未満)で返るため、ページ全体の読み込み時間を大幅に短縮できます。 ↩︎

Licensed under CC BY-NC-SA 4.0
最終更新 2026 年 7 月 15 日 13:05 +0800
本ウェブページの日本語版は、生成系大規模言語モデル(LLM)によって簡体字中国語版の内容を翻訳したものです。その内容は「乱筆」による確認、校正および承認を経ておりません。ご利用の際には、いかなる場合でも本日本語版を簡体字中国語版または英語版と同等と見なさないようご注意ください。
Hugo で構築されています。
テーマ StackJimmy によって設計されています。