アプリに合わせて方式を選ぶ

ブラウザーや、システムプロキシ設定に従うデスクトップアプリだけを使うなら、まずはシステムプロキシを試しましょう。プロキシ設定を参照しないアプリ、一部のゲーム、UDP通信も取り込みたい場合はTUNを検討してください。TUNはより広い範囲をカバーできますが、実際に通信を取り込めるかどうかは、ルーティング、権限、DNS、ほかのVPNの影響にも左右されます。

どちらも解決するのは「通信をどうカーネルに渡すか」であり、「最終的にどのノードを経由するか」ではありません。Clashまたはmihomoに渡った後も、ルールとプロキシグループに従って処理されます。TUNを有効にしてもグローバルプロキシになるわけではなく、DIRECTに一致した接続はそのまま直接接続されます。

システムプロキシとTUNの通信取り込みの仕組み

システムプロキシ:アプリがローカルポートに接続

システムプロキシでは通常、127.0.0.1:7890などのプロキシアドレスをOSに登録します。この設定を参照するアプリは、リクエストをローカルの待ち受けポートに送ります。HTTPSサイトでは一般に、HTTPプロキシのCONNECTメソッドでトンネルを確立します。これはサイトへの接続がHTTPにダウングレードされるという意味ではありません。

アプリがシステム設定を参照するかどうかは、使用するネットワークライブラリによって異なります。コマンドラインツールの中には、HTTP_PROXYやHTTPS_PROXYなどの環境変数だけを参照するものもあれば、独自のプロキシ設定を持つものもあります。Windowsでは、一般的なユーザー向けプロキシ設定とWinHTTPの設定も別物です。サービスプロセスがデスクトップユーザーのプロキシ設定に従うとは限りません。

TUN:ルーティングでIPパケットを仮想インターフェースに送る

TUNはレイヤー3の仮想ネットワークインターフェースを作成し、ルーティングを通じて条件に合うIPパケットをカーネルに渡します。アプリ側でHTTPプロキシやSOCKSプロキシを認識する必要がないため、TCPやUDPで直接接続するプログラムもルールに基づく振り分けの対象にできる場合があります。

すべての通信が自動的に取り込まれるわけではありません。より具体的な既存ルート、ほかのVPNによるポリシールーティング、ネットワークインターフェースのバインド、IPv6の設定などによって実際の経路は変わります。また、TUNを使えばすべてのプロトコルをプロキシできるわけでもありません。UDP通信には選択したアウトバウンドノードとサーバーの対応が必要であり、TCPが使えるからといってUDPも使えるとは限りません。

比較項目システムプロキシTUNモード
通信の取り込み口アプリがHTTPまたはSOCKSの待ち受けポートに接続システムルーティングでパケットを仮想インターフェースに送信
アプリ側の要件プロキシ設定への対応、またはプロキシの明示指定が必要通常、アプリ側にプロキシ設定は不要
UDP通信一般的なシステムのHTTPプロキシ設定では、通常のUDP通信は取り込めない取り込み可能。ただしアウトバウンドとルーティングの対応状況による
実行権限通常のローカルポートで待ち受けるだけなら、一般に管理者権限は不要通常、権限昇格、サービスモード、またはネットワーク管理権限が必要
DNSの動作アプリはシステムDNSを使う場合も、名前解決をプロキシに任せる場合もあるDNS hijackと内蔵リゾルバーを組み合わせて一元的に処理できる
主な競合要因ポートの競合、アプリがシステム設定を無視することVPNのルーティング、仮想ネットワークインターフェース、DNS、ファイアウォール

DNSの扱いが2つの方式の大きな違い

「ウェブページが開ける」だけでは、DNSも想定どおりに処理されているとは限りません。システムプロキシを有効にしていても、アプリによってはOSに先にドメイン名を問い合わせてからプロキシに接続します。一方、ドメイン名を直接プロキシに渡すアプリもあります。SOCKSではローカル名前解決とリモート名前解決にも違いがあるため、テスト時はどの方式を使ったか明確にしてください。

ポート53のDNS hijackと暗号化DNSの違い

mihomoのdns-hijackは、条件に合う従来型DNSリクエストを内蔵DNSに転送できます。一般的なany:53はUDP 53を対象とします。TCP 53も処理する場合は、tcp://any:53を追加できます。これだけであらゆるドメイン問い合わせが自動的に検出されるわけではありません。

ブラウザーのDoHはHTTPS、DoTは通常TCP 853、DoQは通常UDP 853を使用します。ポート53のDNS hijackを設定しただけで、これらが内蔵DNSに切り替わるわけではありません。接続自体がTUNに入る場合でも、暗号化された問い合わせ内容がカーネルのDNSに渡るとは限りません。ドメイン名に基づくルール振り分けの結果は、ドメイン名の対応付けやスニッフィングの設定にも左右されます。

fake-ipが返すアドレスは、名前解決のエラーではない

