外部控制(external-controller)在做什麼,為什麼會變成安全話題?
在 Clash 系列核心裡,external-controller 是對本機 REST API 的聽地位址與埠號。圖形客戶端、自動化腳本、網路面板(如 Yacd 或內建儀表板)都依賴這個介面讀寫執行中狀態:顯示節點延遲、切換 策略組、重新載入設定、有時也會帶到訂閱內容或匯出設定。問題在於,這層能力並不是「看起來只能給本機用」的魔術,而是誰能連上 TCP 埠,理論上就能在沒有額外驗證的情況下下指令;若你把它綁在 0.0.0.0 或具體的區網 IP 上、又沒有設定 secret,等於在區網或更外層廣播了一個無密碼的系統管理入口。
這與 TUN、DNS 或 DOMAIN-SUFFIX 的話題不衝突,但關注點不同:分流正確與否決定的是流量路徑,外控則是本機上誰有權改路徑。2026 年常見的搜尋意圖是「同網段被掃到 9090」「家裡 NAS、工作室電腦跑 headless 時要不要從內網手機看面板」——本文即對準這些情境,讓你能在不犧牲日常操作便利的前提下,把可攻面削到可說明、可審核的程度。
只綁 127.0.0.1:從聽眾上阻斷多數「路過式」的未授權存取
IPv4 的迴路位址 127.0.0.1 只表示「這台作業系統自己打給自己」。當 external-controller 寫成 127.0.0.1:9090 時,同一台機器上的瀏覽器、Yacd 或本機腳本照常可用,但隔壁手機、公司同事筆電、惡意掃描封包從一般區網路徑不應能直接建連。這是最經濟、也最少副作用的第一道門檻。相對地,0.0.0.0:9090 表示「在每一張網卡上都開門」,在筆記型電腦上往往是 Wi‑Fi 與有線兩面都聽、在伺服器上則是區網與實體內網都聽,範圍大得多。
實作上,請在設定檔的頂層(或你客戶端產生檔相應的區塊)明確寫上:
external-controller: '127.0.0.1:9090' # use a high port you prefer, keep it consistent in GUI and scripts
儲存後重啟或依客戶端要求熱重載,再用同一台機器上的 curl 或瀏覽器以 http://127.0.0.1:9090/... 自測。若你先前依教學把埠改成 0.0.0.0 才能「從手機看電腦上的面板」,那其實應改思考網路層的設計,而不是在 API 上永久開洞。本站另一篇專文已分別從 Windows 上允許區網與防火牆 與 OpenWrt 閘道與桌面客戶端並存 說明「代理被分享」與「本機外控可管理」兩者不要混在一起;代理埠可以面對區網,管理 API 則盡量留在 127.0.0.1。
external-controller 仍是作業系統的 socket 行為。請仍以設定檔與防火牆為準,不要在心智上二選一互抵。
設定 API Secret:就算本機,也要讓亂掃的腳本拿不到「空白通行證」
在官方文件與多數 mihomo/Clash Meta 變體中,secret 用來要求呼叫者在 HTTP 標頭帶上與你設定值相符的授權資訊(常見是 Authorization: Bearer <secret>,實際以核心版本與客戶端實作為準)。若欄位留空,代表「只要連得上埠、不必證明身分」。這在純 127.0.0.1 情境下或許讓人覺得夠了,但任何能在本機執行程式碼的惡意軟體、過度寬鬆的瀏覽器外掛、或一時方便開了「本機靜態伺服器+CORS 全開」的實驗專案,都可能在不經你操作 UI 的情況下,替你呼叫幾行 HTTP 變更執行中設定。
實務建議如下:使用夠長、夠亂的隨機字串作為 secret,長度寧可長一點;寫在設定檔內的檔案權限在 Linux 上可限制為只給實際執行帳戶讀取(延伸做法見 Linux headless 與 systemd 那篇)。圖形客戶端若把 secret 以「一鍵產生」處理,可優先採用。切勿把日常密碼、機場帳密或訂閱 token 重複當成 API secret 使用,以免外洩面疊加。
secret: "change-me-to-a-long-random-string"
設好之後,請在 Yacd 或內建面板的「API 位址/密碼」欄填同一值,自測切換一個不重要的策略組、再還原,確認 401 與成功回應都符合預期。若你在公司網管環境、必須與團隊共用同一臺參考機,秘密輪替與檔案如何交接也應併入流程,而不要把「內網=信任」寫在營運假設裡。
Yacd、內建面板與行動裝置:常見迷思與實務填法
Yacd 本質是靜態前端,實際管理的仍是瀏覽器對你填寫的 API 基底位址發出的 XHR 請求。多數人只要在「家裡電腦本機用」的場景,把基底設成 127.0.0.1:9090 並帶上 secret,就能避免把「整份 API」暴露到別台裝置。怕麻煩而長期把位址寫成內網 192.168.x.x:9090 並在書籤之間轉傳,等於在社群或截圖裡不小心外洩「哪裡有台可連的管理口」的線索。若你確實要用手機在沙發上管電腦,較穩的作法是透過受控通道(例如同帳戶的遠端桌面、或你自己維運的跳版)而不是在路由器上多開一個裸奔埠。
部分核心也支援 external-ui 在本地提供靜態目錄;沒有需求就關閉,能少一層可列舉的 URL。圖形客戶端內建「一鍵開面板」的按鈕,通常也會在幕後帶上正確的本機迴路位址。若你從未在設定檔中改過卻在區網被掃到 9090,建議盤點客戶端是否曾一鍵還原成廣告教學裡的「可遠端」範本,那往往是風險的來源。
若真的暴露出去,可能發生什麼?心裡要有一條風險邊界
在沒有密碼的狀況下,能連上 外控 埠的實體,可能執行與圖形介面幾乎等價的動作量級:讀出目前 策略組、變更出口節點、重新載入設定、若介面有暴露甚至影響訂閱 URL。對一般使用者,「被切成奇怪的節點」可能只是體感變差;但對內有敏感主機、或家裡小孩裝了來路不明 App 的裝置,未授權讀寫的後果要往資訊外洩與橫向移動的想像,而不是只當惡作劇。公網若透過不安全的埠轉發露出去,掃描流量更是數量級的上升。
本文刻意不把情境寫成「紅藍演練報告」:在防護上,綁 127.0.0.1 與帶上 API Secret 已能擋下大量漫無目的的機械化嘗試;剩下的是帳戶、檔案權限與網路邊界的老問題。你若有訂閱裡的敏感參數,也請記得訂閱與 外控 是兩層風險,前者偏外洩,後者偏本機遙控,不要混淆「我只怕節點被看到」的單一敘事。
防火牆、Docker 與埠映射:迴路綁定以外的第二道審核
在 Windows 與多數 Linux 桌面,系統防火牆規則可能在你第一次啟動 Clash 時就跳出「要允許嗎」。允許 127.0.0.1 上的本機迴路連線與開一個讓眾人連進來的埠不是同一件事。若你曾手動加過「讓 9090 從公網進來」的規則,請在更新設定檔後一併檢查是否需要回收。
在 Docker 內執行 mihomo 的使用者,常見的坑是 ports: 9090:9090 讓宿主與內部網橋的綁定範圍與你心裡想的不同;即使設定檔內寫 127.0.0.1,映射方式仍可能讓實際聽的介面變寬。建議在容器內、宿主上各跑一輪實測,並閱讀 Docker 與宿主 Clash 搭配 裡的網路模型說明。若實在要在內部網路開放 Web UI,至少把 secret 與僅內部路由當成硬需求,再談圖表漂亮與否。
一定要遠端存取圖形面板時:SSH 轉接埠比「多開 0.0.0.0」更可控
在無圖形 Linux 上跑 headless、又想從筆電用 Yacd 看狀況,推薦模式是讓 mihomo 穩定聽在 127.0.0.1:9090,再用 SSH 本機轉接把該埠暫時映射到筆電(例如 ssh -L 9090:127.0.0.1:9090 使用者@伺服器 的形式,參數以你的環境為準),瀏覽器打開的仍是本機 9090。這條路徑多了 SSH 的驗證、金鑰與帳戶層的防線,比單純在路由器上轉 9090 到公網更不容易演變成「全世界都能試著改你的 Clash 規則」。
若你團隊內有私有 PKI 或 mTLS 反向代理,可在此模式上再疊一層,但屬於維運專案範圍,本文不展開。核心訊息是:不要為了圖兩下方便,在設定檔裡寫一個你十年後也忘記的 0.0.0.0 範本。
可帶走的安全自檢清單(2026 實務向)
- 在設定檔中確認
external-controller是否已從0.0.0.0收斂到127.0.0.1或你明確知情的單一內部位址,並讓客戶端與 Yacd 同步。 - 填寫夠長的
secret,並在圖形端以實際切換一個測試策略驗證 401 與成功兩路徑都合理。 - 盤點
external-ui、內建儀表板、以及是否曾一鍵把埠暴露到示範用範本;不需要就關。 - 在 Docker 或 WSL2 之類的虛層內,把埠映射的實際行為在宿主與容器各測一輪,不要只看 YAML 字面上的 127.0.0.1。
- 釐清「分享代理給手機」與「讓外控可被手機打」的差異,必要時參考前述兩篇專文拆開觀念。
當你完成以上步驟,多數在論壇上被問的「我明明只在家用、為什麼同網段能開我面板」的案例,都會在設定檔與第一次允許防火牆的那個勾勾裡找到答案。剩下若仍要追 root cause,就回到連線層的日誌與實際命中規則,與我們在分流專欄寫的思維一致,只是戰場改成本機面的管理埠。
常見問題(外控、127.0.0.1 與 Yacd 一次釐清)
把 external-controller 設成 0.0.0.0:9090 有什麼風險?
代表在所有介面上都開放同一埠;同網段掃到、路由器轉發、或內部惡意裝置都有機會直接呼叫 API。沒有 API Secret 時,等於無驗證的系統遙控。
只綁 127.0.0.1 就夠了嗎?還要設 secret 嗎?
迴路位址讓遠方機器預設打不進來,但本機惡意程式仍可能碰得到。兩層都開是實務上較穩的組合。若用 SSH 轉接埠,本機 127.0.0.1 仍然是合理的預設。
Yacd 的 API 欄位要怎麼填?
在只給本機用時,基底應是 http://127.0.0.1:你的埠,密碼欄帶上與 secret 相同值。避免長期在書籤裡寫內網 192.168 位址當成唯一入口,除非你清楚暴露範圍與人員權限。
Linux 上沒圖形、只想從筆電管,有沒有推薦做法?
讓 mihomo 在伺服器上只聽 127.0.0.1,再用 SSH 本機轉接把埠帶回筆電,搭配瀏覽器開 Yacd。比直接把 0.0.0.0 丟在設定檔裡「給內網用」可稽核性更好。
系統防火牆已點了允許 Clash,還要看設定檔嗎?
要。防火牆擋外網是另一件事;external-controller 綁在誰、Docker 又怎麼映埠,決定的是誰能碰到 API。兩層要一起看,不互相取代。
寫在最後:分流通順與帳戶訂閱之餘,別忘了管理介面也該有邊界
我們在專欄裡寫了許多以 DOMAIN-SUFFIX、策略組 與 DNS 為中心的場景,因為多數人最初踩坑的是流量有沒有走對;而當你開始依賴圖形面板、自動化腳本與免費訂閱連結匯入的長期管線,external-controller 變成日常操作的一部分。把這一塊用 127.0.0.1 與 API Secret 收斂好,並分清楚跟區網分享代理的差別,是進階使用者與小型工作室很划算的安全投資。相較介面堆疊但底層黑箱的產品,看得懂的 YAML 與能說明清楚的聽眾邊界,長期維護更安心。
若你希望圖形客戶端能整合訂閱匯入、可視化切換 策略組 與日誌,同時內建較新 mihomo 行為、減少手動在設定檔裡試錯,歡迎從下載中心挑選合適的作業系統版本。需要更多專欄內容,可持續瀏覽技術專欄;分流的語法全觀可延伸閱讀《Clash YAML 規則分流完全指南》。
想搭配路由器或無圖形伺服器佈建時,可交叉閱讀OpenWrt 與桌機並存、Linux headless 與 systemd 兩文,讓網路層的閘道與本機迴路的外控各安其位。