系統代理無效排查
瀏覽器擴充功能攔截代理、終端機未讀取系統代理或環境變數缺漏?逐項找出原因,並提供可驗證的修復方法。
先釐清:代理開關、應用程式入口與規則出口
Clash 用戶端顯示「系統代理已啟用」,通常只代表用戶端嘗試將本機代理位址寫入作業系統設定。這不表示所有程式都已交由核心處理,更不代表每個要求都會使用遠端節點。瀏覽器可能讀取系統設定,也可能由擴充功能接管;終端機中的 curl、Git 和套件管理工具則可能使用各自的環境變數或設定檔。
每個要求都依序經過三個環節:應用程式連上本機監聽連接埠、核心依規則選擇策略,以及選定的出口建立連線。排查時,先固定測試網址和連接埠,再查看用戶端的「連線」頁面或記錄。不要同時更換節點、修改 DNS、啟用 TUN,否則無法判斷是哪項變更發揮作用。
| 現象 | 優先檢查項目 | 判斷依據 |
|---|---|---|
| 瀏覽器正常,終端機失敗 | 終端機代理變數與工具設定 | 明確指定代理的 curl 是否成功 |
| 終端機正常,瀏覽器失敗 | 擴充功能、瀏覽器代理設定、啟動參數 | 停用代理擴充功能後重新送出要求 |
| 瀏覽器與終端機都失敗 | 本機監聽、核心狀態、出口連線 | 連接埠檢查與核心記錄 |
| 出現連線記錄,但顯示 DIRECT | 規則模式、命中規則、策略群組 | 連線詳細資料中的規則與完整策略鏈 |
步驟一:確認核心確實在本機連接埠監聽
分清 mixed-port、port 與 socks-port
mihomo 設定中的 mixed-port 可在同一個連接埠接收 HTTP 和 SOCKS 代理要求;port 是 HTTP 代理入口;socks-port 則是 SOCKS 入口。若將 HTTP 要求送到僅支援 SOCKS 的連接埠,可能會出現通訊協定錯誤或連線中斷。圖形化用戶端也可能覆寫訂閱中的連接埠,因此執行中的設定比訂閱原始內容更值得參考。
# mihomo 本機入口範例;請勿直接覆寫整份訂閱設定
mixed-port: 7890
allow-lan: false
mode: rule
同一台電腦上的瀏覽器和終端機不需要啟用 allow-lan。這項設定用來控制區域網路存取,不會讓本機應用程式讀取系統代理。排查本機連線時,請使用明確的 IPv4 迴圈位址 127.0.0.1,避免 localhost 被解析為 ::1,但核心只監聽 IPv4 所造成的混淆。
先檢查監聽狀態,再送出明確指定代理的要求
# Windows PowerShell:查看 7890 的監聽狀態
Get-NetTCPConnection -LocalPort 7890 -State Listen
# Linux:查看 TCP 監聽狀態
ss -lntp 'sport = :7890'
# macOS:查看 TCP 監聽狀態與處理程序
lsof -nP -iTCP:7890 -sTCP:LISTEN
依照你的作業系統執行其中一項指令即可。若沒有監聽結果,請先處理用戶端核心未啟動、設定解析失敗或連接埠遭占用等問題。若顯示正在監聽,也要確認所屬處理程序;其他軟體可能也占用了 7890。
# macOS / Linux
curl -q -v --noproxy "" --proxy http://127.0.0.1:7890 \
--connect-timeout 7 --max-time 20 -I https://example.com/
# Windows PowerShell:明確執行 curl.exe
curl.exe -q -v --noproxy "" --proxy http://127.0.0.1:7890 --connect-timeout 7 --max-time 20 -I https://example.com/
-q 放在第一個參數的位置,用來略過預設 curl 設定檔;在支援傳遞空參數的 shell 中,--noproxy "" 可清空略過代理清單;--proxy 則用來明確指定入口。舊版 Windows PowerShell 傳遞空字串參數的方式可能不同;若結果仍顯示略過代理,可先暫時移除目前工作階段的 NO_PROXY,再重新測試。
看到 Connected to 127.0.0.1,只能證明本機代理入口可連線;HTTPS 要求接著出現 200 Connection established,則表示 HTTP CONNECT 通道已建立。還要查看後續目標網站的回應和核心連線記錄。此處測試的是 example.com,測試成功不代表所有目標網站都能連線。
步驟二:單獨排查瀏覽器的系統設定與擴充功能
Chrome、Edge:先排除擴充功能接管
- 開啟 Chrome 的
chrome://extensions/或 Edge 的edge://extensions/,暫時停用所有用來管理代理、PAC 或切換網路的擴充功能。 - 在 Chrome 中前往「設定」→「系統」→「開啟電腦的代理設定」;在 Edge 中前往「設定」→「系統與效能」→「系統」,尋找代理設定入口。不同版本的項目名稱和分類可能略有不同。
- 在系統代理頁面確認位址、連接埠和略過清單。若系統使用 PAC,請確認目前生效的是 PAC 還是手動代理;不要只憑某個開關判斷實際連線路徑。
- 完全結束瀏覽器後重新啟動,再造訪測試網址,同時查看用戶端的連線記錄。
Windows 11 的設定路徑是「設定」→「網路和網際網路」→「代理伺服器」。macOS 的路徑是「系統設定」→「網路」→目前的網路服務→「詳細資訊」→「代理伺服器」。手動 HTTP 代理與安全 Web 代理可能是兩個不同項目;測試 HTTPS 網站時,也要確認對應設定。
如果設定頁面顯示代理由擴充功能或組織管理,請先查明管理來源。企業原則和瀏覽器啟動參數可能會覆寫一般設定;反覆切換 Clash 的系統代理開關,通常無法解除這類覆寫。無痕視窗也不是可靠的隔離測試,因為某些擴充功能獲准在無痕視窗中執行。
Firefox:確認是否使用獨立代理設定
桌面版 Firefox 請前往「設定」→「一般」→頁面底部的「網路設定」→「設定」。選擇「使用系統代理設定」才會沿用作業系統代理;若選擇「手動代理設定」或「自動代理設定 URL」,使用的則是瀏覽器自己的設定。
- 手動 HTTP 代理:位址填入
127.0.0.1,連接埠填入實際的 HTTP 或混合連接埠;也請確認 HTTPS 代理項目。 - 手動 SOCKS:選擇 SOCKS v5,並使用 SOCKS 或混合連接埠;若要由代理解析目標網域,請確認 SOCKS v5 的代理 DNS 選項。
- 「不使用代理」清單:確認測試網域及其網域後綴是否列在其中,避免把略過代理規則誤認為用戶端故障。
步驟三:為終端機設定目前工作階段的代理變數
終端機視窗本身不會替網路要求設定代理,真正發起連線的是視窗內執行的程式。許多命令列工具不會自動讀取桌面系統代理。若明確指定代理的測試成功、一般指令卻失敗,請優先補上該工具支援的環境變數,而不是直接更換節點。
macOS 與 Linux:先暫時設定 export
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 -v --connect-timeout 7 --max-time 20 -I https://example.com/
https_proxy 這個變數名稱代表它用於 HTTPS 目標,不表示變數值必須使用 https://。常見的 Clash 本機 HTTP 代理會透過 HTTP CONNECT 傳輸 HTTPS,因此此處仍應填寫 http://127.0.0.1:7890。任意改成 https:// 會讓工具嘗試與本機代理建立 TLS 連線;若監聽端不支援,就可能連線失敗。
這些變數只會影響目前的 shell,以及之後啟動的子處理程序。確認設定有效後,再依照實際使用的 shell 寫入 ~/.zshrc 或 ~/.bashrc。不要一次寫入多個啟動檔;從桌面啟動的 IDE 也不一定會讀取這些檔案,請另外確認 IDE 的環境或終端機設定。
Windows 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 -v --connect-timeout 7 --max-time 20 -I https://example.com/
在 Windows PowerShell 5.1 中,curl 可能是 Invoke-WebRequest 的別名。使用 curl.exe 可明確執行 curl,避免混淆兩種工具的參數和代理行為。工作階段變數不會回溯修改已執行的程式;只有新啟動的處理程序才會繼承目前環境。
需要使用 SOCKS 時,明確指定 DNS 解析位置
curl -q -v --noproxy "" --proxy socks5h://127.0.0.1:7890 \
--connect-timeout 7 --max-time 20 -I https://example.com/
在 curl 中,socks5:// 通常由本機解析目標網域;socks5h:// 則會將目標網域交由 SOCKS 代理解析。兩者的差異有助於排查 DNS 問題,但其他工具不一定支援相同的 URL 格式。設定 ALL_PROXY 前,請先查閱該工具的文件;不要假設這項設定對所有程式都有效。
步驟四:檢查 NO_PROXY 與工具本身的設定
環境變數設定正確卻仍直接連線,常見原因是略過清單或工具本身的設定。NO_PROXY 和 no_proxy 用來指定不經代理的主機;不同工具對大小寫、網域後綴和 CIDR 的支援並不完全相同。尤其要確認是否包含 *,在許多工具中它代表略過所有目標。
# macOS / Linux:只在本機查看代理變數
env | grep -i proxy
# Windows PowerShell
Get-ChildItem Env: | Where-Object Name -Match 'proxy'
# 查看 Git 設定來源,包含系統、全域與目前儲存庫
git config --show-origin --get-regexp '.*proxy.*'
Git 的 http.proxy、依 URL 比對的代理設定,或套件管理工具自己的代理項目,都可能讓同一個終端機中的不同指令走上不同路徑。如果 Git 指向舊的 127.0.0.1:7891,而目前用戶端只監聽 7890,就會出現 curl 成功、Git 失敗的情況。
- Git:搭配
--show-origin找出實際的設定檔和作用範圍,只修改已確認有誤的項目。儲存庫層級的設定可能會覆寫全域設定。 - npm:使用
npm config get proxy和npm config get https-proxy查看工具本身的代理入口,同時檢查專案中的.npmrc。 - WSL 與容器:其中的
127.0.0.1通常指向各自的網路環境,不應預設它等同於 Windows 或主機。WSL 網路模式和容器網路設定都可能改變可連線路徑。
若虛擬機或容器必須連線至主機代理,請確認主機可連線位址、用戶端監聽範圍及防火牆規則。只對必要的本機網路開放,切勿為了暫時排查而將代理連接埠暴露於公網。
步驟五:入口正常後,再檢查規則、DNS 與 TUN
有連線記錄,卻未使用預期節點
先在用戶端的連線詳細資料中找到測試網域,確認命中的規則和策略鏈。在規則模式下,DIRECT 表示核心依規則選擇直連,不代表應用程式繞過核心。如果策略群組目前選擇直連,或目標命中直連規則,只開啟系統代理不會改變結果。
記下原本設定後,可短暫切換至全域模式,並明確選擇已知可用的代理出口,重新測試同一個網址。若全域模式成功、規則模式失敗,請回頭檢查規則順序、網域比對和策略群組選項,測試完成後再還原原本模式。不要直接將全域模式測試結果當成長期設定建議。
依錯誤發生階段縮小排查範圍
| 觀察結果 | 可能原因與下一步 |
|---|---|
| 連線至 127.0.0.1:7890 遭拒 | 優先檢查本機監聽、處理程序是否結束,以及連接埠是否填寫正確;先別調整遠端節點。 |
| 本機連線已建立,之後逾時 | 查看核心記錄,檢查節點連線、目標 DNS 和出口;單憑逾時無法判定問題所在層級。 |
| 記錄顯示目標網域解析失敗 | 確認核心 DNS 設定、上游解析器是否可連線,以及 SOCKS 的解析位置。 |
| 目標回傳 HTTP 403 或 429 | 要求可能已抵達目標服務,應檢查存取政策或頻率限制;這不等於本機代理未生效。 |
什麼情況才需要 TUN 模式
TUN 透過虛擬網卡和路由接管符合條件的流量,適合無法設定代理、也不會讀取系統代理的程式。它不能取代修正錯誤連接埠或失效節點,也不代表接管後所有連線都會使用遠端節點;最終出口仍由規則決定。
如果只是 curl 缺少環境變數,先修正變數通常更容易驗證。確實需要 TUN 時,再依照用戶端要求安裝服務或授予管理員權限,並確認路由和 DNS,同時留意是否與其他 VPN 衝突。比較系統代理與 TUN 的差異時,一次只變更一種流量接管方式,避免兩條路徑同時生效,導致問題原因難以判斷。
還原設定並完成最終驗收
驗收時應測試瀏覽器、明確指定代理的 curl,以及一般 curl,並針對同一個目標檢查連線記錄。瀏覽器成功但一般 curl 失敗,請繼續檢查終端機設定;明確指定代理的 curl 也失敗,則回頭檢查監聽狀態和核心記錄。不要只憑用戶端開關的顏色或節點延遲數值判定問題已解決。
- 記錄最後使用的連接埠、代理入口類型和生效設定來源,例如「混合連接埠 7890,PowerShell 目前工作階段環境變數」。
- 重新啟用暫時停用的必要擴充功能,每次啟用一項並重新測試;若問題再次出現,就能找出衝突來源。
- 清除排查期間新增的全域模式、過於寬泛的略過項目和重複代理變數,避免下次啟動時出現不同結果。
# macOS / Linux:僅在這些變數是本次暫時設定時清除
unset http_proxy https_proxy all_proxy no_proxy
# Windows PowerShell:清除本次工作階段的暫存項目
Remove-Item Env:http_proxy, Env:https_proxy, Env:all_proxy, Env:no_proxy -ErrorAction SilentlyContinue
清除指令不會還原啟動檔或工具設定中的永久設定。若已寫入設定檔,還需要修改對應檔案。關閉用戶端後,請再次確認系統代理是否已還原,避免系統仍指向已停止監聽的本機連接埠。