まず「通信の取り込み」と「出力ルール」を区別する

システムプロキシとTUNは、アプリの通信をClashのコアに渡すという共通の課題を解決します。コアに入った通信は、実行モードやルール、グループ設定に応じて、直接接続・プロキシ経由・遮断のいずれかに振り分けられます。TUNを有効にしても全通信がプロキシ経由になるわけではなく、システムプロキシを有効にしてもすべてのプロセスが設定に従うとは限りません。

この記事では、mihomoコアを使用するClashクライアントを例に説明します。TUNの実装はクライアント、コア、OSによって異なるため、特定のクライアントの設定名をすべてのソフトに当てはめることはできません。操作前にクライアントのコア情報でmihomoが実際に動作していることを確認し、対応する設定項目を参照してください。

システムプロキシ:アプリからローカルポートへ接続

ブラウザーからClashへ通信を渡す仕組み

クライアントで「システムプロキシ」を有効にすると、通常はOSのHTTP・HTTPSプロキシ設定がローカルの待ち受けアドレスに変更されます。たとえば、設定の mixed-port: 7890 は、同じポートでHTTPプロキシとSOCKSリクエストを受け付けることを表します。7890 はあくまで例です。確認時は現在有効な設定を参照してください。

システムプロキシに対応したブラウザーは設定を読み込み、まず 127.0.0.1:7890 に接続します。HTTPSサイトへのアクセスでは、通常HTTPの CONNECT でトンネルを確立し、その中でTLS通信を行います。一般的なプロキシ転送では、サイトの通信を復号するためのルート証明書をブラウザーにインストールする必要はありません。

システムプロキシに対応したアプリ
  → 127.0.0.1:7890
  → mihomoのルール判定
  → DIRECTまたは選択したプロキシノード

OSの設定がすべてのアプリに適用されるとは限らない

そのため、「ブラウザーでは接続できるのに、ターミナルでは接続できない」からといって、必ずしもノードの障害とは限りません。両者が異なる経路で通信している可能性があります。同様に、WindowsのWinHTTPプロキシとユーザー向けのプロキシ設定は別の仕組みです。netsh winhttp show proxy の結果だけで、ブラウザーがプロキシを使っているかどうかは判断できません。

TUN:仮想ネットワークインターフェースとルートで通信を取り込む

TUNはレイヤー3の仮想ネットワークインターフェースです。有効にすると、クライアントまたは補助サービスが仮想ネットワークインターフェースを作成し、設定に応じてルートを変更します。対象のルートに一致するIPパケットはコアに送られて処理されるため、アプリがHTTPプロキシやSOCKSを理解している必要はありません。

アプリがIPパケットを送信
  → OSがルートを選択
  → TUN仮想ネットワークインターフェース
  → mihomoのネットワークスタックとルール判定
  → DIRECTまたは選択したプロキシノード

この経路を使えば、システムプロキシに従わないアプリの通信もルール判定に渡せます。ただし、あらゆるプロトコルがどのプロキシノードでも転送できるわけではありません。たとえばゲームのボイスチャットにはUDPが必要です。ノードのプロトコル、サーバー、関連設定がUDPに対応している必要があります。また、ICMPが期待どおり応答するかどうかから、HTTPSプロキシの正常性を直接判断することはできません。

よく使う3つの設定項目と役割

設定項目役割確認ポイント
auto-routeTUNへ向かうルートを自動設定社内VPNやほかの仮想ネットワークインターフェースと競合しないか
auto-detect-interface送信に使用するネットワークインターフェースを自動検出Wi-Fiと有線LANを切り替えたとき、適切なインターフェースが選ばれるか
stackTUNで使用するネットワークスタックを選択コアの対応状況とOSとの互換性を踏まえて選択

ネットワークインターフェースの作成やルートの変更には、通常、管理者権限、システムサービス、またはプラットフォームの許可が必要です。クライアントの「サービスモード」は、補助サービスにこれらの処理を任せるためのものです。プロキシサーバーを指すものではなく、サービスのインストールに成功してもノードが必ず使えるとは限りません。TUNを有効にするとすぐにオフに戻る場合は、ノードを調べる前に権限、サービス、ネットワークインターフェース作成のログを確認してください。

DNSとfake-ip:ドメイン名をルール判定に使う仕組み

システムプロキシを使う場合、アプリがドメイン名をそのままローカルプロキシに渡すこともあれば、先にローカルで名前解決することもあります。動作はアプリとプロキシプロトコルによって異なります。一方、TUNが受け取るのはIPパケットです。コアにドメイン名との対応情報がなければ、宛先IPだけからアプリが元々アクセスしようとしたドメイン名を常に正確に特定できるとは限りません。

fake-ipモードでは、ドメイン名に合成アドレスを割り当て、その対応関係を保持します。たとえばmihomoでよく使われる 198.18.0.0/16 は、このマッピング用の範囲であり、サイトの実際の接続先アドレスではありません。アプリが合成アドレスに接続すると、コアはドメイン名を特定し、DOMAIN-SUFFIX などのルールで判定できます。

設定例は既存のProfileに統合してください

以下は設定項目の関係を示すmihomo用YAMLの例です。ノードとグループ設定は含まれておらず、完全なサブスクリプションとしては使えません。IPv4のDNS設定例を使用しています。既存のProfileをそのまま置き換えたり、ファイル内に2つ目のトップレベル dns または tun を追加したりしないでください。クライアントがオーバーライドやマージを使う場合は、最終的に適用される設定を確認してください。

mixed-port: 7890
mode: rule

tun:
  enable: true
  stack: system
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53

