TUNとシステムプロキシ:通信を取り込む仕組みの違い

ClashのTUNモードは仮想ネットワークインターフェースでIPパケットを受け取り、カーネルで解析してルールに照合したうえで、外部への接続を確立します。一方、システムプロキシはアプリにHTTPまたはSOCKSプロキシの接続先を提供する仕組みで、アプリ側がプロキシ設定に従う必要があります。そのため、ブラウザーは通信できるのにコマンドラインツールやゲーム、一部のデスクトップアプリではプロキシが使われない場合、原因はノードではなく通信を取り込む経路にある可能性があります。

この記事の設定例は、Clash Metaの後継として開発されているmihomoカーネルを対象としています。Clashという名前のクライアントでも、同じカーネルが使われているとは限りません。旧Clash、旧Premium、mihomoでは対応する設定項目も異なるため、まずクライアントのカーネル情報または起動ログでmihomoが動作していることを確認し、使用中のカーネルが対応する項目に合わせて設定してください。

比較項目システムプロキシTUNモード
通信を取り込む場所アプリのプロキシインターフェースシステムルーティングと仮想ネットワークインターフェース
アプリ側の要件システムプロキシに従うか、個別に設定する必要がある該当するルートを通る通信を取り込める
UDP通信通常のHTTPシステムプロキシでは一律に処理できない取り込み可能。プロキシの出口側もUDPに対応している必要がある
必要な権限通常、仮想NICを作成する権限は不要通常、管理者権限・特権サービス・ネットワーク権限のいずれかが必要
通信の振り分け基準カーネルのルールで決まるカーネルのルールで決まる

有効化前に確認すること:ノード・権限・設定の保存先

  1. まず基本の接続を確認します。システムプロキシを使って、接続できることがわかっているサイトにアクセスします。サブスクリプションが読み込まれ、プロキシグループに利用可能なノードがあることも確認してください。TUNを有効にしても、期限切れのサブスクリプションやノードの認証失敗、サーバー停止は解決できません。
  2. 現在の設定をバックアップします。モード、DNS設定、既存のルーティングを控えておきます。クライアントによってはサブスクリプションから実行用設定を生成するため、生成ファイルを直接編集すると更新時に変更が失われます。クライアントのオーバーライド、マージ、永続設定の機能を利用してください。
  3. ほかの通信制御ツールを一時停止します。デフォルトルート、DNS、ファイアウォールルールの競合を避けるため、ほかのVPNや通信高速化ツール、仮想NICを使うプロキシをいったん終了します。切り分けが終わったら、ひとつずつ再開してください。
  4. ローカルで操作できる状態を確保します。ルーティングの変更でリモートデスクトップやSSH接続が切れることがあります。初回の有効化は端末の前で行い、唯一のリモート接続からルートを変更しないでください。

メニュー名はクライアントによって異なります。特権サービスが利用可能であること、TUNが有効であること、実行設定に正しいtunセクションがあることの3点を確認してください。画面上のスイッチがオンになっているだけでは、仮想NICの作成が成功したとは限りません。

mihomoのTUN設定:stack・ルーティング・DNS

以下は既存のmihomo設定にマージして使う例で、ノードやプロキシグループを含む完全なサブスクリプション設定ではありません。既存のプロキシ設定とルールはそのままに、通信の取り込み口とDNSだけを示しています。トップレベルにdnsやtunがすでにある場合は、同じキーを重複して定義せず、項目をマージしてください。

mode: rule

tun:
  enable: true
  stack: mixed
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53

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

stack:まずmixedを試し、問題に応じて切り替える

mihomoでは、TUNのプロトコルスタックとしてsystem、gvisor、mixedなどを選べます。mixedはTCPをsystemスタック、UDPをgVisorスタックで処理するため、まず試す構成として適しています。OSやカーネルのビルドによって互換性は異なります。接続に問題がある場合は、同じ接続先で検証しながらスタックだけをひとつずつ切り替えてください。ノード、DNS、ルーティングを同時に変更しないようにしましょう。

スタックを切り替えても、ノードの通信機能は変わりません。端末でUDPを取り込めても、選択したプロキシプロトコルやサーバーがUDP転送に対応していなければ、ゲームのボイスチャットやQUICなどの通信は失敗することがあります。その場合は仮想NICを何度も入れ直すのではなく、出口側の対応状況を確認してください。

auto-route:ルートを設定する機能で、振り分けルールは変わらない

auto-route: trueを設定すると、カーネルがTUNへ向かうルートを自動で設定します。auto-detect-interface: trueは外部接続に使うネットワークインターフェースを自動判定し、プロキシサーバーへの接続が再びTUNに取り込まれてループするのを防ぐための設定です。有線LAN・Wi-Fi・仮想NICが共存する端末では、既存のルートによって自動判定が影響を受けることがあります。外部接続用のインターフェースを手動指定する場合は、実際のインターフェース名を確認し、使用中のカーネルが対応する方法で設定してください。

dns-hijack:通常のDNSを受け取る設定で、暗号化DNSをすべて処理するものではない

