TUN モードとシステムプロキシの仕組み比較:トラフィックはどの層で奪われるのか
システムプロキシがアプリの設定読み取りに依存するのに対し、TUN は仮想ネットワークカードで全 IP トラフィックを捕捉する違いを解説。コマンドラインツール・ゲーム・UDP アプリで挙動が変わる理由と、それぞれに向く用途を整理します。
先に結論をまとめると
システムプロキシと TUN モードは働く層が異なります。システムプロキシはアプリケーション層の取り決めで、OS がプロキシアドレスを設定に書き込み、アプリがそれを読み取って初めてプロキシ経由になります。TUN モードはネットワーク層での捕捉で、mihomo が仮想ネットワークカードを作成し、カーネルが条件に合う IP パケットをすべてそのカードに送り込みます。アプリはプロキシの存在を知らず、回避することもできません。
要するに、システムプロキシはアプリの協力が必要、TUN モードはカーネルのルーティングに依存します。コマンドライン・ゲーム・UDP の場面で両者の挙動がまったく異なるのは、この根本的な違いがあるからです。
システムプロキシ:アプリが設定を読み取って初めて有効
システムプロキシを有効にすると、Windows では「設定」→「ネットワークとインターネット」→「プロキシ」にアドレスが書き込まれ、macOS では「システム設定」→「ネットワーク」→「プロキシ」に同じ情報が書き込まれます。mihomo はデフォルトで 127.0.0.1:7890 で混在ポートを待ち受け、HTTP と SOCKS5 の両方の接続を受け付けます。
重要なのは次の段階です。アプリが自らシステムにプロキシ設定を問い合わせ、そのアドレスで実際に接続を確立しなければなりません。ここで挙動は4つに分かれます。
- ブラウザや多くの Electron アプリはシステムのネットワーク API を使うため設定を読み取り、システムプロキシが有効に機能します。
- ゲームエンジンは socket を直接生成することが多く、システムプロキシを参照せずそのまま直結します。
curl、wget、gitは Windows と macOS ではデフォルトでシステムプロキシを読まず、http_proxy/https_proxy環境変数しか認識しません。- すべての UDP トラフィック:HTTP プロキシは TCP のみを扱います。SOCKS5 には UDP ASSOCIATE 拡張がありますが、ほとんどのアプリは実装していません。
つまり「プロキシを有効にしたのにターミナルで curl が直結のまま」というのは設定ミスではなく、システムプロキシの仕組み上の限界です。比較すると次のとおりです。
| トラフィックの種類 | システムプロキシ | TUN モード |
|---|---|---|
| ブラウザの HTTP/HTTPS | 捕捉 | 捕捉 |
| コマンドラインの curl / git / brew | 捕捉しない(環境変数が必要) | 捕捉 |
| ゲーム・音声の UDP | 捕捉しない | 捕捉 |
| QUIC / HTTP/3 | 捕捉しない(ブラウザは TCP にフォールバック) | 捕捉 |
| LAN 内デバイスからのアクセス | 影響なし | 社内・ローカル網の除外設定が必要 |
TUN モード:仮想ネットワークカードが IP 層を捕捉
TUN はカーネルが提供する仮想ネットワークデバイスです。mihomo が TUN を有効にすると仮想ネットワークカードを作成します。Windows では wintun ドライバー、macOS では utun、Linux では tun を使用し、さらにルーティングテーブルを書き換えて、自ホスト以外の宛先 IP パケットをこのカードへ向けます。
これによりトラフィックの経路は次のように変わります。
- アプリがデータをカーネルに渡す。
- カーネルがルーティングテーブルに従って仮想ネットワークカードへ送る。
- mihomo がユーザー空間で完全な IP パケットを読み取る。
- TCP または UDP を解析し、ルールに照合する。
- ノード経由で外部へ転送する。
捕捉する層はネットワーク層(L3)であり、アプリケーション層(L7)ではありません。mihomo はアプリがどうデータを送るかには関知せず、IP パケットとしてしか見ていません。直接の結果は3つです。アプリは自分がプロキシ経由であることに気づかない。TCP と UDP が平等に扱われる。プロセスがどの言語・どのネットワークライブラリを使っていても、ルーティングテーブルから逃れられない。
代償も明確です。仮想ネットワークカードの作成には管理者権限または root 権限が必要です。ルーティングテーブルが書き換わるため、社内 LAN やローカルネットワークへのアクセスには別途の許可設定が必要になります。
DNS も TUN モードで見落としがちなもう一つのポイントです。TUN 設定の dns-hijack は 53 番ポート宛てのクエリをすべてローカル解決に乗っ取り、enhanced-mode: fake-ip と組み合わせることでドメイン解決もプロキシ経路を通り、DNS リークを防ぎます。Clash Verge のデフォルト設定を例にすると:
tun:
enable: true
stack: mixed
dns-hijack:
- any:53
dns:
enable: true
enhanced-mode: fake-ip
nameserver:
- https://doh.pub/dns-query
有効にすると、直結できないドメインの解決結果は 198.18.0.0/16 レンジの Fake-IP になり、実際の解決はリモートの DoH が行います。これは TUN が本当に機能しているかを確認する直感的なサインです。
コマンドライン・ゲーム・UDP:2つのモードの分かれ目
コマンドラインツール
git clone、curl、brew、npm、go install はシステムプロキシモードではすべて直結になります。システムプロキシだけではこれらをカバーできないため、環境変数を手動でエクスポートする必要があります。
export https_proxy=http://127.0.0.1:7890
export http_proxy=http://127.0.0.1:7890
export all_proxy=socks5://127.0.0.1:7890
7890 は混在ポートで HTTP と SOCKS5 が共用されます。上の3行で git、curl、npm が同じ入口を通ります。TUN モードではこの手順は不要で、環境変数が残っていると逆にプロキシが二重にかかるため、削除することをおすすめします。
ゲームと UDP
ゲームのマッチング、ボイスチャット、状態同期では UDP が多用されます。システムプロキシはプロトコル上 UDP を扱いません。SOCKS5 を有効にしても、ゲームクライアントが UDP ASSOCIATE を実装することはほとんどありません。そのため「ログインできるのにマッチングできない」「ボイスが途切れる」といった半端な状態がよく起こります。TUN は UDP パケットをそのまま仮想ネットワークカードに取り込み、ルールに従って転送するため、直結に近い挙動になります。
QUIC と HTTP/3
Chrome や Safari は HTTP/3 対応サイトでは QUIC(UDP/443)を優先的に試します。システムプロキシではブラウザがプロキシの UDP 非対応を検知して TCP に自動フォールバックします。TUN では QUIC トラフィックがそのまま捕捉されるため、フォールバックは発生しません。
シーン別比較:どちらを使うべきか
| シーン | 推奨モード | 理由 |
|---|---|---|
| 日常のウェブ閲覧 | システムプロキシ | 管理者権限が不要でリソース消費も少ない |
| 開発・コマンドライン作業 | TUN モード | git / npm / curl を一括でカバー |
| ゲーム・ボイスチャット・ビデオ通話 | TUN モード | UDP はネットワーク層での捕捉が必要 |
| 社内 LAN とプロキシの併用 | システムプロキシ + ルール | ローカル網を捕捉せずポリシーを制御しやすい |
| アプリに管理者権限を要求できない環境 | システムプロキシ | TUN のネットワークカード作成には権限昇格が必要 |
| 全体のパケットキャプチャ・全量テスト | TUN モード | 全プロセスが同じ経路を通る |
切り替え前のチェックリスト
- 疎通確認:
curl -I https://www.gstatic.com/generate_204で検証します。ping は使わないでください。ICMP が捕捉されるかどうかはノードとスタックに依存し、プロキシの有効性を判断する根拠にはなりません。 - DNS:直結できないドメインを解決して
198.18.x.xが返れば Fake-IP が機能しています。実際の IP が返る場合はdns-hijackとenhanced-modeを確認してください。 - LAN:プリンター、NAS、ルーターの管理画面が TUN で横取りされることがあります。
tunセクションにroute-exclude-address: 192.168.0.0/16を追加するか、ルールで直結にしてください。 - Windows の互換性:ゲームや P2P で接続できない場合は、
stack: system→gvisor→mixedの順に切り替えて再テストしてください。 - 環境変数の残り:システムプロキシモードでターミナルから
env | grep -i proxyを実行し、残っていればunsetしてください。残したままだとコマンドラインが古いプロキシを使い続けます。
よくある誤解:TUN を有効にした後にシステムプロキシも有効にするケースです。両者は重複せず、ブラウザのトラフィックが 7890 を経由して戻ってくるだけで遠回りになります。TUN モードではシステムプロキシのスイッチをオフにするのが最短経路で、問題の切り分けもしやすくなります。