為什麼「Windows 開了 Clash」,WSL2 裡仍像沒代理?

許多使用者在 Windows 11(或 Windows 10 搭配 WSL2)上,已用圖形化 Clash 用戶端連上節點、Edge 也能正常開海外網站,但一進 WSL2 裡的 Ubuntu,執行 sudo apt updatecurl https://example.com 卻依然緩慢、逾時,甚至錯誤訊息顯示正在嘗試直連。這通常不是 Clash 沒開,而是子系統內的行程,預設並不會自動沿用你在 Windows「系統代理」或瀏覽器裡看到的那條路徑

WSL2 本質上是一個輕量虛擬化環境:Linux 發行版跑在虛擬網路介面之後,與 Windows 主機之間有明確的邊界。你在 Windows 勾選的「系統代理」、或某些用戶端寫入的 WinHTTP 設定,主要影響的是Windows 使用者空間裡的程式;而 Bash、apt、curl 這類在 Linux 檔案系統與網路堆疊上執行的工具,需要自己知道「要往哪一個位址、哪一個埠」送出 CONNECT 或 SOCKS 協商。因此,把情境講清楚:我們要做的是「讓 WSL2 內的工具,主動連到跑在 Windows 上的 Clash 入站埠」,而混合埠(mixed-port)正是最常見、也最適合同時承接 HTTP_PROXY 與一般 HTTPS 流量的單一入口。

若你同時在 Windows 終端機裡調過 Git/npm 的代理,可先對照本站Windows 端混合埠與環境變數一文,釐清「系統代理」與「環境變數」的差異;本文則把焦點完全放在WSL2 全環境如何把出網接到同一個 Windows Clash 混合埠,關鍵詞包含 WSL2 Clash 代理、Windows 混合埠、以及 Ubuntu 子系統讓 apt 走代理的實務寫法。

步驟一:在 Windows 端確認混合埠真的在聽

在動 WSL2 之前,請先在 Windows 用戶端確認三件事:混合埠數字核心已載入設定、以及是否只綁在 loopback。混合埠的意義,是讓單一 TCP 埠能同時處理常見的 HTTP 代理與 SOCKS 風格連線;對多數情境,你只要記住用戶端介面上顯示的那個數字(例如 7890),並在設定檔中對應到 mixed-port 欄位即可。若你習慣直接閱讀 YAML,亦可對照Clash YAML 設定深度解析裡關於 mixed-portportsocks-port 的區別,避免把 HTTP 埠與 SOCKS 埠抄反。

若 Clash 僅監聽 127.0.0.1,在「從 WSL2 連回 Windows」時仍可能成功(見下一節的 localhost 轉發與鏡像模式),但若你打算改用手動查到的主機區網 IP(例如 192.168.x.x)當代理位址,就必須一併在設定裡允許區網連線(常見選項名稱為 allow-lan 或等效設定),否則會出現 connection refused。這與「手機透過同一台電腦上網」那類情境共享同一套觀念;若你需要更完整的防火牆與綁定位址說明,可延伸閱讀站內 Windows 區網代理主題。

步驟二:WSL2 要連「哪一個主機位址」才碰得到混合埠?

這是全篇最容易卡關、也最值得用可重現指令寫進筆記的地方。歷史上常見做法是讀取 /etc/resolv.conf 裡的 nameserver:在預設 NAT 網路下,該位址往往指向可在子系統內路由到的 Windows 主機,因此有人會用 export http_proxy=http://$(grep nameserver /etc/resolv.conf | awk '{print $2}'):7890 這類一行式設定。請注意:不同 WSL 版本、不同公司網路或自訂虛擬交換器時,nameserver 不一定是「主機 IP」,也可能是內部 DNS;因此不要盲信單一教學片段,務必用 curl -v 實測。

另一條路是從路由表讀預設閘道:ip route show default | awk '{print $3}' 在許多安裝上會得到與上面相近的結果。若兩者不一致,以能實際連通混合埠的那個為準。你也可以在 Windows PowerShell 執行 ipconfig,找出 WSL 對應的「虛擬乙太網路介面卡」或 Hyper-V 相關介面的 IPv4,再回 WSL2 用 nc -vz 該IP 混合埠 做連線測試。

自較新的 WSL 起,Microsoft 提供 localhostForwarding(預設為 true)與鏡像網路(mirrored networking mode)等選項:前者讓子系統內的 127.0.0.1 有機會對應到主機上的本機服務;後者則進一步讓位址空間與本機語意更一致。若你的環境已啟用轉發,直接把代理設成 http://127.0.0.1:混合埠 可能就能通,這也是最乾淨、最不需要記區網 IP 的寫法。若仍失敗,再退回「主機 IP+必要時 allow-lan」那條路即可。

步驟三:用環境變數讓 curl/wget 先走通

在驗證 apt 之前,建議先用 curl 把「代理鏈路」打通。假設你的混合埠是 7890,且 localhost 發生效,可在 ~/.bashrc 或目前工作階段先輸入:

export HTTP_PROXY="http://127.0.0.1:7890"
export HTTPS_PROXY="http://127.0.0.1:7890"
export ALL_PROXY="http://127.0.0.1:7890"