fake-ipを有効にすると、内蔵DNSは対応関係を保持したIPアドレスを返します。一般的な範囲は198.18.0.0/16で、その後カーネルが後続の接続を元のドメイン名に関連付けます。198.18.x.xが表示されても、すぐにDNSを変更する必要はありません。アプリの通信が引き続きTUNに取り込まれているか、アドレスの対応付けが有効かを確認してください。

  • DNSモードを切り替えたら、テストするアプリを終了して再起動し、古い接続やキャッシュが使われないようにしてください。
  • Windowsではipconfig /flushdnsを実行して、システムのDNSキャッシュを消去できます。ただし、ブラウザーが独自のキャッシュを保持している場合があります。
  • LAN内のデバイス名や社内ドメインには、到達可能な内部DNSを使用してください。すべての問い合わせをそのままパブリックDNSに送るのは避けましょう。
  • IPv4では問題なく、IPv6で失敗する場合は、IPv6ルーティングとDNSの応答を個別に確認してください。Aレコードだけを調べても不十分です。

mihomoの設定と有効化手順

まず正常に使える設定をバックアップしてから、通信の取り込み方式を変更してください。以下はフィールドを統合する例で、完全なサブスクリプション設定ではありません。既存のproxies、proxy-groups、rulesはそのまま残してください。元のファイルにtunまたはdnsがある場合は、既存のマッピングに統合し、同じ名前のトップレベルフィールドを重複して作成しないでください。

まずローカルプロキシの接続口を確認

mixed-port: 7890
allow-lan: false
mode: rule

mixed-portを使うと、HTTPとSOCKSで同じポートを共有できます。allow-lan: falseは、ほかのLAN端末にプロキシサービスを公開しないための設定です。TUNでこの端末の通信を取り込むだけなら、LANアクセスを有効にする必要はありません。ここではmode: ruleでルールによる振り分けを維持しています。ノードやルールの代わりになる設定ではありません。

続けてTUNとDNSのフィールドを統合

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:
    - 223.5.5.5
    - 119.29.29.29

例にある2つのパブリックDNSアドレスは、上流DNSの設定例です。すべてのネットワークに適しているわけではありません。社内ネットワーク、学内ネットワーク、独自の名前解決ポリシーがある環境では、実際の要件に合わせて上流DNSとドメインごとの解決方法を設定してください。listenの1053は内蔵DNSの待ち受けポートです。システムプロキシのポートではなく、このフィールドだけでシステムDNSが自動的に当該ポートへ切り替わることもありません。

  • stack: mixedは混合スタックを選択します。対応状況はカーネルによって異なるため、互換性に問題がある場合はカーネルのドキュメントを確認し、ほかのスタックも比較してください。
  • auto-route: trueは、TUNに通信を流すためのルートを自動設定する指定です。ほかのVPNのルートが必ず優先解除されることを意味しません。
  • auto-detect-interface: trueは、外向きのネットワークインターフェースを自動検出する設定です。複数のネットワークインターフェース、テザリング、VPNを併用する場合は、実際の出口を確認してください。
  • dns.enableとtun.enableは別々のスイッチです。TUNを有効にしても、内蔵DNSが必ず有効になるわけではありません。

順番に起動して動作を確認

  1. まずシステムプロキシ経由で既存のノードが使えることを確認します。ほかのVPNは一時的に切断し、現在のネットワーク設定を記録してください。
  2. クライアントの指示に従ってサービスをインストールするか、管理者権限を付与してTUNを有効にします。モバイル端末では通常、システムVPNの利用許可が必要です。
  3. 設定を再読み込みし、起動ログにフィールドエラー、権限不足、ネットワークインターフェースの作成失敗、ポートの競合がないか確認します。
  4. システムプロキシを一時的に無効にしてTUNだけを有効にし、ブラウザーと、通常はプロキシ設定に従わないアプリをそれぞれテストします。
  5. 接続ログで宛先、一致したルール、最終的なポリシーを確認し、通信がカーネルに入るだけでなく、意図した経路を通っていることを確かめます。

2種類のテストでポートとルーティングの問題を切り分ける

テストでは一度に変更する条件を1つにしてください。以下のコマンドは同じHTTPSアドレスを使い、プロキシを明示する場合と、アプリケーション層のプロキシを使わない場合を比較します。Windows PowerShellでは、環境によってcurlが別名として動作するため、curl.exeの使用をおすすめします。

テスト1:HTTPプロキシの接続口だけを確認

curl --noproxy "" --proxy http://127.0.0.1:7890 --connect-timeout 10 -I https://example.com/

TUNを無効にした状態での実行をおすすめします。--noproxy ""は今回のリクエストでプロキシを使わない宛先のリストを空にし、ローカルの7890ポートを明示的に使用します。接続拒否のエラーが出たら、まずポートの待ち受け状態とカーネルの起動状況を確認してください。プロキシがリクエストを受け取った後に接続がタイムアウトする場合は、ノード、ルール、接続先サイトを調べます。

テスト2:TUNによる通信の取り込みだけを確認

curl --noproxy "*" --connect-timeout 10 -I https://example.com/

