Linuxでmihomoを導入する方法|GUIクライアントとsystemdによるヘッドレス運用

LinuxデスクトップへのGUIクライアントの導入から、サーバーでの設定配置、systemdサービス作成、自動起動、パネルへのアクセスまでを解説します。

1. デスクトップはGUI、サーバーはsystemd

Linuxでプロキシを使う方法は、大きく分けて2つあります。デスクトップ環境があり、トレイからノードを切り替えたい場合は、mihomoコアを統合したGUIクライアントを導入します。SSHターミナルのみのサーバーで、ログアウト後も稼働させるなら、mihomoコアを直接導入してsystemdで管理します。どちらも設定の基本は共通ですが、設定ディレクトリ、サブスクリプションの更新方法、権限管理は異なります。

ClashXはmacOS向けのクライアントであり、Linux用インストーラーはありません。Linuxデスクトップでは、ディストリビューションに合ったClash Verge RevやFlClashなどのパッケージを選んでください。サーバーでプロキシを使うためにデスクトップ環境を導入する必要はなく、GUIクライアントのウィンドウプロセスを動かす必要もありません。

用途推奨方法設定・自動起動の場所
個人用LinuxデスクトップGUIクライアントクライアントの設定画面、デスクトップへのログイン時に起動
SSHサーバーmihomoとsystemd/etc/mihomo/config.yaml、システムサービス
一部のコマンドだけプロキシを使うローカルのHTTP / SOCKSリスナーアプリのオプションまたはプロセスの環境変数
より多くのシステム通信を制御する権限を確認してからTUNを設定コア設定、ルーティング、DNS

2. Linuxデスクトップへの導入と設定の読み込み

アーキテクチャとパッケージ形式を確認する

まず次のコマンドでシステムを確認します。x86_64は通常amd64 / x64パッケージ、aarch64は通常arm64パッケージに対応します。両者は互換性がありません。UbuntuやDebianでは通常DEB、Fedoraでは通常RPMを選びます。ディストリビューションのバージョンによってシステムライブラリとの互換性も異なるため、導入前に使用するクライアントの最新リリースノートを確認してください。

uname -m
cat /etc/os-release
  1. インストーラーページを開き、Linuxを選択して、アーキテクチャとパッケージ形式に合ったクライアントを入手します。
  2. ファイルマネージャーでダウンロードしたDEBまたはRPMを開き、システムのソフトウェアインストーラーでインストールします。依存関係の解決に失敗した場合は、パッケージマネージャーが報告した依存関係を先に解決してください。強制的に無視してはいけません。
  3. クライアントを起動し、「設定」または「Profiles」画面からサブスクリプションURLかローカルのYAMLを読み込みます。項目名はクライアントやバージョンによって異なるため、実際の画面を確認してください。
  4. 読み込んだ設定を選択し、ノード一覧とプロキシグループが表示されることを確認します。次に「設定」でプロキシポートを確認し、実際の待ち受けポートを把握してください。
  5. まず下記の明示的なプロキシ指定で動作を確認してから、クライアントの「システムプロキシ」を有効にしてください。
curl --proxy http://127.0.0.1:7890 \
  --connect-timeout 10 --max-time 20 \
  -I https://example.com/

ここでの7890は記事内の例であり、すべてのクライアントがこのポートを使うとは限りません。HTTPレスポンスが返ればリクエスト経路が確立したことは分かりますが、特定のリモートノードを経由した証明にはなりません。ルールがDIRECTに一致すれば、リクエストは直接接続されます。接続ログのルール、プロキシグループ、出力ノードもあわせて確認してください。

デスクトップの自動起動はシステムサービスとは異なる

クライアントの「起動時に実行」は通常デスクトップセッションに依存し、ユーザーがデスクトップにログインした後に起動します。サーバー再起動後にユーザーがログインしない環境では、バックグラウンドプロキシとして適しません。また、GUIクライアントと後述のsystemdサービスで127.0.0.1:7890を同時に使わないでください。どちらか一方を動かすか、ポートを明確に分けてください。

3. mihomoコアと設定ファイルを配置する

以下はsystemdを使用するLinux向けの手順です。コマンドはsudoを実行できる一般ユーザーで実行してください。例ではDebian / Ubuntuで一般的なシステムツールを使います。ほかのディストリビューションでuseraddなどが見つからない場合は、パッケージマネージャーで該当ツールを先にインストールしてください。コンテナや一部の軽量システムにはsystemdがないため、このサービス設定はそのまま使えません。

