実行方法と通信経路を決める

Linux向けのClash互換クライアントは、一般にGUIとプロキシコアで構成されます。mihomoはプロキシコアとしてYAML設定を読み込み、ローカルポートで待ち受けてルールに沿って通信を振り分けます。GUIクライアントはサブスクリプションの取り込み、設定管理、プロキシグループの選択に加え、システムプロキシやTUNの利用を担います。両者は別のソフトウェアであり、設定ディレクトリも共通とは限りません。

GNOMEやKDEなどのデスクトップ環境があり、ノードを頻繁に切り替えるならGUIクライアントが便利です。SSHのみで操作するサーバーや、起動時の自動実行、ログの一元管理が必要な環境では、mihomoとsystemdを使うと権限やファイルの所有者を明確にできます。ここで紹介するコマンドライン手順は、systemdを利用する一般的なLinuxホストを対象としており、コンテナ用のプロセスマネージャーしかない環境には適用できません。

項目 デスクトップGUIクライアント mihomoサービス
設定の場所クライアントの設定・サブスクリプション画面/etc/mihomo/config.yaml(この記事で指定)
起動方法デスクトップのアプリメニューまたはログイン時に自動起動systemctl enable --now mihomo
ログの確認場所クライアントのログ画面journalctl -u mihomo
基本的な通信経路システムプロキシまたはアプリごとのプロキシ設定アプリから 127.0.0.1:7890 に直接接続
権限の分離通常のGUIと権限を付与したサービスを分ける基本的なプロキシは専用の非rootユーザーで実行

デスクトップ編:GUIクライアントの導入と設定の読み込み

1. ディストリビューション、アーキテクチャ、パッケージ形式を確認する

クライアントのダウンロードページから、Linuxに対応したClash Verge RevやFlClashなどを選べます。まずシステム情報を確認し、PCの製品名だけでインストールパッケージを判断しないでください。x86_64 はリリースページのx64またはamd64、aarch64 は通常arm64に該当します。CPUアーキテクチャだけでなく、対応するディストリビューションのバージョンやランタイムも確認しましょう。

cat /etc/os-release
uname -m

DebianやUbuntuでは通常DEBパッケージ、Fedoraなどでは通常RPMパッケージを使用します。以下ではダウンロード済みのファイルを、コマンドを簡潔にするためローカルで client.deb または client.rpm に名前変更しています。これは例示用の名前であり、実際の配布ファイル名ではありません。ファイルがあるディレクトリに移動し、ディストリビューションに応じてどちらか一方を実行します。

# Debian / Ubuntu
sudo apt install ./client.deb

# Fedora
sudo dnf install ./client.rpm

デスクトップのアプリメニューからクライアントを起動し、GUI全体を sudo で実行しないでください。サービスモードやTUNの権限が必要な場合は、クライアントに用意されたサービスのインストール機能や権限設定を使います。設定ファイルの所有者がrootになり、次回の通常起動時にサブスクリプションを保存できなくなる事態を防げます。

2. サブスクリプションを読み込み、適用中の設定を確認する

  1. クライアントの設定またはサブスクリプション画面で、有効なClash互換サブスクリプションURLを読み込むか、ローカルのYAMLファイルをインポートします。メニュー名はクライアントのバージョンによって異なる場合があります。
  2. 読み込んだ設定を選択し、現在の設定として適用します。ダウンロードに成功しただけでは、設定が有効になったとは限りません。
  3. プロキシグループで利用可能なノードを選び、ログに設定の解析エラーがないか確認します。プロキシグループ名はルール内の参照先と一致している必要があります。
  4. 現在の設定または実行情報から、HTTP、SOCKS、mixedの待ち受けポートを確認します。以下では 7890 を例にしますが、既存クライアントのポートを無理に変更する必要はありません。
  5. まず明示的なプロキシ接続をテストし、その後システムプロキシを有効にします。プロキシ設定に従わないアプリも制御する必要がある場合に限り、さらにTUNをテストしてください。

GUIクライアントは、サブスクリプション、オーバーライド設定、画面上のオプションを統合し、実行用の設定を生成することがあります。このような一時生成ファイルを直接編集しないでください。サブスクリプションの更新や設定の切り替えで変更が失われる可能性があります。ポート、ルール、DNSの設定を継続して保持するには、クライアントのオーバーライド機能を使いましょう。また、クライアントが ~/.config/mihomo/config.yaml を読み込むと決めつけないでください。

3. デスクトップのシステムプロキシとターミナルのプロキシを区別する

