Clash 系統代理已開啟卻無法代理:瀏覽器與終端機分開排查
瀏覽器擴充功能攔截、系統代理設定未寫入,以及終端機未讀取系統代理,是最常見的三大原因。本文分別整理瀏覽器與命令列的檢查順序和環境變數設定。
先分辨:請求未進入核心,還是規則選擇了直連
先開啟用戶端的連線頁面,再造訪一次目標網站。系統代理是作業系統提供的代理設定,只有會讀取這項設定的應用程式才會使用。用戶端按鈕顯示「已開啟」,不代表瀏覽器、終端機和背景服務都已接上代理。
先了解兩者的分工。圖形介面用戶端負責切換系統設定並顯示連線狀態;Clash 或 mihomo 核心則負責監聽連接埠、比對規則及轉送請求。mihomo 是 Clash Meta 更名後的核心。核心正常運作、系統代理設定正確寫入,而且應用程式願意讀取設定,三者都符合時,請求才會依這條路徑進入核心。
| 觀察結果 | 優先檢查項目 | 接下來怎麼做 |
|---|---|---|
| 瀏覽器造訪後沒有新增連線 | 系統代理、擴充功能、瀏覽器獨立設定 | 確認代理位址與連接埠,再暫時停用代理擴充功能 |
| 瀏覽器正常,終端機沒有新增連線 | 命令列工具未讀取系統代理 | 使用 curl 明確指定代理進行測試 |
| 有連線,但出口顯示 DIRECT | 規則選擇直連 | 查看比對到的規則與完整策略鏈 |
| 有連線,但代理鏈逾時 | 節點連線狀況或遠端 DNS 解析 | 查看記錄,不要反覆切換系統代理 |
關閉目標頁面後重新開啟,或送出一筆新的命令列請求。瀏覽器快取、背景長連線及連線頁面的篩選條件都可能影響觀察結果。沒有新增記錄只能當作線索,不能單憑此點下結論。如果正在使用 TUN 模式,請先記下目前狀態;TUN 透過虛擬網卡接管流量,因此測試結果不再只反映系統代理是否生效。
確認本機連接埠:7890 僅為範例
先確認用戶端顯示的 HTTP 連接埠或混合連接埠,再檢查系統設定。混合連接埠可在同一個連接埠接受 HTTP 和 SOCKS 代理連線。本文以 127.0.0.1:7890 為例;如果實際使用的連接埠是 7897,後續命令也要一併替換。
# mihomo 設定片段,並非完整訂閱設定
mixed-port: 7890
allow-lan: false
mode: rule
不要把管理介面的連接埠當成代理連接埠。external-controller 提供的是控制介面,即使有回應,也不能取代 HTTP 代理監聽。也不必為了讓本機瀏覽器連線而啟用「允許區域網路」;同一台系統通常使用迴送位址即可。
確認連接埠是否確實在監聽
在 Windows PowerShell 中執行以下命令。看到監聽記錄,只能確認該連接埠有人使用;還需要確認該程序是否屬於目前用戶端的核心。
Get-NetTCPConnection -LocalPort 7890 -State Listen |
Select-Object LocalAddress, LocalPort, OwningProcess
# 將上一個指令輸出中的程序識別碼輸入提示
Get-Process -Id (Read-Host "輸入 OwningProcess 程序識別碼")
在 macOS 上使用 lsof,在 Linux 上使用 ss。若沒有輸出,請先檢查核心啟動記錄、實際連接埠,以及是否啟動失敗;不要先改瀏覽器設定。
# macOS
lsof -nP -iTCP:7890 -sTCP:LISTEN
# Linux
ss -lntp 'sport = :7890'
瀏覽器疑難排解:先檢查系統設定,再排除擴充功能接管
步驟一:確認系統代理設定是否寫入
在 Windows 11 中,開啟「設定」→「網路和網際網路」→「Proxy」→「手動設定 Proxy」→「編輯」。使用手動代理模式時,位址應指向本機迴送位址,連接埠則須與用戶端一致。如果用戶端使用 PAC,也就是 Proxy 自動設定指令碼,請檢查「使用設定指令碼」及其指令碼位址,不必要求手動代理開關也同時開啟。
在 macOS 13 或更新版本中,開啟「系統設定」→「網路」→目前的網路服務→「詳細資訊」→「代理伺服器」。檢查網頁代理伺服器(HTTP)和安全網頁代理伺服器(HTTPS)。不要以為「安全網頁代理伺服器」代表本機連接埠一定要使用 TLS;它通常仍會連到本機 HTTP 代理連接埠,再由代理建立 HTTPS 通道。
- 退出其他會自動修改系統代理的用戶端,避免設定剛寫入就被覆蓋。
- 檢查代理例外清單。若目標網域列在略過清單中,瀏覽器可能會直接連線。
- 切換 Wi-Fi、有線網路或 VPN 後,再檢查一次設定;尤其要留意 macOS 目前使用的網路服務是否已變更。
- 如果裝置由組織管理,請先檢查政策限制。不要反覆修改會被管理政策強制覆蓋的欄位。
步驟二:檢查瀏覽器本身的代理來源
在 Chrome 或 Edge 的擴充功能管理頁面中,暫時停用具有代理控制權限的擴充功能,再開啟一般視窗測試。瀏覽器代理擴充功能可能會覆蓋系統設定。無痕視窗不是可靠的唯一對照,因為擴充功能可能獲准在無痕模式中執行,瀏覽器政策也仍然有效。
在 Firefox 中,開啟「設定」→「一般」→頁面底部的「網路設定」→「設定」。若要跟隨用戶端切換,請選擇「使用系統代理設定」;若要獨立測試,可暫時選擇手動代理並填入實際位址。測試結束後請還原原設定,避免日後切換用戶端時留下舊連接埠。
如果只有某個瀏覽器無法使用,請用另一款瀏覽器造訪相同網址作為對照。若另一款瀏覽器能在連線頁面產生記錄,請優先檢查原瀏覽器的擴充功能、設定檔和企業政策,不必先重新安裝核心。
終端機疑難排解:用明確指定代理的命令建立對照
先不要依賴環境變數,直接為 curl 指定代理。許多命令列工具不會自動讀取桌面系統代理;瀏覽器能正常使用,不代表終端機也會自動使用代理。以下命令適用於 macOS、Linux 常見的 shell,測試網址為 https://example.com/。
curl -q -v --connect-timeout 10 --max-time 30 \
--noproxy "" \
--proxy http://127.0.0.1:7890 \
https://example.com/ -o /dev/null
在 Windows PowerShell 中明確呼叫 curl.exe,避免 Windows PowerShell 5.1 中的 curl 別名指向其他命令。使用 NUL 捨棄回應本文:
curl.exe -q -v --connect-timeout 10 --max-time 30 --noproxy "" --proxy http://127.0.0.1:7890 https://example.com/ -o NUL
- 將
-q放在第一個參數位置,避免使用者層級的 curl 設定檔干擾這次測試。 --noproxy ""會清空這次請求的略過代理清單,避免目標位址被代理例外排除。--connect-timeout 10限制連線階段的等待時間,--max-time 30限制整次傳輸的時間,單位都是秒。- 查看詳細輸出時,先確認連線到
127.0.0.1的實際連接埠,再檢查 HTTPS 的 CONNECT 通道及後續回應。
若看到 Connection refused,先重新確認本機監聽位址與連接埠;若看到 407 Proxy Authentication Required,請檢查本機代理是否啟用了驗證;如果建立通道後才逾時,則繼續檢查策略群組和節點。網站回傳 403 也不代表沒有走代理,可能是目標網站的存取限制。
不要只憑網頁能否開啟下結論。明確指定代理的命令成功,而且用戶端連線頁面出現相對應的目標,才能確認應用程式到核心的連線已打通。接著再判斷規則是否選到預期的出口。
設定終端機環境變數:區分 HTTP 代理與 SOCKS 代理
macOS 與 Linux:先只在目前的 shell 中生效
先在目前的終端機執行以下設定,再執行不帶 --proxy 的命令驗證。https_proxy 表示存取 HTTPS 目標時使用的代理;變數值仍可為 http://,因為這裡描述的是本機代理服務使用的通訊協定。
export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"
export no_proxy="localhost,127.0.0.1,::1"
curl -q -v --connect-timeout 10 --max-time 30 \
https://example.com/ -o /dev/null
確認設定有效後,再考慮寫入 ~/.zshrc 或 ~/.bashrc 等目前 shell 實際讀取的檔案。不要一開始就寫入全域設定,否則用戶端退出後,終端機仍會嘗試連線到已關閉的連接埠。環境變數通常只會影響目前程序及其後續啟動的子程序,不會自動修改已在執行的程式。
如果工具明確支援 SOCKS,可使用以下單次呼叫方式。socks5h 中的 h 表示由代理解析目標網域;使用 socks5 時,通常會先由本機解析目標網域。只有實際啟用了 SOCKS 或混合監聽的連接埠才能這樣使用。
curl -q --proxy socks5h://127.0.0.1:7890 \
--noproxy "" --connect-timeout 10 --max-time 30 \
https://example.com/ -o /dev/null
Windows PowerShell:修改目前程序的環境變數
在 PowerShell 中使用 $env:,不要照搬 shell 的 export。以下設定會對目前的 PowerShell 及之後由它啟動的子程序生效,不會立即修改其他已開啟的終端機視窗。
$env:http_proxy = "http://127.0.0.1:7890"
$env:https_proxy = "http://127.0.0.1:7890"
$env:no_proxy = "localhost,127.0.0.1,::1"
curl.exe -q -v --connect-timeout 10 --max-time 30 https://example.com/ -o NUL
不要用 setx 做第一輪驗證。它會寫入永久環境變數,通常還得重新開啟程序才能看到變更,容易和目前視窗中的舊值混淆。各工具支援的變數名稱和優先順序不盡相同;curl 的 HTTP 代理變數應使用小寫 http_proxy,不能假設所有工具都會讀取大寫 HTTP_PROXY。
檢查舊環境變數和工具本身的代理設定
明確指定代理的命令成功、一般命令卻失敗時,請檢查 ALL_PROXY、all_proxy、NO_PROXY 和 no_proxy 是否仍指向舊連接埠,或包含目標網域。Git 等工具也有獨立設定;以下命令只會讀取設定來源,不會修改檔案:
git config --show-origin --get-regexp '.*proxy.*'
沒有輸出不一定代表錯誤,只表示找不到符合的項目。如果找到舊設定,請先確認它位於哪個檔案、其他工作環境是否仍在使用,再決定是否修改。分享終端機輸出前,請遮蔽代理帳號、密碼、訂閱連結,以及含有存取權杖的網址。
請求已進入核心但仍未走代理:檢查規則與策略群組
先查看連線詳細資訊中的比對規則與最終出口。規則模式會依設定順序比對;命中 DIRECT 代表核心選擇直連,並非系統代理失效。策略群組也可能包含 DIRECT,因此只看到策略群組名稱還不夠,還要查看完整連線路徑。
- 使用相同的目標位址進行測試,並記下目前模式、比對到的規則和策略鏈。
- 檢查所選代理群組是否實際選中了可用節點,而非直連選項。
- 必要時短暫切換至全域模式,確認全域策略群組選中了代理節點後,再送出相同請求。
- 若全域模式可用、規則模式卻直連,請重新檢查規則順序;若兩種模式都逾時,則檢查節點和記錄。
- 測試結束後請切回規則模式,避免長期改變其他應用程式的分流方式。
請留意,「使用代理」和「目標網站可連線」是兩回事。節點無法使用、遠端限制及 DNS 解析失敗,都可能發生在請求進入核心之後。不要一直新增網域規則來修復本機連接埠拒絕連線的問題,也不要以重新安裝用戶端取代確認比對規則。
WSL、容器與 TUN:最後再處理特殊執行環境
先確認命令實際在哪個系統中執行。WSL、Docker 容器和虛擬機器中的 127.0.0.1 不一定指向主機。WSL 2 在 NAT 網路和鏡像網路下的行為不同;Docker 的主機位址也取決於執行環境。若主機上的瀏覽器可用,但容器內連線遭拒,請優先檢查網路邊界,不要直接照抄迴送位址。
只有確實需要跨越網路邊界連線時,才評估監聽位址、「允許區域網路」和防火牆規則。將代理監聽擴大到其他網路介面會增加可連線範圍,應限制可信任的來源並視需要設定驗證。不要為了排查終端機問題,就把連接埠暴露在公開網路上。
對於不支援代理設定、也不讀取代理環境變數的應用程式,再考慮使用 TUN 模式。TUN 通常需要系統權限,並會接管路由和 DNS;它不是修正錯誤連接埠的捷徑。啟用前先記下原本狀態,避免和另一套 VPN 或虛擬網卡同時接管流量,導致問題難以定位。
完成後還原設定,並留下精簡的排查記錄
先還原臨時變更,再確認日常工作流程正常。如果之前沒有設定代理變數,可用以下命令清除這次新增的變數;如果原本已有值,請還原原值,不要直接刪除。
# macOS / Linux:僅清除本文暫時設定的小寫變數
unset http_proxy https_proxy no_proxy
# PowerShell:僅清除本文暫時設定的程序變數
Remove-Item Env:http_proxy, Env:https_proxy, Env:no_proxy -ErrorAction SilentlyContinue
最後記下四項資訊:實際監聽連接埠、明確指定代理的 curl 測試結果、瀏覽器使用的代理來源,以及連線詳細資訊中的規則和出口。這些資訊能協助判斷問題出在應用程式設定、本機監聽或核心轉送,而不只是留下「開了代理還是不能用」的描述。