安全與隱私 · Clash 技術部落格

Clash Dashboard 怎麼安全遠端存取?

Dashboard 實際連線的是可以切換節點、改設定和關閉連線的控制介面。需要遠端使用時,應先限制監聽位址並設定 secret,再透過內部網路或隧道存取。

  • 安全
  • Dashboard
  • secret
本文目錄

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。圖形用戶端可能透過「設定 → 外部控制器」或覆寫檔案產生這個欄位,因此修改訂閱原文未必會生效;重載後要查看最終設定和實際監聽。

下面的 REPLACE_WITH_RANDOM_SECRET 只是佔位符。先用密碼管理器產生一段長隨機值,把設定和 Dashboard 連線設定中的值同時替換,再重載 Mihomo。不要把佔位符原樣當密碼。

只供本機 Dashboard 使用的起點
external-controller: 127.0.0.1:9090
secret: "REPLACE_WITH_RANDOM_SECRET"
確認誰在監聽 9090
# 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 的請求得到 401,而不是版本 JSON
  • 正確 secret 能讀取 /version
  • 錯誤 secret 也被拒絕
  • Dashboard 重新整理後能正常顯示連線與代理群組
  • 日誌和瀏覽器位址欄沒有暴露 secret

Dashboard 打不開時,不要直接把 CORS 放成任意來源

遠端托管的 Dashboard 是一個網頁來源,它在瀏覽器裡向 external-controller 發請求。CORS 只限制哪些網頁來源可以呼叫介面,不能替代使用者認證。

把 allow-origins 設為 *,再允許私有網路請求,會讓任意網頁更容易嘗試存取本機或區域網路控制連接埠。即使設定了 secret,洩露後可被利用的範圍也會更大。

先確認 Dashboard 的實際 origin,例如 https://dashboard.example.com,再只放行這個完整來源。網域、協議或連接埠變化都會形成不同 origin。設定中的 UI 靜態檔案路徑和 API 監聽位址也不是一回事:頁面能開啟,不代表控制 API 已安全連線。

把示例網域替換成實際 Dashboard 來源
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。

示例:將遠端控制器映射到本機 19090
ssh -N -L 19090:127.0.0.1:9090 [email protected]

# Dashboard 后端填写
http://127.0.0.1:19090

使用 Tailscale 時也不要預設整個 tailnet 都是管理員。透過 tailnet policy 限制哪些使用者或裝置能存取主機與連接埠,再保留 secret。家庭路由器上若必須監聽 LAN 位址,防火牆規則只允許管理電腦,不要允許 Guest Wi-Fi 或整個 WAN zone。

遠端管理面板的安全存取路徑
  1. 你的瀏覽器只從受信裝置發起存取
  2. SSH 隧道或 VPN不直接暴露控制連接埠
  3. 127.0.0.1:9090external-controller 僅本機監聽
  4. Mihomo使用 secret 驗證控制請求

如果必須監聽區域網路位址,也要同時限制防火牆來源,並保留足夠長的 secret。

需要長期存取時,再在 9090 前增加反向代理

只有需要固定網域和長期遠端存取時,才值得部署反向代理。Mihomo 的 external-controller 仍監聽 127.0.0.1:9090,由同機的 Nginx、Caddy 或其他閘道對外提供 HTTPS;公用網路只開放反向代理連接埠,不開放 9090。

反向代理至少要有可信 TLS、獨立登入或用戶端認證、來源限制和存取日誌,並正確轉發 Dashboard 使用的 WebSocket。Mihomo 的 secret 仍然保留,它和反向代理登入是兩層保護,不能互相替代。secret 放在 Dashboard 的連線設定中,不拼進公開 URL。

若 Dashboard 網頁與 API 使用不同網域,還要把實際網頁 origin 精確加入 CORS。設定完成後,從公用網路掃描或另一台裝置測試:HTTPS 網域可以登入,直接存取伺服器公用網路 IP:9090 應連線失敗。

長期遠端入口應滿足

  • external-controller 仍只監聽 127.0.0.1
  • 公用網路沒有 9090 連接埠映射
  • 反向代理強制 HTTPS 並有獨立認證
  • WebSocket 日誌和流量頁面可正常更新
  • Mihomo secret 仍驗證成功
  • 未授權來源無法存取

從伺服器本機和另一台裝置各測一次

完整驗收

  1. 本機看監聽

    確認連接埠綁定的是預期位址,處理程式確實為目前 Mihomo,而不是舊實例。

  2. 未授權存取

    用 curl 請求 /version,確保缺少或錯誤 token 都回傳 401。

  3. 授權存取

    開啟 Dashboard,切換一個測試策略群組並在 Mihomo 中看到相同結果。

  4. 從無權限網路測試

    從不應有權限的 LAN、Guest Wi-Fi 或公用網路位址測試,連線應超時或被拒絕。

  5. 重啟重新測試

    重啟 Mihomo 後確認監聽位址、secret 和防火牆規則沒有被用戶端覆寫。

如果懷疑控制器曾經暴露,先收緊監聽和防火牆,再輪換 secret。隨後檢查連接埠映射、雲安全組、反向代理存取日誌和設定儲存庫歷史;只改 Dashboard 密碼不能讓已經洩露的 Bearer Token 失效。

參考資料