検索意図:何が「開かない」のかを言語化する

ユーザーが「パネルが開かない」と言うとき、実際には次のどれかに分かれます。(1) ブラウザのタブが出るが API エラーで回転し続ける。(2) そもそも TCP で拒否され connection refused。(3) 自分の PC では動くが、同じ Wi-Fi の別ノートから http://192.168.x.x:9090 が届かない。(4) secret を聞かれる/401 相当で弾かれる。症状ごとに見るべき YAML キーが変わるため、まずは自分のケースをここに当てはめてください。

Yacd や MetaCube 系の軽量 UI は、すべて「コアの REST API に JavaScript から叩く」前提です。したがって ダッシュボード単体を直すのではなく、external-controller が生きて応答しているかを先に確かめるのが早道です。GUI クライアントの初回設定でポートを変えた直後によく起きるので、GUI に表示される実効ポートと YAML の一致も忘れずに。

external-controller・bind-address・ポートの関係

Clash 系コアでは、外から操作する HTTP API の待ち受けを external-controller で指定します。典型的には 127.0.0.1:9090 です。ここで注意なのは、待ち受けアドレスを別キー(例:bind-address、または Mihomo/実装ごとの external-controller-tls などの拡張)で上書きしたり、TUN やプロファイル切替で一時的にコントローラが無効化されているケースです。

bind-address127.0.0.1 のままなのに、「スマホから同じ LAN の PC の IP で開きたい」という要件だけ持ち込むと、論理的に届きません。逆に 0.0.0.0 で広く開くと便利そうに見えますが、秘密鍵なしのまま WAN 側に晒すのは避けるべきです。ホーム LAN 内に限定し、必ず secret を設定し、必要ならファイアウォールで絞り込みます。LAN 越しのプロキシ共有の稿で触れた allow-lan(プロキシ側)と混同しないよう、今回の話は 管理 API の待ち受けに特化しています。

設定ファイルで最初に並べるべきキー

多くのテンプレでは、コントローラ周りは次のような塊になります(値は環境に合わせて読み替え)。

# Example only — match keys to your Mihomo / Clash variant and version
external-controller: 127.0.0.1:9090
# bind-address: 127.0.0.1   # if your build separates listen address
secret: "replace-with-a-long-random-string"

secret を空にすると手軽ですが、誰でもルールや接続を弄れる状態になります。少なくともローカル専用でもランダム文字列を入れる習慣をつけると、後から LAN を開いたときも安全側に寄せられます。GUI クライアントが 「上書きプロファイル」を生成している場合、エディタで開いている YAML と実行時に食わせている YAML が別物になっていることがあります。症候が矛盾するときは、UI の「設定の保存先」「実行中のプロファイル名」を確認してください。

一次切り分け:同一マシンから curl で生きているか

ブラウザより先に、ターミナルで TCP が開いているかを見ます。macOS や Linux なら次のようなコマンドが扱いやすいです(secret があるときはヘッダを足す)。

# If secret is unset, omit the Authorization header
curl -sS http://127.0.0.1:9090/version

curl -sS -H "Authorization: Bearer YOUR_SECRET" http://127.0.0.1:9090/version

ここで既に接続拒否なら、コアが起動していないか、external-controller のポートが別、あるいは他プロセスが 9090 を占有している可能性が高いです。Windows の場合は同名の「別の Clash 互換プロセス」が残っているとポートだけ衝突することもあるため、タスクマネージャと GUI の「停止」ボタンを併用して一度クリーンにしてから再試行するのが確実です。