実行ファイルをインストールする

mihomoプロジェクトの公式リリースページから、アーキテクチャとCPU命令セットに合ったLinuxビルドを選びます。展開後、実行ファイルを/tmp/mihomoに配置してください。ファイル名は実際にダウンロードした内容に合わせます。圧縮ファイルをそのまま実行ファイルとして扱うことはできません。古いCPUでは、より高い命令セット要件のビルドを安易に選ばないでください。

file /tmp/mihomo
sudo install -m 0755 /tmp/mihomo /usr/local/bin/mihomo
/usr/local/bin/mihomo -v

-vで実際のコアバージョンを確認できます。Exec format errorが出た場合はCPUアーキテクチャを、Illegal instructionが出た場合はビルドの命令セット要件を確認してください。この記事ではサービスファイルに特定のバージョン番号を固定しません。以降の更新でも同じインストール先を使います。

専用ユーザーとディレクトリを作成する

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

ユーザーがすでに存在する場合は作成を省略し、所属グループを確認してください。ディストリビューションによってnologinの場所が異なる場合は、command -v nologinで確認してからパスを調整します。設定は/etc/mihomoに、キャッシュと実行データは/var/lib/mihomoに置きます。サービス用ユーザーには設定の読み取り権限だけを付与し、サブスクリプション認証情報があるファイルを変更できるようにする必要はありません。

最小構成でプロセスを確認する

sudo tee /etc/mihomo/config.yaml > /dev/null <<'YAML'
mixed-port: 7890
allow-lan: false
bind-address: 127.0.0.1
mode: rule
log-level: info
ipv6: false

rules:
  - MATCH,DIRECT
YAML

sudo chown root:mihomo /etc/mihomo/config.yaml
sudo chmod 0640 /etc/mihomo/config.yaml

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

サービス提供元の設定を読み込む際は、mihomoが読み込めるYAMLが返されていることを確認してください。Webページ、ログイン案内、ノードURIだけのテキストでは使えません。設定を置き換えた後は、待ち受けアドレス、コントロールポート、ルール末尾のフォールバック方針を再確認します。サブスクリプション内の設定が、この記事で示すローカル待ち受けの制限を上書きすることがあります。

-tは設定ファイルの検証であり、リモートノード、ルールのダウンロード先、接続先サイトへの到達性を保証するものではありません。検証時に設定から参照されるデータファイルへアクセスする場合もあります。失敗したら具体的なログを読み、YAML構文エラー、パスの権限エラー、リソース取得エラーを切り分けてください。

4. systemdサービスを作成して自動起動を設定する

まずはroot以外のユーザーで通常のプロキシを動かします。7890のような高いポート番号での待ち受けにroot権限は不要です。以下のサービス設定ではTUN権限を付与しません。明示的なHTTP / SOCKSプロキシには適していますが、透過ゲートウェイには使えません。