システムプロキシを無効にしてTUNを有効にした状態で実行します。--noproxy "*"を指定すると、curlはアプリケーション層のプロキシを使いませんが、OSのTUNルーティングは回避できません。実行後、カーネルの接続ログを確認してください。コマンドが成功しても、宛先への直接接続が成功した可能性があるため、プロキシ経由の証明にはなりません。

この2つのコマンドでテストできるのはHTTPSリクエストのみです。ゲームのUDP通信、音声通話、QUICは検証できません。これらをテストするには、実際のアプリで接続し、該当するUDP通信が記録されるか、どのルールに一致するか、アウトバウンドがUDPに対応しているかを確認してください。

ルーティングとDNSの状態を確認

# Windows
route print
ipconfig /all
netsh winhttp show proxy

# Linux
ip rule show
ip route show table all
resolvectl status

# macOS
scutil --proxy
scutil --dns
netstat -rn

以下のコマンドは状態を確認するためのもので、ネットワーク設定は変更しません。Linuxのresolvectlは、当該ツールが提供されているシステムでのみ使用できます。見つからない場合は、現在のネットワーク管理ツールでDNS設定を確認してください。自動ルーティングは独立したルーティングテーブルに追加される場合があるため、メインのルーティングテーブルだけでは不十分です。

よくあるトラブルと互換性の確認

システムプロキシは使えるのに、TUNを有効にすると通信できない

まずTUNの権限、ネットワークインターフェースの作成、外向きルートを確認してください。TUNを無効にして通信が復旧するか確かめた後、TUNだけを有効にして再度確認します。社内VPNへの接続中だけ失敗する場合は、ノードを何度も変更するのではなく、ルーティングと内部DNSの調整を検討してください。

デフォルトルートを安易に削除したり、正体の分からないネットワークサービスを停止したりしないでください。リモートデスクトップ環境でTUNのルートを変更すると、操作中の接続が切れるおそれがあります。事前にローカルから操作できる手段や、設定を戻す方法を用意してください。

ブラウザーは使えるのに、コマンドラインやゲームが接続できない

システムプロキシだけを有効にしている場合、アプリがそのプロキシ接続口を使っていない可能性があります。コマンドラインツールは、まずプロキシを明示して動作を確認します。ゲームではUDPを使用しているか、ノードが該当する通信に対応しているかを調べてください。TUNを有効にしても接続できない場合は、すべてを「通信の取り込み失敗」と決めつけず、接続ログを確認しましょう。

LAN内のデバイス、プリンター、社内ドメインに接続できない

まず、接続経路の問題か名前解決の問題かを切り分けます。デバイスのIPアドレスでは接続できるのに名前では接続できない場合は、内部DNSを重点的に確認してください。IPアドレスでも到達できない場合は、LANのルーティングとルールを調べます。宛先をDIRECTに設定して決まるのは、カーネルに入った後のアウトバウンド方式だけです。アプリのブロードキャストやマルチキャストによる検出の問題が解決するとは限りません。

2つの方式を同時に有効にできる?

一部のクライアントでは、システムプロキシとTUNを同時に有効にできます。通常、カーネルはループを防ぐために自身のアウトバウンド通信を処理しますが、両方を有効にすれば安定性が上がるとは限りません。トラブルの切り分けでは、まず各方式を個別に検証してください。普段使う際は、必要な通信範囲に合わせて有効にする設定を選びます。ほかのプロキシソフトやVPNを併用すると、どの接続口を使うか分かりにくくなり、ルーティングの競合も起こりやすくなります。

AndroidやiOSでもデスクトップと同じ設定を使える?

そのまま使うことはできません。モバイルクライアントでは、システムVPNインターフェースを使って通信を取り込むことが多く、許可、アプリの除外、バックグラウンド動作のルールはOSとクライアントによって異なります。一般的なモバイル端末では通常、ユーザー向けVPN接続を同時に1つだけ利用できます。この記事のYAMLはモバイルOSの許可設定に代わるものではなく、ほかのクライアントが同じフィールドに対応することを保証するものでもありません。

用途に合わせて必要最小限の設定にする

  • ブラウザーと一般的なデスクトップアプリ:まずシステムプロキシを使い、アプリが設定を参照しているか確認します。
  • 開発ツールとターミナル:まずツール独自のプロキシ指定を使います。多くのツールをまとめて通信制御する必要がある場合に、TUNを検討してください。
  • ゲーム、音声通話、プロキシ非対応アプリ:TUNを利用できますが、UDP、ノードの対応状況、ルールを個別に確認してください。
  • 社内VPN、複数のネットワークインターフェース、複雑な社内ネットワーク:まずルーティングとDNSの状態を記録し、どの通信を取り込むか決めてから設定してください。複数のネットワーク層を一度に変更しないようにしましょう。

安定した設定かどうかは、対象アプリの通信が想定した接続口に入り、ネットワーク環境に合ったDNS解決が行われ、正しいルールに一致し、通信の取り込みを無効にすればネットワークが復旧するかで判断できます。フィールドを確認する場合は設定リファレンスを、一般的な接続トラブルはFAQを参照して、順に切り分けてください。