クライアントの「システムプロキシ」は通常、デスクトップ環境のプロキシ設定を変更します。ブラウザーはその設定に従うことがありますが、新しく開いたターミナルのcurl、パッケージマネージャー、バックグラウンドサービスが参照するとは限りません。逆に、ターミナルで export を実行しても、起動済みのブラウザーの設定は変わりません。テストでは「プロキシを有効にした」とだけ記録するのではなく、対象アプリ、使用したプロキシ経路、ポートを記録してください。

ヘッドレス環境編:mihomoと専用ディレクトリを準備する

ここではパスを固定して導入し、現在のSSHユーザーのホームディレクトリとサービスの作業ディレクトリを混同しないようにします。コアをインストールする前に、uname -m の結果に基づいて、mihomoの公式リリースから現在のアーキテクチャとCPU命令セットに対応したLinuxビルドを選んでください。ダウンロードしたアーカイブを展開し、実行ファイルをローカルで mihomo に名前変更します。以降のコマンドは、そのファイルがあるディレクトリで実行します。

sudo install -m 0755 ./mihomo /usr/local/bin/mihomo
/usr/local/bin/mihomo -v

-v は実際にインストールされたバージョンを確認するオプションです。Exec format error が表示された場合は、圧縮ファイルを実行していないか、アーキテクチャを間違えていないかを確認してください。Illegal instruction の場合は、ビルドが要求する命令セットを確認します。ファイル権限を繰り返し変更するより、ホストに合ったビルドを再ダウンロードするのが適切です。

専用のサービスアカウントを作成する

このアカウントはプロキシサービスの実行専用で、対話的なログインには使いません。アカウントがすでに存在する場合は作成をスキップします。ディストリビューションで nologin のパスが異なる場合は、まず command -v nologin で確認し、パスを調整してください。設定はrootが管理し、実行時データはサービスユーザーが書き込みます。

getent passwd mihomo || sudo useradd \
  --system --user-group \
  --home-dir /var/lib/mihomo \
  --shell /usr/sbin/nologin mihomo

sudo install -d -o root -g mihomo -m 0750 /etc/mihomo
sudo install -d -o mihomo -g mihomo -m 0750 /var/lib/mihomo
  • /usr/local/bin/mihomo:コアプログラム。通常のサービスユーザーが上書きできないようにします。
  • /etc/mihomo/config.yaml:メイン設定ファイル。ノードの認証情報やサブスクリプションURLが含まれる場合があるため、読み取り権限を制限してください。
  • /var/lib/mihomo:-d で指定するデータディレクトリ。実行状態、キャッシュ、設定に必要なリソースを保存します。

ここでは -f でメイン設定を明示し、デフォルトのディレクトリには依存しません。実際の設定に proxy-providers、rule-providers、外部データファイルが含まれる場合は、それらのパス、読み取り権限、ダウンロード条件も確認してください。メインのYAMLだけをコピーして、依存ファイルも揃っていると判断しないでください。

最小構成で待ち受けポートを確認する

インストールの問題とサブスクリプションの問題を切り分けるため、まず次の直接接続用設定を使います。現在のディレクトリに config.yaml を作成し、以下の内容を書き込んでください。この設定で確認できるのは、コアが起動し、プロキシリクエストを受け付け、直接通信できることです。プロキシノードは含まず、出口の地域も変わりません。

mixed-port: 7890
allow-lan: false
bind-address: 127.0.0.1
mode: rule
log-level: info

tun:
  enable: false

rules:
  - MATCH,DIRECT

mixed-port は同じポートでHTTPとSOCKSのプロキシリクエストを受け付けます。allow-lan: false は本機以外からのアクセスを制限し、例ではループバックアドレスも明示しています。ここではコントローラーを有効にする必要はなく、クラウドサーバーのセキュリティグループで 7890 を開放する必要もありません。

sudo install -o root -g mihomo -m 0640 \
  ./config.yaml /etc/mihomo/config.yaml

sudo -u mihomo /usr/local/bin/mihomo \
  -t -d /var/lib/mihomo -f /etc/mihomo/config.yaml

-t は現在のコアで設定を読み込めるか確認するオプションで、ノードへの接続テストではありません。YAMLエラーが出た場合は、インデント、コロンの後のスペース、フィールドの型を確認してください。権限エラーの場合は、設定ファイルと各階層の親ディレクトリにサービスアカウントのアクセス権があるか確認します。

systemdでサービスを常時実行する