若你改以主機 IP(假設為 172.28.112.1)連線,只要把位址替換即可。接著執行 curl -I https://www.google.com 或你信任的測試站台;若 Clash 連線預覽裡能看到對應連線、且延遲合理,代表子系統 → Windows 混合埠 → 節點這段已成立。若 curl 仍直連,請檢查是否少了 HTTPS_PROXY、或環境變數只寫在小寫 http_proxy 而目標程式只讀大寫。

公司內網與本機服務請習慣補上 NO_PROXY,列出 localhost,127.0.0.1,.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 等你確定要直連的範圍,避免內部 Git、套件庫或區網管理介面被硬送去境外節點。實際欄位與語法仍以你使用的 Shell 與工具為準。

步驟四:讓 apt/apt-get 穩定走代理(含 HTTPS 套件庫)

即使 curl 已經成功,sudo 啟用的 apt 仍可能看不到你使用者在 ~/.bashrc 裡的變數,因為預設會重置環境。apt 家族建議使用專用設定檔,例如建立 /etc/apt/apt.conf.d/95clash-proxy(檔名可自訂),內容範例如下(埠號請替換):

Acquire::http::Proxy "http://127.0.0.1:7890";
Acquire::https::Proxy "http://127.0.0.1:7890";

若你的套件庫同時包含 http 與 https 來源,兩行都寫會比較穩。若你必須改走主機 IP,只要把字串中的主機位址替換即可。部分環境會啟用 apt 的沙箱(Sandbox)相關選項,若遇到與網路權限有關的錯誤訊息,請以發行版文件為準調整;這類問題與「代理位址寫錯」表現不同,需要分開排查。

另一個實務細節是鏡像站與區域 CDN:若你把所有流量都送去代理,有時反而比「官方區域直連」慢;這時可以搭配 Acquire::http::Proxy::archive.ubuntu.com 這類針對特定主機覆寫 DIRECT 的寫法,或乾脆把鄰近區域鏡像網域列進 NO_PROXY(若你改回純環境變數路線)。維護重點是:讓規則可讀、可還原,而不是一次寫死後忘記為何當初要繞路。

步驟五:wsl.conf 與 .wslconfig:localhost 與鏡像模式怎麼選?

若你希望「盡量讓 127.0.0.1 在兩邊語意一致」,請查閱目前 WSL 版本所支援的選項。常見相關檔案包括各發行版內的 /etc/wsl.conf(影響開機行為與部分網路選項)以及 Windows 使用者目錄下的 .wslconfig(影響整個 WSL2 VM 的全域參數)。鏡像網路模式在適合的版本中,能顯著降低「子系統與主機位址不一致」帶來的困惑,但也可能與公司 VPN 或自訂路由產生互動;套用前建議備份原設定,並預留退回路徑。

無論你是否啟用鏡像模式,都建議在文件裡記錄兩組資訊:目前有效的代理 URL,以及你是用 localhost 還是主機 IP 連到混合埠。日後換筆電、升級 WSL 或重灌 Ubuntu 子系統時,可以少踩一半的重複坑。

對照表:症狀與優先檢查項

下表整理讀者最常遇到的現象與建議優先順序,實際錯誤字串可能因版本略有出入。

現象 優先懷疑 建議動作
curl 正常、sudo apt 仍失敗 sudo 未繼承使用者代理變數 改寫 /etc/apt/apt.conf.d/ 專用 Proxy 設定
connection refused 埠錯、核心未聽、或僅綁 loopback 卻用區網 IP 連 對照用戶端連線資訊;必要時開 allow-lan 或改回 127.0.0.1
只有 HTTPS 逾時 漏設 HTTPS_PROXY 或 apt 漏 Acquire::https::Proxy 兩邊都指向同一混合埠 URL
Windows 瀏覽器正常、WSL2 全面失敗 子系統根本無法路由到主機上的該埠 檢查 WSL 版本、localhostForwarding、鏡像模式與防火牆

什麼時候要改考慮 TUN 或更底層的路由?

本文路線的優點是:只動應用程式看得懂的代理設定,不必把整台 Windows 的 IP 轉發與路由表都捲進來。缺點則是:某些不讀代理環境變數、也不讀 apt 設定的程式,仍可能維持直連。若你的目標是「子系統內幾乎所有 TCP/UDP 都強制走同一出口」,就要評估是否在 Windows 端啟用 TUN 模式、或採更進階的路由/透明代理方案;相關風險與排查可從Windows Clash TUN 故障排除取得對照思路。

結語

WSL2 與 Windows 並非同一個網路命名空間,因此「主機上的 Clash 已開」並不會自動讓 Ubuntu 子系統裡的 apt、curl 跟著走代理。把Windows 混合埠當成固定接點,依序確認監聽位址、在子系統內選對127.0.0.1 或主機 IP、補齊 HTTP(S)_PROXY 與 apt 專用設定,就能建立可複製的維運片段。相比其他同類工具,Clash 在入站埠與規則可視化上通常更容易對照除錯;若你希望先取得與本機環境相符的用戶端,再依序完成上述步驟,建議從用戶端下載頁取得最新版本,並搭配站內 YAML 與 Windows 主題文章一起閱讀。→ 立即免費下載 Clash,開啟流暢上網新體驗