目次
Clash Dashboard へリモートアクセスする場合は、管理用の入口として保護する
Clash Dashboard は external-controller が提供する REST API を通じて、接続、トラフィック、プロキシグループ、ルールを読み取ります。このインターフェースではノードの切り替え、設定の再読み込み、一部の実行時設定の変更、接続の終了も行えるため、9090 ポートを公開インターネットへ直接さらすリスクは、読み取り専用のステータスページを公開する場合よりはるかに高くなります。
まず、誰がアクセスする必要があるかを明確にします。ローカルだけで使うなら、ループバックアドレスだけでリッスンします。同じローカルネットワークから時々確認する場合も、接続元を制限し、secret とファイアウォールを設定してください。リモート管理には SSH トンネルまたは管理された Tailscale ネットワーク経由の転送を使い、0.0.0.0:9090 を公開インターネットへ直接マッピングしないでください。
アクセス場面と推奨する入口
| 状況 | リッスン方法 | アクセス制限 |
|---|---|---|
| ローカルクライアントに同梱されたパネル | 127.0.0.1:9090 | 強力な secret を設定し、任意のウェブページからローカルインターフェースを呼び出せないようにする |
| 家庭内 LAN からの管理 | 明示した LAN アドレスまたは制限付きのリッスン | ファイアウォールで管理デバイスまたはプライベートサブネットだけを許可 |
| 別の場所から一時的に保守 | 引き続きローカルホストだけでリッスン | SSH ローカル転送または Tailscale 経由でアクセス |
| 公開インターネット向けサービス | 直接公開は推奨しない | 少なくとも独立したリバースプロキシ、TLS、認証、接続元制限が必要 |
別のデバイスからアクセスする必要がなければ、リッスンアドレスをローカルホストへ限定する
最終的に有効となる Mihomo 設定で、external-controller を 127.0.0.1 にバインドします。GUI クライアントでは、「設定 → 外部コントローラー」またはオーバーライドファイルからこのフィールドを生成する場合があるため、元のサブスクリプションを編集しても反映されるとは限りません。再読み込み後に、最終設定と実際のリッスン状態を確認してください。
次の REPLACE_WITH_RANDOM_SECRET はプレースホルダーにすぎません。パスワードマネージャーで長いランダム値を生成し、設定と Dashboard の接続設定にある値を両方置き換えてから、Mihomo を再読み込みします。プレースホルダーをそのままパスワードとして使わないでください。
external-controller: 127.0.0.1:9090
secret: "REPLACE_WITH_RANDOM_SECRET"# Windows PowerShell
Get-NetTCPConnection -LocalPort 9090 -State Listen
# Linux / OpenWrt
ss -lntp | grep ':9090'secret の設定後、未認証のリクエストが実際に拒否されることを検証する
secret は外部コントローラーの Bearer Token です。空の値、短いパスワード、複数デバイスでの長期的な使い回しは、ポートへ到達できる相手へ管理権限を渡すのと同じです。ランダム値を生成し、Mihomo の設定と Dashboard のバックエンドアドレス設定へそれぞれ入力してください。完全な token をスクリーンショット、フロントエンドリポジトリ、公開の障害ログへ記載しないでください。
# 无 Authorization,应返回未授权,而不是接口数据
curl -i http://127.0.0.1:9090/version
# 错误 token 也必须被拒绝
curl -i -H "Authorization: Bearer WRONG_TOKEN" http://127.0.0.1:9090/version
# 只在自己的终端中替换 REAL_TOKEN
curl -i -H "Authorization: Bearer REAL_TOKEN" http://127.0.0.1:9090/version認証が機能していることを示す結果
- Authorization なしのリクエストでバージョン JSON ではなく 401 が返る
- 正しい secret で /version を読み取れる
- 誤った secret も拒否される
- Dashboard を更新すると接続とプロキシグループが正常に表示される
- ログとブラウザのアドレスバーに secret が露出していない
Dashboard を開けない場合も、CORS を任意のオリジンへいきなり許可しない
リモートでホストされた Dashboard は、ブラウザから external-controller へリクエストを送るウェブオリジンです。CORS はインターフェースを呼び出せるウェブオリジンを制限するだけで、ユーザー認証の代わりにはなりません。
allow-origins を * に設定し、さらにプライベートネットワークへのリクエストを許可すると、任意のウェブページからローカルまたは同一ネットワーク内のコントローラーポートへのアクセスを試みやすくなります。secret を設定していても、漏えいした場合の影響範囲は広がります。
まず Dashboard の実際の origin(例: https://dashboard.example.com)を確認し、その完全な origin だけを許可します。ドメイン、プロトコル、ポートのいずれかが変われば、別の origin になります。設定内の UI 静的ファイルのパスと API のリッスンアドレスも別物です。ページが開くからといって、コントロール API が安全に接続されているとは限りません。
external-controller-cors:
allow-origins:
- "https://dashboard.example.com"
allow-private-network: false一時的なリモート保守には SSH トンネルを使い、9090 をローカルへ転送する
Mihomo を自宅サーバーで動かす場合は、external-controller を 127.0.0.1:9090 のままにし、SSH ローカルポートフォワーディングでリモート側のループバックポートを現在のコンピューターへ転送できます。ブラウザは引き続き自身の 127.0.0.1 にアクセスし、公開インターネットから 9090 は見えません。
ssh -N -L 19090:127.0.0.1:9090 [email protected]
# Dashboard 后端填写
http://127.0.0.1:19090Tailscale を使用する場合も、tailnet 全体が管理者だと決めつけないでください。tailnet policy でホストとポートへアクセスできるユーザーやデバイスを制限し、secret も残します。家庭用ルーターで LAN アドレスのリッスンが避けられない場合は、ファイアウォールで管理用コンピューターだけを許可し、Guest Wi-Fi や WAN zone 全体は許可しないでください。
- 使用中のブラウザ信頼できるデバイスからのみアクセスする
- SSH トンネルまたは VPNコントローラーポートを直接公開しない
- 127.0.0.1:9090external-controller はローカルホストだけでリッスン
- Mihomosecret でコントロールリクエストを検証
LAN アドレスでのリッスンが避けられない場合も、ファイアウォールで接続元を制限し、十分に長い secret を設定してください。
長期アクセスが必要になった場合だけ、9090 の前段にリバースプロキシを追加する
固定ドメインと長期的なリモートアクセスが必要な場合に限り、リバースプロキシの導入を検討します。Mihomo の external-controller は引き続き 127.0.0.1:9090 でリッスンし、同じホスト上の Nginx、Caddy、または別のゲートウェイが外部向けに HTTPS を提供します。公開インターネットにはリバースプロキシのポートだけを開放し、9090 は開放しません。
リバースプロキシには、少なくとも信頼できる TLS、独立したログインまたはクライアント認証、接続元の制限、アクセスログを用意し、Dashboard が使用する WebSocket も正しく転送する必要があります。Mihomo の secret も残してください。secret とリバースプロキシのログインは独立した二層の保護であり、互いの代わりにはなりません。secret は公開 URL に付加せず、Dashboard の接続設定に保存します。
Dashboard のウェブページと API が異なるドメインを使用する場合は、実際のページの origin を CORS に正確に追加します。設定後は、公開インターネットからのポートスキャンまたは別のデバイスでテストしてください。HTTPS ドメインではログインでき、サーバーの公開 IP:9090 へ直接アクセスすると接続に失敗する状態が正解です。
長期運用するリモート接続口が満たすべき条件
- external-controller は引き続き 127.0.0.1 だけでリッスン
- 公開側に 9090 のポートマッピングがない
- リバースプロキシが HTTPS を必須とし、独立した認証を備えている
- WebSocket のログとトラフィックページが正常に更新される
- Mihomo の secret が引き続き正常に検証される
- 許可されていない接続元からはアクセスできない
サーバー本体と別の一台のデバイスから、それぞれ一度テストする
総合検証
ローカルでリッスン状態を確認
ポートが想定したアドレスにバインドされ、プロセスが古いインスタンスではなく現在の Mihomo であることを確認します。
未認証アクセス
curl で /version をリクエストし、token がない場合も誤っている場合も 401 が返ることを確認します。
認証済みアクセス
Dashboard を開いてテスト用のポリシーグループを切り替え、Mihomo 側にも同じ結果が反映されることを確認します。
権限のないネットワークからテスト
アクセス権を持たないはずの LAN、Guest Wi-Fi、または公開アドレスからテストし、接続がタイムアウトするか拒否されることを確認します。
再起動して再テスト
Mihomo を再起動した後、リッスンアドレス、secret、ファイアウォールルールがクライアントによって上書きされていないことを確認します。
コントローラーが公開されていた可能性がある場合は、まずリッスン範囲とファイアウォールを絞り、その後 secret をローテーションします。続いて、ポートマッピング、クラウドのセキュリティグループ、リバースプロキシのアクセスログ、設定リポジトリの履歴を確認してください。Dashboard のパスワードだけを変更しても、漏えいした Bearer Token は無効になりません。
