TUNでターミナル通信を取り込む仕組み
Gitのcloneやpush、npm install、Pythonのパッケージ取得、Dockerイメージのpullが不安定なとき、ブラウザーだけで確認できるシステムプロキシ設定では原因を見つけにくい場合があります。ターミナルやバックグラウンドサービスの多くは、ブラウザーと同じプロキシ設定を参照するとは限りません。ClashのTUNモードは仮想ネットワークインターフェースを作り、OSの経路設定を通じてアプリケーションのIP通信をコアへ渡します。コアは受け取った接続にルールを適用し、直接接続するか、設定済みのプロキシ経由で送信します。
ここでは、TUNとDNSの設定に対応するmihomo系コアを前提にします。Clash VergeやClash Verge Revなど、画面上の操作名やコアの選択方法はクライアントやバージョンによって異なります。設定項目が見当たらない場合は、まずクライアントのコア情報で実際に動作しているコアとバージョンを確認してください。古いコアでは、以下のTUN項目や一部のプロトコルに対応していないことがあります。
システムプロキシとTUNは同じ機能ではありません。システムプロキシは、OSのプロキシ設定を参照するアプリからの通信を受け付けます。TUNはルーティング経由でIP通信を取り込む方法であり、アプリがHTTPプロキシを明示的に使わない場合にも役立ちます。ただし、仮想マシン、コンテナー、独自のネットワーク名前空間、OS側の除外経路などは別の条件が加わります。TUNを有効にしただけで、すべての通信が必ずプロキシ経由になるわけではありません。
- 使用中の設定とサブスクリプションをバックアップし、起動中のコア名とバージョンを記録します。
- クライアントの設定でTUNを有効にし、OSが求めるネットワーク拡張の許可や管理者権限を承認します。
- コアの接続一覧に対象の通信が現れるか確認します。表示されない場合は、ルールを増やす前にTUNの起動状態と経路を調べます。
- 接続が表示されたら、適用ルール、選択されたプロキシグループ、最終的なノードを確認します。
mihomoのTUN設定と安全な適用方法
次の例は、既存設定に組み込むTUNとDNSの一部です。プロキシノード、プロキシグループ、すべてのDNS項目を含む完成設定ではありません。サブスクリプションやクライアントのオーバーライド機能が設定を生成している場合は、元ファイルを直接編集するのではなく、クライアントが提供する設定編集・マージ機能を使ってください。再起動や更新の後に設定が元へ戻るときは、編集したファイルが実際にコアへ渡されていない可能性があります。
tun:
enable: true
stack: mixed
auto-route: true
auto-detect-interface: true
dns-hijack:
- any:53
dns:
enable: true
enhanced-mode: fake-ip
fake-ip-range: 198.18.0.1/16
nameserver:
- 1.1.1.1
- 8.8.8.8
mode: rule
log-level: info
stack: mixedはTUNのスタック方式を指定します。スタックの選択肢や既定値はコアのバージョンに依存するため、起動エラーが出た場合は対応する設定リファレンスを確認してください。auto-routeは必要な経路の設定、auto-detect-interfaceは送信に使うインターフェースの検出に関係します。ネットワーク構成やクライアントの実装によって動作が異なるため、値を変更したときは再起動後のルートと接続一覧を確認します。
dns-hijackはTUN経由で通過するDNS通信をコアのDNS処理へ渡すための設定例です。ポート53以外を使うアプリや、暗号化DNSを独自に使うアプリは、この設定だけでは同じ経路にならないことがあります。Fake-IPはDNS応答に仮想アドレスを返し、コアがその対応関係を使って宛先ドメインを扱う方式です。LAN内の機器名、開発用のローカルドメイン、VPN内の名前解決で問題が出た場合は、DNSログと除外設定を個別に確認してください。
設定を変更した後は、クライアントの再起動または設定再読み込みを行い、起動ログに設定エラーがないことを確かめます。単独でmihomoを起動している環境では、使用中のコアに対応した設定検証コマンドを利用できます。検証に成功しても、ノードへの接続やDNSの実通信が成功したとは限りません。最初は通常のWeb通信など、確認しやすい一つの接続でTUNの取り込みを確かめてから開発ツールへ進みます。
Git・npm・PyPIをルールで振り分ける
TUNが通信を取り込んでも、どの出口を使うかはルールとプロキシグループで決まります。以下は開発関連の接続をプロキシグループへ送り、残りは直接接続する例です。開発用プロキシは設定内で定義済みのグループ名に置き換えてください。ルールは上から評価されるため、広範囲のルールやMATCHを先に置くと、後続のドメインルールは適用されません。
mode: rule
rules:
- DOMAIN-SUFFIX,github.com,開発用プロキシ
- DOMAIN-SUFFIX,githubusercontent.com,開発用プロキシ
- DOMAIN-SUFFIX,npmjs.org,開発用プロキシ
- DOMAIN-SUFFIX,npmjs.com,開発用プロキシ
- DOMAIN-SUFFIX,pypi.org,開発用プロキシ
- DOMAIN-SUFFIX,pythonhosted.org,開発用プロキシ
- MATCH,DIRECT
この例は対象ドメインを示すもので、すべてのGitホスティング、パッケージレジストリー、ミラー、企業内サービスを網羅するものではありません。npmのレジストリーは環境によって独自のURLに変更されていることがあります。GitのリモートURLもHTTPSとSSHで接続先やポートが異なります。処理が失敗したら、まず実際にアクセスしたホスト名をパッケージマネージャーやGitの出力、コアの接続一覧で確認し、そのドメインに合わせてルールを追加してください。
GitのHTTPS接続とSSH接続は同じではありません。HTTPSなら通常はTCP 443番ポートですが、SSHの接続先は設定によりTCP 22番ポートや、SSHをHTTPS用ポートで受け付けるホストなどに変わります。GitのURLがIPアドレス直指定の場合や、名前解決の情報がコアに届かない場合は、ドメインルールが期待どおり一致しないことがあります。接続一覧でルール名と宛先を確認し、ドメインが認識されていない場合はDNSの経路やコアのドメイン識別機能を調べます。
| 用途 | 確認する情報 | 振り分けの注意点 |
|---|---|---|
| Git over HTTPS | リモートURL、接続先ホスト、TCP 443番 | リポジトリーのホスト名に加え、必要な認証・配布先ドメインを確認 |
| Git over SSH | SSH設定、接続先ホスト、使用ポート | ホスト別設定で別名やポートを指定していないか確認 |
| npm | 設定中のregistry URL、実際の取得先 | 独自レジストリーやパッケージの配布ドメインを確認 |
| PyPI | index-url、追加のパッケージ配布先 | インデックスと実際のファイル配布先が異なる場合がある |
ルールに一致したことと、通信が成功したことは別々に確認します。ログや接続一覧では、最初に宛先、適用ルール、選択グループ、最終ノードの順に見ます。プロキシグループが正しく選ばれていても、ノードが接続できない、認証に失敗する、TLS証明書の検証で止まるといった別の要因があります。問題のあるツールだけに範囲を絞り、同じ操作を一度だけ実行すると、ログを読みやすくできます。
Docker Hubはデーモン側のプロキシ設定も確認
Dockerの通信は、実行コマンドを入力したシェルだけで完結するとは限りません。イメージのpullやビルド時の取得は、Docker DesktopのバックエンドやDocker Engineが実行します。デスクトップOSではEngineがVM内で動作する構成もあるため、ホストのターミナル通信がTUNで処理されていても、Dockerのデーモン通信が同じ経路を通るとは限りません。接続一覧に該当通信が現れるかを確認し、現れない場合はDocker DesktopまたはDocker Engineのプロキシ設定を確認してください。
Docker Desktopでは、利用中のバージョンの設定画面にあるプロキシ項目を使って、HTTP/HTTPSプロキシを指定できる場合があります。画面の場所や対応する設定はバージョンで変わるため、現在の設定画面と製品の説明を確認してください。Linuxでsystemd管理のDocker Engineを使う場合は、シェルの環境変数だけではデーモンへ引き継がれないことがあります。サービス単位のプロキシ設定を適用した後にデーモンを再起動し、設定が反映されたか確認します。
HTTP_PROXY=http://127.0.0.1:7890
HTTPS_PROXY=http://127.0.0.1:7890
NO_PROXY=localhost,127.0.0.1,.local
これはプロキシ環境変数の書式例であり、Dockerデーモンの設定方法そのものではありません。127.0.0.1:7890はクライアントがローカルにHTTPプロキシを待ち受けている場合に限って使える例です。Docker DesktopのVMから見たlocalhostと、ホストOSのlocalhostは同じ接続先にならない場合があります。ホスト名やポートを推測して設定せず、Docker Desktopが指定する接続先と利用中のクライアントの待ち受けポートを照合してください。
Docker Hubへ接続できない場合は、まず通常のコマンドで再現するか、対象がDocker Engineだけかを切り分けます。プロキシ認証情報を設定ファイルへ保存する場合は、ファイルのアクセス権と秘密情報の取り扱いにも注意してください。Dockerの設定やビルド出力にトークン、認証ヘッダー、社内レジストリーの資格情報が含まれることがあります。ログを共有する前に、これらを伏せてください。
Windows・macOSのトラブルを切り分ける
Windowsでは、TUNの仮想アダプター作成やルート設定が管理者権限、セキュリティ製品、他のVPNクライアントの影響を受けることがあります。TUNの状態が有効でも、起動ログにインターフェース作成エラーやルート設定エラーがないか確認してください。クライアントが要求するサービスやドライバーの導入が完了していない場合は、設定値だけ変更しても解決しません。クライアントの公式な手順に従い、権限の確認と再起動を行ってから再試験します。
macOSでは、ネットワーク拡張やVPN構成の許可が必要になることがあります。システム設定で該当する許可が承認されているか、Clashクライアントが現在のOSバージョンに対応する形で起動しているかを確認します。OSのアップデート後に権限が再確認されたり、他のVPNアプリが経路を変更したりすることもあります。問題が起きたときは、一度に複数のVPNを動かさず、クライアントのログ、システムのネットワーク状態、コアの接続一覧を同じ時間帯で照合します。
- 接続一覧に出ない:TUNの起動、OSの許可、仮想アダプター、アプリが使うネットワーク経路を確認します。
- 接続一覧に出るが直接接続になる:ルールの順序、実際のドメイン、ルールモード、設定済みプロキシグループの名前を確認します。
- プロキシグループに一致して失敗する:ノードへの到達性、認証情報、プロトコル、DNS解決を分けて調べます。
- ブラウザーだけ動く:ターミナルやDockerがシステムプロキシを使っていると決めつけず、TUN接続の有無とデーモン側設定を確認します。
- DNSエラーが続く:OSのDNS、コアのDNSログ、Fake-IPの適用、暗号化DNSや独自DNS設定を確認します。
再現時は、操作を一つに絞ってログを採取します。例えば、問題のGitリポジトリーに対する接続だけを再試行し、開始時刻、エラーメッセージ、接続一覧の宛先とルールを記録します。ログレベルを長時間debugに固定すると、機密情報を含むログが増えたり、通常時の確認が難しくなったりします。必要な短時間だけ詳細ログを使い、調査後は通常のレベルへ戻してください。
よくある質問
TUNを有効にすれば、すべてのターミナル通信がプロキシ経由になりますか?
いいえ。TUNは通信をコアへ取り込む仕組みで、出口はルールとプロキシグループによって決まります。また、Dockerのデーモン、仮想マシン、独自のネットワーク名前空間などはホスト側の通常の通信と異なる場合があります。接続一覧で対象通信の有無と適用ルールを確認してください。
ターミナルでは失敗するのにブラウザーでは成功するのはなぜですか?
ブラウザーがシステムプロキシを利用している一方、ターミナルのアプリはその設定を参照していない可能性があります。TUNで通信を取り込めているかを確認し、Gitやnpmなどが独自のプロキシ、DNS、レジストリー設定を持っていないか調べます。
GitHub用のルールを追加したのにSSH接続が失敗します。
リモートURLの形式、SSH設定で指定したホスト名やポート、実際の宛先を確認してください。HTTPS用のドメインルールだけでSSH接続の全条件を解決できるとは限りません。接続一覧にドメインが表示されない場合は、DNSやドメイン識別の状態も調べます。
Dockerだけ接続できない場合、最初に何を確認すればよいですか?
Docker EngineまたはDocker Desktopのバックエンドが通信を実行している点を確認し、デーモン側のプロキシ設定を調べます。ホストのターミナルで使えるlocalhostのポートが、Docker DesktopのVMからも同じように使えるとは限りません。設定画面と接続一覧で、実際の経路を確かめてください。