Clash Meta 外部コントローラー:bind-address・secret・ファイアウォールでリモート管理を安全にする
Clash Meta(Mihomo)には、設定の再読み込みや接続一覧、ルール切り替えなどを行う REST API が付いており、多くのグラフィカルクライアントはこれを external-controller として参照します。同じポートにWeb ダッシュボードを載せる構成も一般的です。ここが 0.0.0.0 で広く開き、かつ secret(共有鍵) が空のままだと、LAN 内の誰でも/場合によってはインターネット側からプロキシ制御面に触れうる状態になります。本稿では bind-address での待受範囲の決め方、secret と Authorization: Bearer、OS・ルーターのファイアウォールを段階的に揃える手順を整理します(自分が合法的に管理する端末に限る前提です)。
external-controller が担う役割
設定ファイルのトップレベルにある external-controller は、「どの IP とポートで API を公開するか」を指定します。グラフィカル UI、スマホ向けリモートアプリ、自作スクリプトはすべてここへ HTTP で接続します。ポート番号は環境ごとに異なりますが、プロキシ用の mixed-port や redir-port とは別物です。混同すると「プロキシは通るのにダッシュボードだけ繋がらない」といった切り分けが難しくなるため、まずリスニング一覧を確認してください。
Clash Meta 系ではダッシュボードの静的ファイルを同じコントローラーから配信する例が多く、ブラウザで http://<ホスト>:<ポート>/ui のような URL を開く運用があります。つまり コントローラーを広く公開することは、管理 UI ごと広く公開することになります。データプレーン(実トラフィック)より制御プレーンのほうが攻撃価値が高い、と考えると安全設計の優先度がはっきりします。
bind-address:127.0.0.1・LAN・0.0.0.0 の違い
待受アドレスは実装と設定の組み合わせで決まります。一般的な整理は次のとおりです。
- 127.0.0.1(localhost のみ):同じマシン上のブラウザやローカルツールだけが接続可能。最も安全な既定寄りの選択。
- 特定の LAN IP(例:192.168.1.10):そのインターフェースにだけバインドし、同じサブネットの端末からのみ到達しやすくする。NIC が複数ある PC や NAS で迷いにくい。
- 0.0.0.0(全インターフェース):LAN・VPN・場合によっては WAN 側インターフェースまで含めてリッスンするため、ファイアウォールと secret の両方が必須級になる。
スマホから同じ Wi-Fi 上の PC を操作したい場合、127.0.0.1 だけでは届きません。そこで LAN IP か 0.0.0.0 に広げる必要が出ますが、その瞬間から脅威モデルは「悪意ある同一 LAN 端末」も含むと考えてください。ゲスト Wi-Fi やシェアハウス、オフィスの混在 VLAN では特に secret と FW 制限を同時に満たすのが現実的です。
まず決めること
「同一 PC だけ」「自宅 LAN の信頼端末だけ」「VPN 内だけ」のどこまでを許容するかを書き出し、その範囲に合わせて bind と FW の送信元 IP 制限をセットにする。片方だけ広げると穴が残りがちです。
secret と Authorization:未鑑権を残さない
secret に長いランダム文字列を設定すると、API リクエストは Authorization: Bearer <secret> ヘッダー、または実装が許すトークンクエリなどで同一値を提示する必要があります。ダッシュボードの URL にトークンを付ける例もありますが、共有リンクの流出=フル管理権限の流出と同義です。ブラウザ履歴やスクリーンショットに残さない運用を意識してください。
secret を空にすると、LAN 内の他端末から設定の書き換えやノード一覧の取得が行える可能性があります。これは「知人に Wi-Fi パスを教えた」程度のリスクではなく、スキャンに対して無防備なので、本番運用では避けるべきです。クライアントが設定ファイルを上書き保存するたびに secret が消える場合は、テンプレートと実ファイルの差分を確認し、GUI の「上書き後も残る欄」に固定してください。
HTTPS ではないことが多い
ローカル HTTP は平文です。同一 LAN のパケットスニッファに secret が読まれるリスクをゼロにしたい場合は、リバースプロキシで TLS 終端するか、SSH トンネル/VPN 内だけに閉じるのが現実的です。いずれにせよ「平文でも secret なしよりマシ」ではあり、まず secret は必須です。
設定例(概念)
実際のキー名はバージョンとフロントエンドの期待に合わせてください。以下は「LAN の 9090 で待ち、秘密鍵を付ける」イメージです。
# Illustrative — adjust keys for your Meta version and UI
external-controller: 0.0.0.0:9090
secret: "replace-with-long-random-string"
# Some setups use separate bind fields — follow your client docs
external-controller を 192.168.1.10:9090 のようにホスト部を特定 IP に固定できる環境なら、0.0.0.0 より意図が明確になります。Docker や Linux の無頭サーバでは 「Clash Meta の Docker Compose」や 「Linux 無頭と systemd」の記事とあわせ、コンテナの publish とホスト FW の二重管理に注意してください。どちらか一方だけ開いて見えない、あるいは逆に二重で広く開く、どちらも起こり得ます。
疎通確認と切り分け
変更後は次の順で確認すると早いです。
- 同一ホストで
curlやブラウザから127.0.0.1宛にヒットするか。 - LAN の別端末から、
http://<サーバ LAN IP>:<port>に届くか。届かない場合は OS ファイアウォール・ルーター AP 隔離・クライアントの bind 設定を疑う。 - secret ありで 401/403 になり、正しい Bearer で 200 になるか。
プロキシの 「mixed-port と allow-lan」はデータ用の話であり、コントローラー端口とは別です。両方を LAN に開く場合は、ポートごとに FW ルールを分け、コントローラー側だけ送信元 IP を厳しくするのがおすすめです。
OS ファイアウォールの考え方
方針は共通で、「必要な送信元(IP またはサブネット)だけを許可し、それ以外は拒否」です。
| 環境 | 典型的な操作 |
|---|---|
| Windows | 「セキュリティが強化された Windows ファイアウォール」の受信規則で TCP ポートを追加し、リモート IP を自宅サブネットに限定。 |
| macOS | システム設定のファイアウォール、またはサードパーティルールで同様に限定。クライアントが署名付きバイナリの許可を求める場合あり。 |
| Linux(nftables / iptables) | INPUT チェーンで -s 192.168.0.0/16 -p tcp --dport 9090 -j ACCEPT のように狭くし、最後に DROP/REJECT。 |
クラウド VPS にコントローラーを晒すのは原則非推奨です。どうしても必要なら、公開鍵認証の SSH ローカルポートフォワード(-L)や WireGuard など別レイヤで認証したトンネルの内側だけに 127.0.0.1 バインドを置くほうが安全です。世界に向けて 9090 を開き secret 一本、ではブルートフォースや実装脆弱性のリスクが残ります。
ルーター・AP 隔離の落とし穴
最近の家庭用ルーターは「ゲストネットワーク相互非表示」をデフォルトにしていることがあります。スマホがゲスト SSID、PC がメイン SSID だと、どちらも同じ「インターネット出口」でもレイヤ 2 で届かないため、コントローラーに繋がりません。逆に、隔離が無効な共有 Wi-Fi では、secret なしのコントローラーが同じ空間にいる全端末に見えることになります。
よくある質問
ダッシュボードが 401 のまま
URL にトークンを付ける方式の UI では、手入力ミスや設定の再読み込み後の不一致が多いです。ブラウザのシークレットウィンドウで開き直し、クライアントが参照している実ファイルの secret と一致しているか確認してください。
Docker でホストから見えない
127.0.0.1:9090 をコンテナにマップすると、ホストの localhost からは見えても、LAN の別端末からは見えません。publish の形と、コンテナ内の bind が 0.0.0.0 かどうかをセットで確認します。
LAN 内なのに繋がらない
企業 VPN が全トラフィックを吸い、ローカルサブネットに戻れないケースや、複数 NIC で誤ったアドレスにバインドしているケースがあります。ss -tlnp や OS 相当のコマンドで実際のリスンを見てください。
チェックリスト
- コントローラーとプロキシのポートを混同しない。
- 待受範囲(127.0.0.1 / 特定 IP / 0.0.0.0)を脅威モデルに合わせて選ぶ。
- 十分に長い
secretを設定し、Bearer で検証できることを確認する。 - OS FW で送信元 IP を絞り、不要なら WAN から到達不能にする。
- 平文 HTTP の限界を理解し、必要なら TLS またはトンネルで包む。
まとめ
external-controller は便利ですが、放置するとプロキシの首根っこをネットワーク上に晒すことになります。bind-address で面を狭め、secret で鑑権し、ファイアウォールで送信元を絞る、の三層を同時に満たすのが実務的です。初めて Clash 系を触る方は 「初心者ガイド」で全体像を押さえたうえで、本稿の設定を足してください。