sudo tee /etc/systemd/system/mihomo.service > /dev/null <<'UNIT'
[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
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
ReadWritePaths=/var/lib/mihomo

[Install]
WantedBy=multi-user.target
UNIT

sudo systemctl daemon-reload
sudo systemctl enable --now mihomo.service
sudo systemctl status mihomo.service --no-pager
sudo journalctl -u mihomo.service -b -n 80 --no-pager

enable --nowは、自動起動の設定とサービスの即時起動を同時に行います。network-online.targetが実際に待機するかどうかは、ディストリビューションで対応するネットワーク待機サービスが設定されているかによります。インターネットやサブスクリプションURLへの接続が保証されるわけではありません。リモートリソースには適切な再試行と更新の仕組みを用意してください。

  • config.yamlを変更した場合は、先に設定を検証してからsudo systemctl restart mihomoを実行します。
  • サービスユニットを変更した場合は、まずsudo systemctl daemon-reloadを実行してからサービスを再起動します。
  • 状態だけを確認する場合は、systemctl is-active mihomoとsystemctl is-enabled mihomoを実行します。
  • 停止して自動起動を解除するには、sudo systemctl disable --now mihomoを実行します。

このユニットにはExecReloadが定義されていないため、systemctl reload mihomoを一般的な更新コマンドとして使わないでください。再起動すれば新しい設定が読み込まれたことを確認しやすくなりますが、既存の接続が切れる場合があります。接続を維持したまま更新する場合は、使用中のコアのコントロールAPIドキュメントに沿って別途手順を設計してください。

5. ポート、プロキシ経路、アプリの動作を確認する

sudo ss -lntp 'sport = :7890'

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

curl --proxy socks5h://127.0.0.1:7890 \
  --connect-timeout 10 --max-time 20 \
  -I https://example.com/

mixed-portはHTTPプロキシとSOCKSプロキシの両方のリクエストを受け付けます。上記のsocks5hでは、接続先ドメインの名前解決をプロキシ側で行います。一方、socks5では通常、ローカル側で先に名前解決します。DNSの調査結果に影響するため、ポートが同じだからといって動作も同じとは限りません。

現在のシェルで一部のプログラムだけにプロキシを使う

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

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

unset http_proxy https_proxy no_proxy

https_proxyの値にhttp://を使っても問題ありません。これはHTTPプロキシ経由でCONNECTトンネルを確立するという意味であり、ローカルのプロキシポート自体がTLSを提供する必要があるという意味ではありません。環境変数が有効なのは、それを参照するプログラムとその子プロセスだけです。ブラウザー、ほかのsystemdサービス、すべてのUDP通信に自動で適用されるわけではありません。

パッケージマネージャー、コンテナデーモン、バックグラウンドサービスは、独自のプロキシ設定を使うことがあります。ターミナルでcurlが成功しても、Dockerのイメージ取得やシステム更新がプロキシ経由になったとは限りません。各プログラムのプロキシ設定を個別に確認してください。また、認証情報を含むプロキシ環境変数を、誰でも読めるファイルに安易に書き込まないでください。

6. SSHトンネル経由でコントロールAPIとパネルにアクセスする

mihomoのコントロールAPIとプロキシポートは別のものです。7890はプロキシリクエストを受け付け、以下で設定する9090はコントロールAPIに使います。サーバーのパネルにはSSHローカル転送でアクセスしてください。リモートから操作するために、コントロールAPIをインターネット上に直接公開してはいけません。

ローカルのコントロールAPIを有効にする

以下のコマンドは、ここまでの最小構成を前提として一度だけ実行します。既存の設定にexternal-controllerやsecretが含まれている場合は、キーを重複させず既存の項目を編集してください。コマンドはランダムなキーを生成してアクセス制限された設定ファイルに書き込み、キーをターミナルには表示しません。

controller_secret=$(openssl rand -hex 32)

printf '\nexternal-controller: 127.0.0.1:9090\nsecret: "%s"\n' \
  "$controller_secret" | \
  sudo tee -a /etc/mihomo/config.yaml > /dev/null

unset controller_secret

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

この手順にはOpenSSLがインストールされている必要があります。キーはコントロール用の認証情報です。パネルに入力する前に、管理用の安全なターミナルで設定内のsecretを確認してください。設定ファイル全体を公開の問い合わせ窓口に貼り付けてはいけません。コントロールAPIを有効にしただけでは、Webパネルは提供されません。

パネルの静的ファイルを配置する

使用する互換パネルプロジェクトの公式リリースパッケージから、ビルド済みの静的ファイルを入手します。index.htmlを含むディレクトリの中身を/etc/mihomo/uiに配置してください。未ビルドのソースコードを静的ページとして使ったり、ディレクトリを余分に入れ子にして入口ファイルのパスを間違えたりしないでください。

sudo install -d -o root -g mihomo -m 0750 /etc/mihomo/ui
sudoedit /etc/mihomo/config.yaml

設定のトップレベルに次の項目を追加し、サービス用ユーザーがパネルディレクトリ内のファイルを読み取れることを確認します。

external-ui: /etc/mihomo/ui

設定を検証してからサービスを再起動します。ローカルPCでSSHコマンドを実行し、PC側の9090をサーバーのループバックアドレスにある9090へ転送します。ここでのmihomo-serverはSSH設定で自分で作成したホストエイリアスです。実際に接続できるホスト名か、設定済みのエイリアスを指定してください。

ssh -N -L 127.0.0.1:9090:127.0.0.1:9090 mihomo-server

SSH接続を維持したまま、ローカルのブラウザーでhttp://127.0.0.1:9090/ui/を開きます。パネルのバックエンドにはhttp://127.0.0.1:9090を入力し、キーには設定内のsecretを入力します。ここでいうローカルアドレスはブラウザーを使っているPCを指し、SSHトンネル経由でサーバーに接続します。ブラウザーからサーバーのループバックアドレスへ直接アクセスするわけではありません。

7. TUN、サブスクリプション更新、よくある問題

TUNはスイッチを1つ切り替えるだけでは使えない

LinuxのTUNには利用可能な/dev/net/tunが必要です。通常はネットワーク管理権限も必要となり、自動ルーティング、ポリシールーティング、DNSの制御にも関わります。この記事の専用ユーザーサービスには必要な権限を付与していないため、tun.enable: trueを追加するだけでは権限エラーになる可能性があります。すべてのコンポーネントをrootで常時実行することを安易な解決策にしないでください。

サーバーでは特にSSHの管理経路を保護してください。デフォルトルートの誤設定、DNSの乗っ取り、プロキシのループによって接続が切れることがあります。TUNを有効にする場合は、まずクラウドコンソールやシリアルコンソールから復旧できる手段を用意し、使用中のコアのドキュメントで必要な権限を確認したうえで、サービス権限、ルーティングの除外設定、ロールバック手順を個別に設計してください。デスクトップクライアントのTUNサービスモードは、この記事の通常のプロキシ用ユニットとは別物です。

サブスクリプションの更新は別途管理する

サブスクリプションのYAML全体をconfig.yamlとしてダウンロードしても、コアが設定全体を定期的に再取得するわけではありません。GUIクライアントには設定更新のスケジュール機能が用意されていることが多くあります。ヘッドレス環境では、設定全体を更新するスクリプトを使うのか、proxy-providersのurl、path、intervalでノードプロバイダーを更新するのかを明確にしてください。

ノードプロバイダーのファイルと完全設定は構造が異なるため、任意のサブスクリプションURLをそのままproviderに指定することはできません。providerのキャッシュ先は、サービスが書き込める/var/lib/mihomoの下に配置してください。完全設定を更新する場合は、一時ファイルにダウンロードして形式を確認してから正式なファイルに置き換えます。唯一の設定ファイルをネットワークからのダウンロードで直接上書きしないでください。

症状まず確認する項目対処方法
address already in usesudo ss -lntpGUIクライアントや別のコアプロセスが7890 / 9090を使用していないか確認します。
permission denied設定ファイルの読み取り権限、キャッシュのパス、systemdの書き込み制限設定は読み取り専用のままにし、キャッシュとproviderファイルを書き込み可能なデータディレクトリに移します。
サービスが何度も再起動するjournalctl -u mihomo -bログに最初に出た設定、リソース、権限のエラーを修正してから、サービスを再起動します。
パネルが空白になる、または404になる/etc/mihomo/ui/index.htmlビルド済みファイルを使っているか、ディレクトリ構成が正しいか、サービス用ユーザーがファイルを読み取れるか確認します。
パネルで認証エラーが表示されるバックエンドアドレス、SSH転送ポート、secretプロキシポートではなくコントロールポートを使い、現在の設定にあるキーを確認します。
プロキシリクエストは成功するが、直接接続される接続ログ、ルールの一致状況、プロキシグループの選択DIRECTに一致していないか確認します。最小テスト設定にはDIRECTルールしかありません。

アップグレードとロールバックの確認

アップグレード前に旧バイナリ、設定、サービスユニットを保管し、mihomo -vの出力を記録してください。新しいバイナリで既存設定に-tを実行してから、入れ替えと再起動を行います。アップグレード後は、サービスの状態、7890の待ち受け、明示的なプロキシリクエスト、パネル接続を順に確認してください。失敗した場合は、ネットワーク設定を次々に変更するのではなく、旧バイナリと互換性のある設定に戻します。

導入完了の最低条件は、システム再起動後にサービスがactiveであること、プロキシポートが想定したアドレスだけで待ち受けること、アプリがルールに従ってリクエストを送信できること、コントロールAPIへ保護された管理経路からアクセスできることです。プロセスの存在だけを見るより、この4点を個別に検証するほうが確実です。

Clashをダウンロード