応答ボディが JSON で返ってくれば、REST レイヤは生存しています。ここで失敗する段階では Yacd を当てにしないでください。API が確定してから初めて、UI 側の URL 入力(http://127.0.0.1:9090 と秘密鍵)を疑います。

二次切り分け:別 PC から叩く条件

同一 LAN の別マシンから管理したい場合、(1) 待ち受けを 0.0.0.0:9090 もしくは「external-controller にその PC の LAN IP」を明示する、(2) OS のファイアウォールでそのポートの着信を許可する、(3) secret を必ず入れ、ブラウザに絶対に入れない場所で共有する——の三段が必要です。購読 URL と同様に、秘密情報はチャットやスクリーンショットに写さない運用が安全です。

「プロキシのポートは LAN から通るのに、9090 だけ通らない」というのは典型で、プロキシ用の allow-lanコントローラの bind は独立している実装がほとんどです。片方だけ整えても、管理 UI は開きません。片方の稿では済まない、という意味で本稿を独立させています。

Yacd/埋め込みダッシュボードと API の突き合わせ

Yacd は静的なフロントエンドに近く、配布元のページで「API のベース URL」を入力させます。ここに 127.0.0.1:9090 と入れても、HTTPS のページから混在コンテンツとしてブロックされるケースや、ブラウザ拡張が localhost を横取りするケースがあります。症状がブラウザ依存で変わるときは、別ブラウザかプライベートウィンドウで切り分けてください。

公式やサードパーティの「オンライン版 Yacd」に自分の API を指させるのは、トークンを第三者ドメインに送るリスクがあります。可能ならローカルにホストするか、信頼できる同一オリジンに閉じてください。MetaCube/Mihomo 系がバンドルするダッシュボードでも、根っこは同じ REST です。表示が古いままなら、ブラウザキャッシュではなく API の /configs が本当に更新されたかを疑います。

TLS・カスタムヘッダ・リバプロの落とし穴

自身で Nginx や Caddy の背後にコントローラを置き HTTPS 終端する構成では、WebSocket 相当の更新や CORS、Authorization ヘッダの透過を正しく設定しないと UI だけ壊れます。また一部の実装では Bearer ではなく別のヘッダ名を期待するウィンドウがあり、バージョン差で詰まることがあります。ミスマッチしたらまず 同一マシンから素の HTTP で curl が通る状態に戻し、逆算してリバプロ設定を直すのが手早いです。

WSL2・Docker・VM の「どのループバックか」

Windows ホストでコアを動かし、ブラウザだけ WSL 内の Linux から開こうとすると、127.0.0.1 の指し先がホストとゲストで別物になります。Docker でもコンテナ内の localhost はコンテナ自身です。環境をまたぐときは、明示的にホストの IP を叩くか、ポート公開のマッピングを整理してください。この手の「見えているつもりの localhost」は、エラーメッセージが短くても実はかなり多いので、ネットワーク境界を一つずつ言語化すると解決が早くなります。

最終チェックリスト(コピー用)

  1. 実行中プロファイルの external-controller が、UI に入力したホスト:ポートと一致するか。
  2. 同一 OS 上の curl /version が、期待する secret で成功するか。
  3. LAN 越しなら待ち受けがループバック専用になっていないか、FW で 9090 が開いているか。
  4. 別プロセスが同じポートを占有していないか。
  5. HTTPS ページから HTTP API を呼んでいないか(混在ブロック)。
  6. GUI の一時プロファイルとディスク上の YAML が同一か。

セキュリティの一文メモ

外付けコントローラは、プロキシ本体と同等かそれ以上に強い権限を持ちます。検証が終わったら、不要なら LAN 向けの広い bind を閉じる、ルータのポート開放で WAN に直晒さない、VPN 出口のマシンでは特に二重化する——を習慣にしてください。

まとめ

Yacd や外付け Web UI の不調の多くは、見た目のフロントではなく external-controller の REST が先に死んでいることに起因します。bind-address とポート、secret、同一マシンからの curl、LAN なら FW と待ち受け範囲——この順に実測すれば、connection refused も別 PC からのタイムアウトも、原因の筋がほぼ見えてきます。エラーコードの寄せ集めではなく、外付けコントローラ単体の設計思想に沿って切り分けるのが本稿の狙いでした。

ダッシュボードとログを一つのクライアントで扱えると、この種の確認も短時間で済みやすくなります。→ Clash を無料ダウンロードし、external-controller の疎通を確かめたうえで Yacd をもう一度開いてみる