any:53はTUNに入るUDP 53番ポートのリクエスト、tcp://any:53はTCP 53番ポートのリクエストに対応します。該当する通信をカーネルのDNS処理に渡しますが、ブラウザー内蔵のDoHやアプリ独自のDoTを通常のDNSに戻す機能ではありません。検証時はブラウザーの「セキュアDNS」を一時的にオフにし、まずシステムの名前解決経路を確認してください。

例にある127.0.0.1:1053はローカルDNSの待ち受けアドレスです。システムプロキシのポートではなく、仮想NICのDNS欄にポート付きのアドレスを入力する必要もありません。TUNによるDNS横取りとローカルの待ち受けは別の経路です。fake-ipはカーネル内でのマッピングに使う仮想アドレスを返すため、198.18.0.0/16の範囲のアドレスが表示されても、それだけで異常とは判断できません。

Windows:サービスの権限を確認してから仮想NICを調べる

  1. ほかのVPNを終了します。「設定」→「ネットワークとインターネット」→「プロキシ」を開き、既存の手動プロキシ設定を控えてください。検証時に2種類の通信経路を混同せずに済みます。
  2. クライアントでサービスモードをインストールまたは有効にし、Windowsのユーザーアカウント制御の確認に応じて許可します。サービスモードがない場合は、権限の問題かどうかを確認するため、クライアントの案内に従って一時的に管理者として実行してください。
  3. TUNを有効にしてルールモードのまま、インターフェースの作成やルート設定に失敗したことを示すログがないか確認します。出所不明の場所からネットワークアダプターのドライバーを個別にダウンロードし、クライアント付属のコンポーネントと置き換えないでください。
  4. クライアントでシステムプロキシをオフにし、以下のコマンドでインターフェースとルートを確認して、実際に通信できるかテストします。テスト後、必要に応じてシステムプロキシを元に戻してください。
Get-NetAdapter -IncludeHidden |
  Format-Table Name, InterfaceDescription, Status

Get-NetRoute -AddressFamily IPv4 |
  Sort-Object RouteMetric |
  Format-Table DestinationPrefix, InterfaceAlias, NextHop, RouteMetric

Resolve-DnsName example.com
curl.exe --noproxy "*" -I https://example.com

以下のコマンドはPowerShellで実行します。--noproxy "*"を指定するとcurlはアプリケーション層のプロキシ設定を無視しますが、システムルーティングは迂回しないため、TUNの確認に役立ちます。ネットワークアダプター名はクライアントの設定によって異なるため、特定の名前が表示されるかどうかだけで判断しないでください。カーネルの接続記録にも、このアクセスが記録されているか確認します。

ログにアクセス拒否が記録されている場合は、まずサービスの権限を確認してください。インターフェースがあるのにリクエストがカーネルに届かない場合は、ルーティング、ほかのVPN、セキュリティソフトのブロック記録を調べます。ファイアウォール全体を無効にする方法を恒久的な解決策にしないでください。

macOS:補助サービスを許可し、utunインターフェースを確認

macOSでTUNインターフェースを作成してルートを変更するには、適切な権限が必要です。デスクトップクライアントでは通常、特権補助サービスを使って処理します。アプリの案内に従ってインストールまたは許可し、システムから求められた場合は「システム設定」→「プライバシーとセキュリティ」で確認してください。配布方法によって認証の仕組みは異なるため、特定のスイッチが見当たらないだけでインストール失敗と判断しないでください。

  1. まず通常のプロキシモードでノードへの接続を確認し、その後、クライアントの特権補助サービスとTUNを有効にします。
  2. TUNだけを検証するには、「システム設定」→「ネットワーク」→現在のネットワーク接続→「詳細」→「プロキシ」で、HTTP・HTTPS・SOCKSプロキシの状態を確認します。
  3. ターミナルでインターフェース、ルート、DNSを確認し、カーネルの接続記録でテスト通信に適用されたルールと出口を確認します。
ifconfig
netstat -rn -f inet
scutil --dns
curl --noproxy '*' -I https://example.com

utunインターフェースはmacOSの機能やほかのVPNによって作成されることもあるため、数だけではClash TUNが動作しているか判断できません。有効化前後のルートの変化とログの時刻を照合してください。macOSではインターフェースやドメインごとにDNSリゾルバーが割り当てられるため、システムDNSの状態を調べるには/etc/resolv.confだけを見るよりscutil --dnsが適しています。

Linux:/dev/net/tunとサービスの実行ユーザーを確認

LinuxではTUNデバイスが利用可能で、インターフェースの作成やルート変更に必要な権限があることを確認してください。通常はCAP_NET_ADMINが関係しますが、必要な権限はカーネル機能、サービスのサンドボックス、実行環境によっても異なります。デスクトップクライアントでは付属サービスがこれらの操作を実行できます。mihomoを直接実行する場合は、内容を確認したサービス設定を使い、出所不明のバイナリに安易に権限を付与しないでください。

ls -l /dev/net/tun
ip -br link
ip route show table all
ip rule show
resolvectl status