/etc/systemd/system/mihomo.service を新規作成し、以下の内容をすべて書き込みます。このサービスは前述のローカル明示プロキシ方式を対象としており、TUNデバイスの作成やシステムルートの変更権限は付与しません。

[Unit]
Description=mihomo local proxy service
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=mihomo
Group=mihomo
WorkingDirectory=/var/lib/mihomo
StateDirectory=mihomo
StateDirectoryMode=0750
ExecStart=/usr/local/bin/mihomo -d /var/lib/mihomo -f /etc/mihomo/config.yaml
Restart=on-failure
RestartSec=5s
UMask=0027
NoNewPrivileges=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=strict

[Install]
WantedBy=multi-user.target

StateDirectory を使うと、書き込み可能な状態ディレクトリをsystemdが管理します。ProtectSystem=strict はサービスによるシステムファイルへの書き込みを制限しますが、状態ディレクトリには書き込めます。ProtectHome=true はサービスからユーザーのホームディレクトリへのアクセスを遮断するため、ダウンロードディレクトリにproviderファイルを置いたまま参照しないでください。依存ファイルをサービスがアクセスできるディレクトリに置き、設定内のパスに合わせて整理します。

sudo systemctl daemon-reload
sudo systemctl enable --now mihomo.service

systemctl status mihomo.service --no-pager
sudo journalctl -u mihomo.service -b -n 80 --no-pager
sudo ss -lntup 'sport = :7890'

enable --now は、起動時の自動実行を有効にすると同時にサービスを起動します。network-online.target の待機動作は、ディストリビューションで有効になっているネットワーク待機サービスによって異なり、外部のサブスクリプションサイトへの接続を保証するものではありません。起動時にリモートリソースをダウンロードする場合は、リクエストが成功したかログで確認してください。

設定の更新とバイナリのアップグレード

YAMLを変更したら、まず前述の -t をサービスユーザーとして実行して確認し、成功した場合に再起動します。この記事では ExecReload を定義していないため、systemctl reload mihomo を実行できる手順として扱わないでください。再起動すると既存のプロキシ接続が切断されるため、適切なメンテナンス時間を選びましょう。

sudo -u mihomo /usr/local/bin/mihomo \
  -t -d /var/lib/mihomo -f /etc/mihomo/config.yaml \
  && sudo systemctl restart mihomo.service

コアをアップグレードする前に、現在のプログラムと設定を保存してください。サービスを停止してから install で新しいプログラムを配置し、バージョンを確認して設定を再検証した後、サービスを起動します。実行中のバイナリを直接上書きしないでください。また、新版が旧設定の非推奨フィールドをすべてサポートするとは限りません。

ターミナルのプロキシ環境変数を設定してリクエストを検証する

まず明示的なプロキシ接続をテストする

mihomoを実行しているホスト上で、次のテストを実行します。--noproxy "" を指定すると、既存の NO_PROXY 設定によって今回のリクエストがプロキシを迂回するのを防げます。HTTPレスポンスが返れば通信経路に進展があったことを示しますが、サイトが返した具体的なステータスコードは別途確認が必要です。

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

最小構成の直接接続設定でテストが成功しても、ローカルのプロキシ入口が使えることを示すだけです。実際のノードを含む設定に切り替えた後は、接続ログの接続先、ルール、プロキシグループを確認し、ノードを経由しているか判断してください。Webページが開けるだけで出口が切り替わったと決めつけないでください。

現在のターミナルと子プロセスにプロキシを設定する

export http_proxy=http://127.0.0.1:7890
export https_proxy=http://127.0.0.1:7890
export all_proxy=socks5h://127.0.0.1:7890
export no_proxy=localhost,127.0.0.1,::1

curl --connect-timeout 10 --max-time 30 -I https://example.com/

https_proxy の値に http:// を使っても矛盾はありません。これはローカルのHTTPプロキシへの接続方式を表し、HTTPSの接続先には通常CONNECTでトンネルを確立します。この指定に対応するプログラムでは、socks5h:// は接続先のドメイン名をSOCKSプロキシ側で名前解決することを意味します。利用する環境変数や優先順位はツールによって異なります。

  • この export の設定が適用されるのは、現在のシェルと、その後に起動する子プロセスだけです。他のログインセッションには反映されません。
  • 設定を継続して有効にするには、使用中のシェルの起動ファイルに追加できます。たとえばBashの対話型ターミナルでは ~/.bashrc がよく使われますが、すべてのプログラムがこのファイルを読み込むわけではありません。
  • sudo は通常、環境変数を引き継ぎません。「通常のcurlで成功した」からといって、sudo apt も同じプロキシを使うとは限りません。
  • systemdのシステムサービスはユーザーの ~/.bashrc を読み込みません。プロキシが必要な他のサービスには個別に環境変数を設定してください。また、mihomo自身にmihomoの待ち受けポートを指すプロキシ変数を設定しないでください。