dns:
  enable: true
  listen: 127.0.0.1:1053
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  nameserver:
    - 223.5.5.5

dns-hijack の any:53 は、TUNが取り込んだ対象の従来型DNSリクエストを横取りする設定です。デフォルトではUDPが対象です。TCP DNSも扱う場合は、コアのドキュメントに従って tcp://any:53 を追加できます。すべてのDNSプロトコルを強制的にローカルで名前解決する設定ではありません。ブラウザー内蔵のDoHは通常HTTPSを使うため、ポート53のルールだけでは取り込めません。

選び方:まずアプリの要件を確認

用途まず試す方法確認方法
ブラウザー、システムプロキシを参照するデスクトップアプリシステムプロキシWebページを開き、クライアントの接続ログに該当ドメインが表示されることを確認
単一のコマンドラインツールツール独自のプロキシ設定ローカルポートを明示して、プロキシを指定しない場合と結果を比較
システムプロキシを参照しないアプリTUNシステムプロキシをオフにしても、新しい接続がコアに入るか確認
ゲームやボイスチャットなどUDPを使うアプリTUNとUDP対応ノードUDP接続、グループの選択、実際の通信が正常か確認
社内VPNも併用する場合まず現在のネットワーク構成を維持社内ルート、ドメイン名の解決、アドレスの除外設定を確認し、項目ごとに有効化

システムプロキシとTUNは同時に有効化できますが、最初のトラブルシューティングではおすすめしません。システムプロキシに対応したアプリはローカルプロキシポートに接続し続け、ほかのアプリはTUNを通るため、接続ログがどちらも正常に見えても、どちらの方式が使われたのか判断しにくくなります。まず片方の経路を個別に確認してから、必要に応じて組み合わせてください。

「TUNを有効にすると遅延が下がる」という見方も、一般化できません。TUNが変えるのは端末側で通信を取り込む経路です。接続先の地域、回線の混雑、サーバーの状態はノードによって変わります。比較時は対象サイト、ノード、ルールモード、テストツールを固定し、ノード変更による差を仮想ネットワークインターフェースの効果と混同しないようにしてください。

切り替え手順:一度に変更するのは1項目

  1. 現在の設定を保存します。Profile名、ローカルポート、実行モード、グループの選択を記録します。カスタムオーバーライドもコピーしておけば、サブスクリプションの更新後に元へ戻せなくなるのを防げます。
  2. まずローカルプロキシの入口を確認します。TUNを一時的にオフにしてコアを起動したまま、プロキシを明示するコマンドでテスト用アドレスにアクセスします。失敗する場合は、ポート、ノード、ルールを先に確認してください。
  3. システムプロキシを確認します。システムプロキシを有効にしてブラウザーで同じアドレスにアクセスし、クライアントの接続画面でドメイン名、適用されたルール、実際の出力先を確認します。テスト後はシステムプロキシをオフにしてください。
  4. TUNだけを有効にします。クライアントの案内に従って権限を許可するかサービスを起動します。ネットワークインターフェースの作成やルートの設定に失敗したログがないことを確認してから、プロキシを設定していないアプリをテストしてください。
  5. 通常の用途以外の通信も確認します。LAN内の端末、社内ネットワーク、音声通話、スリープ復帰後の通信をテストします。直接接続のままにする必要がある通信が、誤ってリモートノードに送られていないことを確認してください。

コマンドでポートとルートの問題を切り分ける

以下のアドレスはテスト用の例です。Windowsでは curl.exe、macOSとLinuxでは curl を使用できます。例のポートは現在の設定値に置き換えてください。2つ目のコマンドでは今回のリクエストに対する明示的なプロキシ指定を解除しますが、TUNが有効な場合、パケットは仮想ネットワークインターフェースに取り込まれる可能性があります。

# ローカルHTTPプロキシの入口をテスト
curl --proxy http://127.0.0.1:7890 --connect-timeout 10 -I https://example.com/

# curlでプロキシを指定せず、システムのルート経路を確認
curl --proxy "" --noproxy "*" --connect-timeout 10 -I https://example.com/

HTTPステータスが返っても、そのリクエストに応答があったことがわかるだけで、プロキシを経由した証明にはなりません。クライアントの接続画面でリクエストが記録されているか、どのルールに一致したか、最終的な出力先が DIRECT かプロキシノードかも確認してください。ブラウザーが古い接続を再利用する場合があるため、切り替え後は既存の接続を閉じるか、テストするアプリを再起動してから確認します。

よくあるトラブルは入口・DNS・ルートの順に確認

システムプロキシは使えるが、TUNでは接続できない

Webは見られるが、ゲームや音声が使えない

まずアプリの通信がTUNに入っているかを確認し、次に選択中のノードがUDPに対応しているかを確認してください。Webの閲覧で主に確認できるのはTCPやブラウザー独自の通信経路です。ゲームのUDP通信が使えることの証明にはなりません。ノードの遅延テスト結果だけで判断するのも避けてください。テスト用URLへの接続成功と、実際のサービスで使うプロトコルの通信成功は別です。

クライアント終了後もインターネットに接続できない

まず、システムプロキシが待ち受けを停止した 127.0.0.1 のポートを参照したままになっていないか確認します。次にクライアントからTUNを正常に停止し、ルートとDNSの設定が元に戻ったことを確認してください。クライアントが異常終了した場合は再起動してから正常に終了します。それでも解決しないときはログを保存し、OSのネットワーク設定を一つずつ元に戻してください。ネットワークインターフェースやルートをまとめて削除するのは避けてください。