Web 面板背後其實是什麼?
不論你用的是內建儀表板、瀏覽器開 http://127.0.0.1:9090/ui,還是外掛的 yacd/metacubexd,本質上都是在透過 REST API 和核心溝通:讀取目前版本、列出代理與規則、切換節點、觸發重新載入設定。對 Clash Meta/mihomo 來說,這組介面通常由設定檔裡的 external-controller(對外控制器位址與埠)決定要在哪一張網路介面、哪一個埠上提供服務。
因此「開 Web 面板」與「開了一個可遠端操作代理核心的管理埠」幾乎是同一件事。若監聽範圍太大、又沒有驗證,任何能連到該埠的程式或人,都有機會在未登入你作業系統帳號的情況下,透過 HTTP 讀寫狀態——這就是許多教學文會警告的 未授權存取 場景。接下來我們依序處理:先縮小監聽範圍(bind-address 與 external-controller 的組合),再加上 secret,最後若你真的需要從另一台裝置管理,再談防火牆、SSH 隧道或反向代理,而不是一開始就把埠丟到公網。
第一步:把 external-controller 綁在你真的需要的地方
常見的預設寫法是 external-controller: 127.0.0.1:9090,代表只有本機迴圈位址能連上管理 API。這對「只在這台電腦上用瀏覽器看面板」已經足夠,也是風險最低的預設。若你改成 0.0.0.0:9090 或本機的區網 IP,等同告訴作業系統:所有介面上到達該埠的連線都可能被接受——區網裡其他裝置、錯誤轉發的連接埠,甚至(在路由或防火牆設定不當時)外網掃描,都會一併納入攻擊面。
部分進階設定還會看到 external-controller-pipe(命名管道,常見於 Windows)或與 TLS 相關的選項;一般桌面用戶先專注在 external-controller 與下文要談的 secret 即可。若你使用圖形用戶端,介面裡「允許區域網路存取儀表板」之類的開關,往往就對應到把控制器從 127.0.0.1 改為對區網開放——開之前請先想清楚:你是不是真的需要用手機在區網內改節點?若只是偶爾看一下狀態,維持本機連線再搭配 SSH 轉發通常更安全。
bind-address 與「誰能碰到管理埠」
bind-address 主要影響的是代理埠(例如 mixed-port)要綁在哪;與 external-controller 不一定永遠同一組邏輯,但概念相通:都是「服務要聽在哪個位址」。若你曾依 區網共用代理 一文把代理開給家裡其他裝置,請務必把「給別人上網用的埠」和「能改設定的管理埠」在心裡分開——前者可以配合 allow-lan 謹慎開放,後者仍建議預設只留在本機。
第二步:一定要設 Secret(並妥善保管)
當 secret 留空或未設定時,許多環境下 API 會以無需驗證的方式回應(實際行為依版本與用戶端包裝略有差異,但「沒密碼=任何人都能叫 API」永遠要當成預設假設)。一旦你把控制器聽在區網可達的位址,等於把家裡 Wi‑Fi 上任意裝置都變成潛在管理員。正確做法是在設定檔頂層加入足夠長、足夠隨機的密鑰,例如:
# Example: lock down the REST API (replace with your own long random string)
external-controller: 127.0.0.1:9090
secret: "change-me-to-a-long-random-string"
呼叫 API 時,客戶端會在 HTTP 標頭帶上 Authorization: Bearer <你的 secret>(舊版或部分工具也可能使用 Bearer 以外的形式,請以你使用的面板說明為準)。重點是:Secret 不是給人記來「登入網頁」的口號,而是給程式用的令牌;任何人拿到同一組字串,就等同拿到管理權限,所以不要寫在公開截圖、不要貼到論壇、也不要和訂閱網址擺在同一個可被同步到雲端的明文筆記裡。
secret 之後,已開著舊連線的瀏覽器分頁可能會突然 401;這是正常現象。請在面板設定裡更新同一組密鑰,或清除本機儲存的 API 位址後重新連線。
第三步:用 curl 自己驗證「有沒有鎖好」
改完設定並重載核心後,建議在本機終端機直接打 API,比只看「網頁能不能開」更可靠。下列範例假設控制器在 127.0.0.1:9090,且你已設定 secret:
# Should succeed when Authorization matches secret
curl -sS -H "Authorization: Bearer change-me-to-a-long-random-string" \
http://127.0.0.1:9090/version
# Should fail (401/403) without the header — if it still returns JSON, fix your config
curl -sS http://127.0.0.1:9090/version
若省略標頭仍能讀到版本資訊,代表核心仍處於高風險狀態,請回頭檢查:設定是否真的載入、是否有多份 config.yaml、用戶端是否覆寫了你的修改。相對地,若帶正確 Bearer 仍失敗,常見原因是埠號不一致、實際監聽在 IPv6 的 ::1、或被另一個行程佔用了 9090。
第四步:只有必要時,才讓「區網或遠端」碰得到
若你堅持要在平板或手機上、於同一 Wi‑Fi 內調整節點,比起把 external-controller 直接改成 0.0.0.0,更穩健的順序通常是:
- 維持 API 只聽
127.0.0.1,並已設定強隨機secret - 從另一台裝置經 SSH 區域轉發(例如
ssh -L 9090:127.0.0.1:9090 user@電腦IP)把遠端瀏覽器流量隧道到本機——封包仍只在 SSH 裡走,管理埠不對整個區網廣播 - 若無 SSH,可改為在路由器或防火牆上限定來源 IP 範圍,只允許你家子網段連入該 TCP 埠,並確保沒有對 WAN 做連接埠轉發
- 仍不建議把 9090 類管理埠直接暴露在公網;若真有遠端維運需求,應優先 VPN、WireGuard 回內網,或放在有身分驗證與 TLS 的反向代理之後
這些作法與「把代理埠開給家人共用」不同;後者討論的是 HTTP/SOCKS 流量,前者是管理平面。混淆兩者時,最容易發生「為了手機能上網,順手把儀表板也開成全網可連」的遺憾。若你正在從舊版核心遷移,也可一併複習 Clash Meta 升級 mihomo 指南,裡面同樣提醒勿將 external-controller 大範圍綁在 0.0.0.0 卻無保護。
Web UI、external-ui 與日常習慣
部分設定會出現 external-ui 或類似欄位,用來指定內嵌儀表板的靜態檔路徑;實際對外提供頁面的仍是同一個控制器服務。換句話說,保護 API 就是保護面板。另外,請避免在咖啡廳、公司訪客 Wi‑Fi 上對外廣播自己的管理位址;若筆電同時連了多張網卡(有線+無線),也要留意作業系統防火牆是否對「公用網路」檔案開了不必要的入站規則。
Windows 使用者若剛接觸這些概念,可搭配 Clash for Windows 教學 先把「系統代理、UAC、防火牆提示」釐清,再回頭調整 YAML;否則常出現「檔案已改但執行中核心讀的是另一份設定」的假成功。
可照做的檢查清單(開面板前勾一輪)
external-controller是否僅在127.0.0.1(或你明確知情的單一介面)上監聽?- 是否已設定長度足夠的
secret,且未出現在公開截圖或版本庫裡? - 用
curl驗證:無Authorization時應拒絕,有Bearer時應成功。 - 若必須區網存取:是否已用防火牆或 SSH 縮小來源,而非裸聽
0.0.0.0? - 路由器是否未將 9090 轉到 WAN?筆電熱點、公共網路是否關閉了儀表板相關入站?
相較於只追求「面板漂亮、一鍵開啟」,把 REST API 當成與 SSH、資料庫管理埠 同級的服務來看待,長期維護成本反而更低:你不需要記一堆僥倖沒被掃到的理由,只要確定監聽範圍與 secret 始終合理即可。
若你希望少手動改 YAML、又能維持核心版本與安全選項同步更新,可以選用把 mihomo 整合良好的現代用戶端;相較於散落各處的舊版介面,它在儀表板開關與設定覆寫行為上通常更透明,也比較不容易在不知情下把管理介面暴露到區網。