Linux ヘッドレス環境での Clash Meta:インストール、systemd 常駐、サブスクリプション自動更新
Windows/Android 向け記事は GUI を前提にしていますが、VPS や自宅の無 GUI サーバーではトレイアイコンもウィザードもありません。長く生き続ける単一プロセス、YAML 設定、異常時に再起動してくれるスーパーバイザがセットになります。本稿では多くの利用者が mihomo リリースとして入手する Clash Meta 系スタックを例に、バイナリ配置、定期取得する proxy-providers、本番想定の systemd ユニット、ブート順序、curl や git 向けの CLI プロキシ 環境変数、無停止に近い設定リロードの考え方までをまとめます。サイドルータやリモート開発機の土台として、そのまま運用に載せやすい流れです。
ヘッドレス Linux で Clash Meta を選ぶ理由
ヘッドレス環境にはトレイもプロファイルウィザードもありません。挙動はすべて設定ファイルに書き、init 系で強制します。Meta 系コアは多くのプロバイダが前提とする機能やルールエコシステムに追従しやすく、ノート PC クライアントとデータセンター中継で同じパターンを流用しやすいのが利点です。Clash はローカルポート(多くは HTTP/SOCKS 兼用の mixed-port)で待ち受け、ルールに従ってアウトバウンドへ流します。外部コントローラは REST API を公開するため、状態確認やプロファイル切替、リロード要求を自動化でき、UI が SSH だけのときに特に効きます。
デスクトップ向けチュートリアルと比べると、サーバー運用では三つの責務が繰り返し現れます。第一に、アーキテクチャに合った実行ファイルを配布し、プロトコル変化に合わせて更新すること。第二に、ディレクトリ権限は最小権限へ:専用アカウントで動かし、秘密情報を world-readable に置かず、書き込みが必要な provider キャッシュを静的設定から分離する。第三に、systemd と統合してクラッシュを一過性にし、ネットワーク準備への依存を明示し、journalctl で観測可能にする。ここまで固めると、透過転送や TUN 的な取り込みは段階的な拡張になり、一度きりの脆い構成になりにくくなります。
前提:ユーザー、ポート、コールドスタート
チェックリスト
- アーキテクチャ:
uname -mで確認し、リリース資産(amd64、arm64など)と一致するものを取得する。 - サービスユーザー:
clashやmihomoなどを作成し、設定ツリーの所有者にする。 - ポート設計:mixed または分割 HTTP/SOCKS、
external-controllerを確保し、コントローラをインターネットに晒さない。 - サブスク到達性:URL が既存プロキシ経由でしか取れない場合は、provider ファイルを別ホストで取得して持ち込むなどコールドスタート経路を用意する。
サイドルータ読者はカーネル転送や nftables、DHCP と組み合わせることもありますが、本稿は「そのマシン上で信頼できる SOCKS/HTTP 出口を得る」ところまでを対象にします。systemd でパスとログが安定していると、ゲートウェイ連携の後工程がずっと楽になります。
mihomo(Clash Meta)バイナリのインストール
GitHub Releases などから現行版を取得し、アーキテクチャに合うアーカイブまたは単体バイナリを /usr/local/bin/mihomo のような標準パスへ配置します。公開されているチェックサムがあれば検証してください。ディストリビューションのパッケージや AUR も可ですが、古いビルドは新しい YAML キーを拒否して即終了し、ログでは原因不明のサービス失敗に見えがちです。
uname -mの出力とリリース資産名を突き合わせる。- 公開されているダイジェストがあれば整合性を確認する。
sudo install -m 0755 mihomo /usr/local/bin/mihomoなどで配置する。- サービスユーザーで
mihomo -vを実行し、動作と依存を確認する。
ヒント
root で広い権限を付け替えるより、systemd の ReadWritePaths と専用ユーザーの組み合わせを優先してください。後者の方がサブスク URL の露出リスクを抑えられます。
設定ディレクトリと最小スケルトン
実運用では /etc/mihomo や /var/lib/mihomo に config.yaml を置き、所有者を揃えます。リスナー、モード、ログ、コントローラバインド、読み込む proxy-providers/rule-providers を宣言します。サーバーでは secret を必ず設定し、露出モデルを理解していない限り 127.0.0.1 にバインドするのが無難です。
次のスケルトンは関係を示す最小例です。本番前に実際のポリシーグループ、パーサ、ルールで拡張し、URL はプロバイダのものに差し替えてください。
port: 7890
socks-port: 7891
mixed-port: 7893
mode: rule
log-level: info
external-controller: 127.0.0.1:9090
secret: "change-me"
proxy-providers:
airport:
type: http
url: "https://example.com/subscription"
path: ./providers/airport.yaml
interval: 3600
health-check:
enable: true
interval: 600
url: https://www.gstatic.com/generate_204
proxies: []
proxy-groups:
- name: PROXY
type: select
use:
- airport
rules:
- MATCH,PROXY
interval はコアがサブスクリプションを再取得してメモリへマージする周期です。ヘルスチェックでノードを積極的に試し、手動ローテーションを減らせます。プロバイダが provider 断片ではなく完全プロファイルを返す場合は、利用バージョンのドキュメントに合わせて構造を調整してください。フィールド名は進化し、厳格なパーサは失敗時に即終了します。
systemd ユニットの記述
/etc/systemd/system/mihomo.service を作成します。Type=simple、WorkingDirectory を設定ルートに、起動は mihomo -d /path。Restart=on-failure と適切な RestartSec、負荷時のための LimitNOFILE を設定します。PPPoE や VPN でリンクが不安定なら After=network-online.target に揃え、ディストリが実際にルーティング可能になるまで待つ仕組みがあるか確認してください。さもなくば初回取得がレースし、provider が空のままになることがあります。
[Unit]
Description=mihomo (Clash Meta) daemon
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=mihomo
Group=mihomo
WorkingDirectory=/etc/mihomo
ExecStart=/usr/local/bin/mihomo -d /etc/mihomo
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reloadsudo systemctl enable --now mihomo.servicesystemctl status mihomoでactive (running)を確認- YAML エラー、DNS 失敗、ポート競合は
journalctl -u mihomo -eで追う
セキュリティ
ファイアウォールと強い secret なしに external-controller を晒すのは、プロキシ方針を遠隔操作できるリモコンを公開するのと同義です。既定はループバックにし、別マシンからは SSH ポートフォワードで管理するのが安全です。
環境変数による CLI・自動化
mixed-port がローカルで待ち受けると、多くのツールが http_proxy、https_proxy、all_proxy を解釈します。curl、wget、各種パッケージマネージャ、標準変数に対応した CI にとって摩擦が最も小さい経路です。例(ポートは設定に合わせて変更):
export http_proxy="http://127.0.0.1:7893/"
export https_proxy="http://127.0.0.1:7893/"
export all_proxy="socks5://127.0.0.1:7893/"
大文字のみ/小文字のみを読むツールもあります。メンテナンストラフィックを直送したいなら、グローバルプロファイルに書かずシェル単位や env http_proxy=... curl ... のようにコマンド単位で渡してください。プロキシを無視するアプリには proxychains や redsocks、TUN 層が必要になりますが運用面が広がるので、環境変数で足りないときの拡張と考えます。
ヒント
fake-ip など DNS 負荷の高いモードでは、バージョン別ドキュメントを読んでください。DNS を誤るとローカルサービスがプレースホルダアドレスに解決し、同一ホスト上の無関係なデーモンまで壊すことがあります。
サブスク更新と設定リロード
interval による provider 取得は、多くの場合プロセス全体を再起動せずノード一覧を更新します。config.yaml 本体を編集し(provider 追加、ルールファイル変更、リスナ変更など)、完全な再読込が要る場合は外部コントローラ API にシークレット付きでアクセスするのが一般的です(パスはリリースごとに異なり、/configs への PUT パターンが多い)。単純には systemctl restart mihomo も使えますが短時間の切断は発生します。
任意で systemd timer を用意し、時間ごとに curl スクリプトで強制更新する方法もあります。プロバイダ側のエンドポイントが不定期に変わり、すべての interval を短くしたくないときに有効です。トークンはモード 600 の EnvironmentFile に置きユニットから参照し、世界読み取り可能なヘルパースクリプトに埋め込まないでください。
サーバーでは可観測性が重要です。構造化ログに加え、コントローラのヘルスルートがあれば HTTP GET、または mixed-port 経由の定期 curl で、自動化スタックより先に provider 沈黙を検知しましょう。
よくある質問
起動直後に終了し「address already in use」
ss -lntp や lsof -i :7893 で待受を確認してください。手動起動の残骸や別プロキシが mixed/controller ポートを掴んでいる可能性があります。スーパーバイザは systemd に一本化し、二重のフォアグラウンド実行を止めます。
サブスクリプション取得が常に失敗する
同一ホストから curl -v で DNS・TLS・パスを切り分けます。既存プロキシがないと届かない URL なら、信頼できるマシンで初期 providers を用意するか、一時的に届くネットワークで取得し、ノードが通った後は定期更新に任せます。ホスト名の別ラインを試す方が、interval を盲信して詰めるよりコールドスタート改善につながることが多いです。
provider キャッシュ書き込みで権限エラー
実行ユーザーとディレクトリ所有者を一致させ、WorkingDirectory 配下に ./providers を用意してください。ドキュメントのサンプルを root 所有のままコピーし、非 root ユーザーで動かすのは典型ミスです。
まとめチェックリスト
- アーキテクチャ一致のバイナリを管理されたパスへ入れ、バージョン文字列を確認する。
proxy-providersと適切な interval、必要ならヘルスチェックを含むconfig.yamlを書く。- 再起動ポリシー、ファイル記述子上限、現実的なネット依存を含む systemd ユニットを配布する。
- mixed-port はローカルのみ、CLI には環境変数、コントローラはループバックを基本とする。
- 構造変更は API リロードか計画的再起動、日々のノード更新は interval に任せる。
デスクトップ版も欲しい場合
サーバーは YAML と systemd のまま、ワークステーションはインポート補助付き GUI が向きます。本ヘッドレス構成を上流やゲートウェイにしつつ、Windows/macOS では使いやすい統合ビルドが必要なら ダウンロードページ もあわせてご利用ください。