以前に大文字の環境変数を設定していた場合は、それらも確認して値を統一してください。curlはセキュリティ上の理由から大文字の HTTP_PROXY を受け付けないため、この記事では小文字を使います。プロキシを停止する前に、後続コマンドの接続エラーを防ぐため、現在のターミナルに残っている一般的な変数を削除できます。

unset http_proxy https_proxy all_proxy no_proxy
unset HTTP_PROXY HTTPS_PROXY ALL_PROXY NO_PROXY

TUN、リモートアクセス、トラブルシューティング

TUNの利用には別途権限付与とルート変更が必要

TUNは仮想ネットワークインターフェースを使い、ルーティング条件に合うIP通信を取り込みます。「すべてのプログラムのすべての通信が必ずプロキシを通る」ことを保証するものではありません。経路の除外設定、DNS、IPv6、既存のVPNによって結果が変わります。Linuxでは通常、/dev/net/tun へのアクセス権とネットワーク管理権限が必要です。tun.enable を true にするだけでは、これらの要件を回避できません。

この記事の非root systemdユニットには、これらの権限を付与していません。TUNを使う場合は、利用するクライアントまたはmihomoの最新ドキュメントを確認し、サービス権限、DNSの制御、ルーティング設定を見直してください。権限昇格コマンドを1つ追加するだけで済ませないでください。SSHサーバーで作業する際は、別のSSHセッションとクラウドコンソールへの接続手段を確保し、管理用ネットワークを除外する方法を明確にして、ルート変更で接続を失わないようにしてください。

リモート利用にはSSHポートフォワーディングを使う

個人のPCからサーバー上のローカルプロキシを一時的に使う場合は、プロキシポートをインターネットに直接公開せず、PC側でSSHローカルポートフォワーディングを設定できます。以下では、SSH設定に mihomo-host というホスト別名が登録済みであることを前提とします。

ssh -N -o ExitOnForwardFailure=yes \
  -L 127.0.0.1:17890:127.0.0.1:7890 mihomo-host

SSH接続を維持したまま、個人のPCでアプリのプロキシを 127.0.0.1:17890 に設定します。転送先の 127.0.0.1:7890 はサーバー側のループバックアドレスであり、個人のPCを指すものではありません。LAN向けにプロキシを公開する場合は、認証、ファイアウォール、アクセス範囲を別途設定してください。allow-lan を有効にするだけでは不十分です。

エラーの症状から原因を絞り込む

症状まず確認すること
address already in usess でポートの使用状況を調べます。デスクトップクライアントとsystemdサービスが同時に7890番ポートを使っている可能性があります。片方だけを使うか、それぞれ別のポートに設定してください。
Permission deniedサービスユーザーがメイン設定とproviderファイルを読み取れるか、データディレクトリに書き込めるか確認します。原因を特定せずにディレクトリ全体の権限を開放しないでください。
Connection refusedサービスが実行中であること、実際の待ち受けアドレス、アプリで指定したポートが一致していることを確認します。コンテナ内の127.0.0.1はホストのループバックアドレスではありません。
ポートには接続できるが、リクエストがタイムアウトするノードへの接続、DNSの成否、プロキシグループの選択状態、適用されたルールを確認し、ローカルの待ち受けと上流への接続を切り分けます。
ターミナルでは使えるが、他のアプリでは使えない対象アプリが環境変数に対応しているか、アプリ独自のプロキシ設定が有効になっているか、環境変数を設定する前にアプリを起動していなかったか確認します。
ターミナルでは起動するが、サービスとしては起動しない実行ユーザー、作業ディレクトリ、設定ファイルの絶対パス、ファイル権限を比較します。ProtectHome によってアクセスが遮断されたファイルを参照していないかも確認してください。

トラブルシューティングでは、次の3点を記録してください。mihomo -v のバージョン出力、サービスログに最初に現れた有効なエラー、アプリで実際に使われているプロキシアドレスです。ログを共有する前に、サブスクリプションの認証情報、ノードのパスワード、コントローラーのキーを削除してください。設定項目の意味はドキュメントで、サブスクリプションの初回読み込みや設定の切り替えは設定ガイドで確認できます。