為什麼 Windows 能上、WSL2 卻像「斷網」
WSL2 使用輕量虛擬機與虛擬網路介面,讓 Linux 發行版與 Windows 宿主共享同一台機器,但不是共享同一個 loopback 位址語意。你在 PowerShell 裡用 curl.exe 連 127.0.0.1:7890,封包抵達的是 Windows 上監聽該埠的行程;同樣一行放到 WSL 的 Bash,127.0.0.1 卻是子系統裡的 Linux 本機。若 Clash 只綁在 Windows 的 loopback,WSL 內的程式就會得到典型的 Connection refused,或你改設了錯誤位址後長時間卡住。
另一個常見誤解是:「我已開 TUN 模式/系統代理,為什麼 WSL 還是不跟?」實務上,系統代理主要影響遵循 WinINet/系統代理堆疊的應用程式;許多 Linux 工具鏈在 WSL 內預設不讀 Windows 的系統代理。TUN 則依客戶端實作與路由注入範圍而定,未必覆蓋到 WSL 虛擬介面的轉送路徑。對開發者而言,最穩定、最好寫進團隊文件的做法,仍是:在 WSL 內顯式設定代理環境變數,把 HTTP/HTTPS 流量導向「可從 WSL 路由到的宿主 IP」加上 Clash 的代理埠。這與 Docker 容器內不能用盲目 127.0.0.1 的道理同源,本站 Docker 與終端走 Clash 一文可當交叉參考。
當你排除位址錯誤後,若仍見 TLS 或逾時,請不要先換節點;建議用 連線日誌與 TLS 排查 判斷請求有沒有真的進入 Clash,以及失敗發生在代理鏈哪一段。
localhost。
第一步:取得 Windows 宿主機在 WSL2 視角下的 IP
最常見、也最穩定的寫法是讀取 WSL 自動產生的 /etc/resolv.conf 內 nameserver 欄位:在預設網路模型下,它通常指向宿主機在虛擬區網中的位址。你可以用下列指令快速檢視(輸出會隨環境而異,以下僅示意流程):
grep nameserver /etc/resolv.conf | awk '{print $2}'
將得到的 IPv4(例如常見的內網段開頭)記為 WIN_HOST,後文範例會以 http://WIN_HOST:PORT 表示。若你使用自訂 DNS 或企業政策改寫過 WSL 網路,nameserver 可能不再是宿主位址,此時可改查官方文件建議的「WSL 至 Windows 互通位址」,或以 ip route show default 觀察預設閘道是否指向同一類宿主介面。重點是:在 WSL 內用 ping 或 curl -v 對該 IP 做連通性驗證,確認不是紙上談兵。
若你啟用了較新的 mirrored/鏡像網路模式(依 Windows 與 WSL 版本而定),localhost 轉發行為可能與傳統 WSL2 預設不同;遇到與文件不符時,請以實際 resolv.conf 與路由表為準,不要硬背舊口訣。
第二步:讓 Clash 在該 IP 上真的「聽得到」
即使你在 WSL 內填了正確的 WIN_HOST,若 Clash 在 Windows 上只監聽 127.0.0.1,從 WSL 過去的封包仍可能連不上。解法思路有兩條主線:(1)在確認安全邊界後,讓 Clash 監聽 0.0.0.0 或包含虛擬區網介面的位址,並在設定中允許區網/LAN 連入(常見選項名如 allow-lan,實際鍵名依核心與前端而定);(2)維持只聽 loopback,但改用微軟與社群文件建議的互通位址(若你的環境提供)。兩條路徑都必須搭配 Windows Defender 防火牆:對 Clash 可執行檔或對應 TCP 埠建立入站允許規則,否則會出現「WSL 內顯示連到 IP 卻逾時/被拒絕」的現象。防火牆與綁定位址的組合題,亦可對照 區網共享與防火牆 的思路,把「誰能連入代理埠」一次想清楚。
安全提醒:開放監聽面會提高暴露風險,建議僅在受信任的家用或公司內網使用,並避免將代理埠對公網介面無差別放行。完成連線後,若不再需要從 WSL 存取,可關回 allow-lan 或縮小防火牆規則範圍。
代理埠與協定:mixed-port、HTTP、SOCKS 如何對齊
多數圖形客戶端會顯示 mixed-port:單一 TCP 埠同時承載 HTTP 代理 與 SOCKS5 語意(細節依核心版本與前端封裝為準)。實務上你只要記「畫面上那個數字」並在 WSL 內一致使用即可。若你仍使用分離的 port(HTTP)與 socks-port,請勿混抄範例埠號;錯一個數字就會變成「偶爾能連、多數工具失敗」的半套狀態。
協定選擇上:http://WIN_HOST:PORT 適合走標準 HTTP_PROXY/HTTPS_PROXY 的工具;socks5h://WIN_HOST:PORT 則適合希望由代理解析主機名的鏈路(字母 h 常代表遠端 DNS)。若你在 Clash 端啟用 Fake-IP 或較進階的 DNS 模組,工具鏈對「誰做 DNS」會更敏感,可延伸閱讀 Clash Meta DNS 設定,避免把解析問題誤判成節點故障。
第三步:在 WSL2 內設定 HTTP/SOCKS 環境變數
下列範例請把 WIN_HOST 換成上一節取得的宿主 IP,把 7890 換成你的 mixed-port(或實際 HTTP/SOCKS 埠)。可寫入 ~/.bashrc、~/.zshrc 或獨立 ~/proxy-on.sh 再以 source 載入,團隊成員較容易同步。
export HOST_PROXY="192.168.12.34"
export MIXED_PORT="7890"
export HTTP_PROXY="http://${HOST_PROXY}:${MIXED_PORT}"
export HTTPS_PROXY="http://${HOST_PROXY}:${MIXED_PORT}"
export ALL_PROXY="socks5h://${HOST_PROXY}:${MIXED_PORT}"
export NO_PROXY="localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
說明:HTTP_PROXY 與 HTTPS_PROXY 讓多數套件管理器與 apt 這類走 HTTP 代理語意的工具找到出口;ALL_PROXY 作為兜底,讓只認全域 SOCKS 變數的程式也能對齊同一埠。NO_PROXY 用來排除內網 Git、私有 registry、本機 Kubernetes API 等,避免流量被硬拖進 Clash 後反而變慢或失敗。若你發現「關掉代理就正常、開代理全掛」,優先檢查 NO_PROXY 是否過寬或過窄。更多變數語意可回看 mixed-port 與環境變數 的段落化說明。
驗證建議先用顯式參數,再改為環境變數:例如 curl -x http://WIN_HOST:7890 -I https://www.example.com(請替換成你環境允許存取的測試目標)。若此時成功,代表「路由與埠」已通;再把 -x 換成 export,讓 apt、git 等跟著受益。
apt、Git、npm/pnpm 與 curl 的實務差異
APT
Ubuntu 的 apt 會讀 http_proxy/https_proxy(小寫)與大寫並存慣例;企業環境若另有 /etc/apt/apt.conf,請避免與 shell 變數互相打架。建議在設定後執行 sudo -E apt update 讓子程序繼承目前 shell 的環境(是否允許繼承仍取決於 sudoers 政策)。若僅一般使用者 shell 有代理、進 sudo 後遺失,就是典型「有設卻沒生效」案例。
Git
除了環境變數,亦可使用 git config --global http.proxy/https.proxy;缺點是與 shell 設定可能分叉。團隊可約定以環境變數為主,並在 CI 使用同一組變數。若出現憑證或 TLS 錯誤,請先對照 Clash 日誌確認連線有進代理,再考慮節點或 SNI 議題。
Node/npm/pnpm
這類工具常讀標準大寫變數,但部分版本對 NO_PROXY 語法支援不一。遇到怪異行為時,可用最小重現:單一 npm ping 或鎖定 registry 的 curl 測試,縮小是「代理」還是「倉庫鏡像」問題。
DNS 與 /etc/resolv.conf:連得上埠卻仍失敗時
有些使用者成功把 TCP 連到 Clash,但 apt 或 git 仍卡在解析階段。此時要分兩件事:(1) Linux 側實際使用的 DNS 伺服器是否可達;(2) Clash 的 DNS/Fake-IP 模式是否讓應用程式拿到「看似可 ping、實際不能當終點」的位址。若你在核心設定裡啟用 Fake-IP,請確保規則、嗅探與 fake-ip-filter 與你的使用情境對齊,細節可參考 Clash Meta DNS 專文。另請注意 /etc/resolv.conf 在 WSL 中常被標記為自動產生,開機或休眠喚醒後位址可能變動;若你的腳本把宿主 IP 寫死,卻沒在每次啟動 shell 時更新,會出現「昨天可以、今天不行」的漂移現象。可考慮在登入時動態寫入環境變數,或以小函式重新讀取 nameserver。
若你懷疑是純 DNS 問題,可在 WSL 內用 dig/nslookup 對公共 DNS 與預設解析器交叉比對;並在 Clash 日誌觀察是否有對應的 DNS 查詢與規則命中。
IPv6、雙棧與新版 WSL「鏡像網路」模式
部分網路環境預設走 IPv6,若你的代理埠只在 IPv4 監聽,或環境變數只寫了 IPv4 位址,可能出現「瀏覽器可走、命令列隨機走 v6 失敗」的雙棧現象。可用 curl -4 與 curl -6 對照。若組織政策允許,亦可評估在變數中明確使用 v4 位址並關閉不必要的 v6 路徑,但請理解這屬於環境取捨而非通解。
微軟持續調整 WSL 網路模型;當官方文件與社群腳本衝突時,以你機器上實際 ip addr、resolv.conf、wsl.conf 為準。若遷移模式,記得重跑本文的「取宿主 IP → 測埠 → 設變數」三步驟,不要沿用舊機器的硬編碼。
僅 WSL 側失效:快速排查清單
- 是否誤用
127.0.0.1或localhost指向 Linux 自己而非 Windows Clash。 mixed-port是否抄錯,或 HTTP/SOCKS 埠與變數前綴不一致。- Clash 是否只聽 loopback;是否需要
allow-lan或調整綁定位址。 - Windows 防火牆是否擋下從 WSL 虛擬介面到代理埠的入站流量。
NO_PROXY是否把必要網域誤判成直連,或缺少內網排除導致循環/黑洞。/etc/resolv.conf是否變更導致WIN_HOST漂移;腳本是否需改為動態取得。- Fake-IP 與 DNS 模組是否讓解析結果與應用預期不一致(參考 Meta DNS 專文)。
- 代理變數是否在
sudo、systemd user service、非互動 shell 中遺失。
結語
WSL2 與 Windows 的 雙棧網路,本質上是在同一台硬體上跑兩套 IP 堆疊:記住「127.0.0.1 不是通解」,改以可路由到的宿主 IP 對齊 Clash 代理埠,再用標準 HTTP/SOCKS 環境變數 讓 apt、git、curl 等工具鏈顯式走代理,大多能一次排除「只有子系統壞」的困擾。其餘則是防火牆、allow-lan、DNS 與 Fake-IP 的疊加題,依序縮小範圍即可。
相較依賴隱式行為,把設定寫清楚、可重現、可版本控制,長期維護成本更低;這與願意閱讀連線日誌、維護規則的習慣是同一套方法論。若你希望客戶端在 Windows 上狀態清楚、切換 TUN/系統代理/純埠轉發時不易迷路,選型可參考 如何選擇適合自己的 Clash 客戶端;一般性問題亦可先查 常見問題。
→ 立即免費下載 Clash,開啟流暢上網新體驗,把 Windows 桌面與 WSL2 終端的代理契約對齊在同一套規則與日誌視角下,開發與上網都更穩定。