resolvectlはsystemd-resolvedを使うシステム向けです。ほかのディストリビューションでは、実際に使用している名前解決サービスを確認してください。mihomo.serviceというsystemdユニットがインストールされている場合は、以下のコマンドでサービスの状態と今回の起動ログを確認できます。ユニット名が異なる場合は、インストール時に設定された名前を使ってください。

systemctl status mihomo.service
journalctl -u mihomo.service -b --no-pager -n 100

ルートを確認するときは、メインのルーティングテーブルだけを見ないでください。自動ルーティングではポリシールーティングが使われる場合があるため、ip rule showとすべてのルーティングテーブルを確認します。コンテナ内のrootユーザーがホスト側のすべての権限を持つとは限りません。コンテナからTUNデバイスを適切に利用できるようにし、必要な機能を設定してください。権限を検討せず、安易に特権コンテナを有効化するのは避けましょう。

検証手順:通信の取り込み・ルール・出口を個別に確認

  1. 通信が取り込まれているか確認します。システムプロキシをオフにして前述のcurlリクエストを実行し、カーネルの接続記録を確認します。対象ドメインまたは対象IPが記録されていれば、リクエストはカーネルに届いています。Webページが開けるだけでは判断できません。
  2. ルールを確認します。直接接続する想定のサービスとプロキシ経由の想定のサービスにそれぞれアクセスし、適用されたルール、プロキシグループ、最終的なノードを記録します。TUNが正常でもDIRECTに振り分けられる場合は、通信の取り込みではなく振り分け結果の問題です。
  3. DNSを確認します。まずシステムの名前解決をテストし、その後DNSリークテストを行います。テストサイトに表示されるのは再帰DNSの出口であり、プロキシの出口IPと一致するとは限りません。事前に決めたDNS経路に沿っているかを確認してください。
  4. IPv6を確認します。システムでIPv6が有効な場合は、IPv4とIPv6それぞれでアクセスし、結果とカーネルの記録を確認します。IPv4だけの検証では、デュアルスタックの通信がすべて取り込まれているとは限りません。
  5. UDPを確認します。実際に使うゲーム、音声通話、HTTP/3対応アプリで再テストし、ノードがUDPに対応しているかも確認します。一般的なWebサイトへのTCP接続が成功しても、UDPが正常に動作する証拠にはなりません。

「有効化前・有効化後・無効化後」の3段階で、システムプロキシの状態、適用ルール、DNSの上流、エラーログを記録しておくと便利です。遅延はノード、接続先、ネットワーク経路、キャッシュの影響を受けるため、速度測定1回の数値だけでTUNがシステムプロキシより速いとは判断できません。

よくあるトラブルと安全な戻し方

症状まず確認する項目対処方法
有効にするとすぐ通信できなくなるインターフェースの権限、ルーティングループ、上流DNSへの接続TUNをオフにして通信を復旧し、起動ログを項目ごとに確認する
ドメインでは失敗するがIPアドレスには接続できるカーネルDNS、53番ポートの横取り、アプリの暗号化DNSノードは変更せず、名前解決の経路だけを検証する
ブラウザーは使えるがゲームで問題が起きるUDPの出口、ノードの対応状況、接続先に適用されるルールUDPの接続記録とサーバー側の対応状況を確認する
LAN内の機器にアクセスできないプライベートネットワークのルート、接続先アドレス、ドメインの名前解決対象のネットワーク範囲に合わせてルート除外または直接接続ルールを設定する
Wi-Fiを切り替えると問題が起きる外部接続インターフェースの判定、古いルート、ネットワーク変更時のログネットワークが安定してからカーネルを再起動し、ルートを確認する

LANへの直接接続とTUNによる取り込みの除外は別の設定

特定のプライベートIPアドレスをDIRECTに振り分ける設定は、通信がカーネルに入った後で直接接続するという意味です。一方、そのネットワーク範囲をTUNのルートから除外すると、通信はカーネルを通りません。この2つではログの確認可否やDNSの動作が異なります。プリンター、NAS、社内ネットワークに接続できない場合は、まず接続先の実際のアドレスとネットワーク範囲を確認してください。特定の機器の問題を解決するために、範囲がわからないネットワーク全体を除外しないでください。

無効化後に元へ戻す手順

まずTUNをオフにし、クライアントがインターフェースとルートを削除するまで待ってから、以前のシステムプロキシとDNS設定に戻します。それでも通信できない場合は、クライアントを通常の方法で終了し、残ったプロキシ設定やルート、ほかのVPNの状態を確認してください。ルーティングテーブル全体をいきなり消去しないでください。DNSやfake-ipの設定を変更しても古いアドレスが使われる場合は、設定に誤りがないことを確認したうえで、システムのDNSキャッシュを消去し、関連アプリを再起動します。

動作確認済みの設定を保存しておきましょう。カーネルの種類、TUNスタック、DNSの上流、外部接続インターフェースの選択、必要なLAN向け例外を明記します。サブスクリプションの更新では、想定した内容だけが変更されるようにしてください。通信の取り込みやDNSの設定を変更するたびに同じ手順で再テストすれば、設定・ノード・システムネットワークのどこに原因があるか切り分けやすくなります。