GitHubからのcloneはできるのにnpmの依存関係取得が止まる、Dockerイメージのpullだけタイムアウトする――こうした差は、アプリごとにプロキシ設定の方法や通信を実行する場所が違うために起こります。ClashのTUNモードは、仮想ネットワークインターフェースを使って端末のIP通信を取り込み、ルールに従って処理する方式です。ターミナルで起動したアプリの通信をまとめて扱える一方、Docker Desktopの仮想マシン内や別ホスト上の通信まで必ず捕捉できるわけではありません。
この記事では、mihomo対応クライアントを例に、TUNの有効化、CLIツールの通信経路、DNSとルールの確認を順に説明します。設定画面の名称はClash Verge、Clash Verge Revなどで異なるため、画面名よりも設定値とログを基準にしてください。
開発者向けClash TUN設定ガイド:Git・npm・Dockerの通信をまとめてプロキシへ
TUNモードで何が変わるか
通常のシステムプロキシは、HTTPプロキシ設定を参照するアプリの通信をローカルポートへ送ります。環境変数のhttp_proxyやGit、npmの個別設定も、対応するプログラムにプロキシの接続先を知らせる方法です。これに対しTUNは、仮想インターフェースとルート設定を使ってIPパケットを取り込みます。そのため、アプリにプロキシ設定欄がなくても、OS側のルートとTUNの設定が適切なら通信をClashへ渡せる場合があります。
ただし、TUNは「すべての通信を自動的にプロキシへ送る機能」ではありません。取り込まれた通信も、設定のルールやモードに従います。DIRECTに一致すれば直接接続になり、ブロックするルールや誤ったプロキシグループに一致すれば通信は失敗します。DNS解決、OSのルーティング、権限、VPNやファイアウォールとの競合も影響します。
| 方式 | 適する場面 | 注意点 |
|---|---|---|
| システムプロキシ | ブラウザーなど、OSのプロキシ設定を参照するアプリ | すべてのCLIやバックグラウンドサービスが参照するわけではない |
| アプリごとの設定・環境変数 | Gitやnpmなど、プロキシ設定を持つツール | 子プロセスや別の通信ライブラリには引き継がれないことがある |
| TUN | アプリ個別の設定がない通信を、OSのルート経由で扱いたい場合 | 権限、DNS、ルール、仮想ネットワークの構成を確認する必要がある |
設定画面にTUNのスイッチがあっても、使用中のコアがmihomoとは限りません。クライアントの「バージョン情報」やコア情報で、実行中のコア名とバージョンを確認します。旧来のClashコアとmihomoでは利用できる項目に違いがあるため、未対応のフィールドをそのまま追加しないでください。
TUNを有効にして動作を確認する
まずクライアントの設定で、現在有効なプロファイルとコアを確認します。TUNの有効化には管理者権限やシステム拡張の許可が必要な場合があります。許可ダイアログが出た場合は、対象アプリと要求された権限を確認してから操作してください。別のVPNや仮想ネットワークソフトが同時にルートを変更していると、経路が競合することがあります。問題の切り分け中は、許可された範囲で一つずつ有効化して確認します。
mihomoの設定例は次のとおりです。既存設定に取り込む場合は、tun:やdns:を新たに重複定義せず、既存の各項目に統合してください。実際の対応フィールドは使用中のコアの仕様を確認します。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
strict-route: true
dns-hijack:
- any:53
auto-routeはルート設定を自動化する項目です。auto-detect-interfaceは利用するネットワークインターフェースの検出に関係し、strict-routeは経路漏れを抑える設定です。環境によってはローカルネットワークやほかのVPNへの接続に影響するため、すべての環境で同じ値が最適とは限りません。TUNを有効にした直後に社内ネットワークやルーターの管理画面へ接続できなくなった場合は、ログとルートの状態を確認し、元の設定に戻してから例外経路を検討してください。
dns-hijackはDNS通信をmihomoのDNS処理へ渡す設定例です。DNS機能自体が無効、または上流DNSへ到達できない状態では、名前解決に失敗します。TUNの動作確認では、設定を一度に何項目も変更せず、コアのログでインターフェース作成やルート設定に関するエラーがないかを見ます。クライアントに「TUN」「サービス」「管理者権限」などの状態表示がある場合は、その表示も確認してください。
Gitとnpmの通信経路を整える
Gitの通信方法は、リポジトリURLがHTTPSかSSHかで異なります。HTTPSでgit clone https://...を実行する場合、Gitのプロキシ設定または対応する環境変数が使われることがあります。以下はローカルの混合ポートが7890の場合の例です。実際のポートはクライアントの現在の設定を確認してください。
git config --global http.proxy http://127.0.0.1:7890
git config --global https.proxy http://127.0.0.1:7890
git config --global --get http.proxy
git config --global --get https.proxy
この設定はHTTPSプロキシを使う例で、混合ポートがHTTPプロキシの要求を受け付けることが前提です。動作確認後、不要なら設定を解除できます。
git config --global --unset http.proxy
git config --global --unset https.proxy
git@host:owner/repo.gitのようなSSH形式のURLは、GitのHTTPプロキシ設定では通常処理されません。TUNでSSHのTCP通信を取り込む方法のほか、SSHクライアント側で対応するプロキシを明示する方法があります。接続先ポートや認証方式はサーバー側の設定に従ってください。HTTPS cloneは成功するがSSH cloneだけ失敗する場合は、ルールだけでなくSSHの経路も切り分けます。
npmでは、使用中のNode.jsとnpmのバージョン、設定ファイル、レジストリを確認します。npmがプロキシ設定を参照する構成なら、次のように設定できます。
npm config set proxy http://127.0.0.1:7890
npm config set https-proxy http://127.0.0.1:7890
npm config get registry
npm config get https-proxy
実行環境でこの設定が不要になった場合は、npm config delete proxyとnpm config delete https-proxyで解除できます。組織のレジストリや認証設定がある場合は、既存値を控えてから変更してください。依存関係の取得先はnpmレジストリだけでなく、パッケージの配布元やGitリポジトリなどに分かれることがあります。ひとつのURLを許可するだけで全依存関係が取得できるとは限りません。
Gitやnpmの設定とTUNを同時に使うと、通信経路が二重になる場合があります。まずTUNだけ、またはアプリ設定だけで試し、どちらの経路で成功するか確認すると原因を追いやすくなります。
DockerのpullはCLIとデーモンを分けて考える
docker pullはターミナルから実行しますが、イメージを取得する通信は多くの構成でDockerデーモンが行います。そのため、ターミナルのhttp_proxyを設定しただけではpullの通信経路が変わらないことがあります。Docker Desktopではデーモンが仮想マシン内で動く構成があり、ホストOSのTUNがその外向き通信を常に同じ方法で捕捉するとは限りません。Linuxでホスト上のデーモンを使う場合も、ルート、ファイアウォール、デーモンのプロキシ設定によって結果が異なります。
まず、使用中のDockerコンテキストとエラーを確認します。docker context showで接続先を調べ、docker infoでデーモンの状態を確認してください。認証エラー、DNSエラー、接続タイムアウトでは対処が異なります。docker pullの詳細にレジストリ名や接続先が表示される場合は、機密情報を含まない範囲で記録します。
Docker DesktopにはバージョンやOSに応じたプロキシ設定があります。Linuxのsystemd管理デーモンでは、デーモン用のプロキシ環境設定をサービス側に与える方式が使われます。どちらも、シェルの環境変数とは設定場所が別です。変更後は、対象サービスを通常の手順で再起動し、状態とログを確認します。Docker設定ファイルにプロキシ認証情報を書く場合は、ファイルのアクセス権と共有範囲に注意してください。
Dockerのレジストリ通信では、認証用サービスやレイヤー配布用の接続先へリダイレクトされる場合があります。TUNのルールでdocker.ioだけを指定しても、すべてのpullが完了するとは限りません。接続ログに現れる実際のドメインを確認し、必要な宛先だけを既存ルールへ追加します。Docker Desktopの仮想マシンからの通信がホストのClashログに現れない場合は、TUNルールを増やすより先にDesktop側のプロキシ設定とネットワーク構成を確認してください。
ルールとDNSを確認し、通信経路を検証する
開発用ドメインをルールで扱う場合、既存のproxy-groupsに定義済みのグループ名を使います。次の例にある開発用は説明用の名前で、実際の設定に同名グループがあるとは限りません。ルールは上から順に評価されるため、より広いドメインルールやMATCHより前に置いてください。
rules:
- DOMAIN-SUFFIX,github.com,開発用
- DOMAIN-SUFFIX,npmjs.org,開発用
- DOMAIN-SUFFIX,docker.io,開発用
- MATCH,既存の最終ルール
これはルールの書式例であり、完全な設定ファイルではありません。グループ名が存在しない、または最終ルールを誤って置き換えた場合は、設定エラーや意図しない直接接続につながります。Gitのホストやパッケージ配布元、Dockerの認証・レイヤー配信先は環境ごとに違うため、接続ログで実際の宛先を確認してから追加します。広いIP範囲を一括でプロキシ対象にするのではなく、まずドメイン単位で検証しましょう。
- クライアントのログを開き、TUNを有効にした後のエラーと、通信を試した時刻を記録します。
git ls-remoteで対象リポジトリの参照を取得できるか試し、GitHubへの接続がClashの接続ログに現れるか確認します。実際のリポジトリURLを公開ログに貼らないでください。npm viewで小さなパッケージのメタデータを取得し、レジストリ名、名前解決、適用ルールを確認します。依存関係のインストール全体と切り分けて試せます。docker pullで対象イメージを取得し、失敗時にDockerデーモンのログ、Docker Desktopの診断情報、Clashの接続ログを同じ時刻で照合します。- 各ツールのプロキシ設定を一時的に外す、またはTUNを無効にする比較試験を一つずつ行います。複数の設定を同時に変えると、どの経路が効いたか判断できません。
名前解決の問題は、プロキシ接続の問題と区別します。ドメイン名で失敗し、IPアドレスへの接続だけが成功する場合でも、DNSを固定IPへ置き換えるのは恒久対策にならないことがあります。CDNやレジストリのIPは変わり、TLS証明書の検証にもホスト名が必要です。DNSログやmihomoのDNS設定を確認し、上流DNSへの到達性とルール判定を調べてください。
よくある質問
TUNを有効にしたら、Gitやnpmのプロキシ設定は削除すべきですか?
必ず削除する必要はありません。ただし、アプリ設定とTUNの両方が同じ通信をプロキシへ送ると、二重経路になったり、アプリ設定だけが原因のエラーを見落としたりすることがあります。まず現在の値を控え、TUN単独で動作するか比較してください。組織指定のプロキシ設定は、管理者の案内なしに変更しないでください。
Docker pullがClashのログに表示されないのはなぜですか?
Dockerデーモンがターミナルとは別のプロセスや仮想マシン内で動いている可能性があります。Docker Desktopのプロキシ設定、使用中のDockerコンテキスト、デーモンのネットワーク経路を確認します。ホストのTUNで必ず捕捉されるとは限らないため、表示されないことだけでルールの誤りと判断しないでください。
GitのHTTPS cloneは成功し、SSH cloneだけ失敗する場合は?
HTTPS用のGitプロキシ設定は、通常SSH通信には適用されません。TUNがSSHの通信を取り込んでいるか、接続先ポートへのルールやネットワーク制限に問題がないかを確認します。HTTPSとSSHは別の経路として検証してください。
ルールを追加したのに接続できない場合、次に何を見ますか?
ルールの順序、参照先のプロキシグループ、DNS解決、接続ログの実際の宛先を確認します。リダイレクト先が別ドメインなら、その通信も失敗している可能性があります。エラーの発生時刻をそろえ、Git・npm・Dockerの各ログとClashのログを比較してください。