5 min read

WSL port-forwarding

為什麼 WSL 2 需要 Port Forwarding?

預設情況下,WSL 2 使用 NAT (網路位址轉換) 架構的虛擬網路,這表示它擁有獨立於 Windows 主機的虛擬 IP。因此,區域網路中的其他設備無法直接透過 Windows 主機的實體 IP 存取 WSL 2 內部的服務。

要將流量引導至實體 IP,目前有兩種主流方法:

1. 使用 Mirrored Mode (推薦,適用於 Windows 11 22H2 以上版本)

如果你使用的是較新的 Windows 11 版本,微軟官方已加入「Mirrored Mode (鏡像網路模式)」。啟用後,WSL 2 會直接共用 Windows 主機的網路介面與實體 IP,完全不需要手動設定指令或腳本進行通訊埠轉發

設定步驟

A. IP 綁定

  1. 按下 Win + R 開啟執行視窗,輸入 %USERPROFILE% 並按下 Enter,進入你的使用者資料夾。
  2. 在該目錄下建立或編輯名為 .wslconfig 的純文字檔案。
  3. 將以下內容貼入檔案並儲存:
[wsl2]
networkingMode=mirrored
  1. 開啟 PowerShell,輸入 wsl --shutdown 完全關閉 WSL。
  2. 重新開啟 WSL(可以透過直接在PowerShell輸入 wsl 開啟),之後在 WSL 內部啟動的服務即可直接綁定並使用主機的實體 IP。

B. 開啟防火牆

開啟 Mirrored Mode(鏡像模式)後,雖然解決了「網路路由與轉發」的問題,外部網路確實可以直接透過 Windows 實體 IP 找到 WSL。但是,基於安全性,微軟預設會阻擋所有從外部連入 WSL 的流量

最新版的 WSL 支援讓 WSL 直接套用 Windows 系統的防火牆規則,這樣管理起來最直覺。

1. 修改 .wslconfig:在 %USERPROFILE%\.wslconfig 檔案中,除了原本的鏡像模式,再加上一行 firewall=true

[wsl2]
networkingMode=mirrored
firewall=true
  • 修改後記得在 PowerShell 執行 wsl --shutdown 重啟 WSL

2. 在 Windows 防火牆放行 Port:因為已經整合了 Windows 防火牆,只需要像平常開放 Windows 軟體一樣開放對應的 Port 即可。

這部分內容直接跳到3.

2. 使用 Netsh 指令手動轉發 (適用於 Windows 10 或預設 NAT 模式)

如果你無法使用 Mirrored Mode,可以透過 Windows 內建的 netsh 工具,將主機實體 IP 接收到的通訊埠流量轉發給 WSL 2 內部的 IP。

設定步驟

1. 取得 WSL 2 的內部 IP:在 Windows PowerShell 或是 WSL 終端機內輸入以下指令,取得 WSL 2 目前的 IP 位址:

wsl hostname -I
  • 請記下這組 IP (例如 172.18.x.x)。

2. 設定通訊埠轉發規則:以系統管理員身分開啟 PowerShell。使用以下指令建立轉發規則 (請將 abcd 替換為你實際需要的通訊埠,並將 <WSL_IP> 替換為上一步取得的實際 IP):

netsh interface portproxy add v4tov4 listenport=8080 listenaddress=0.0.0.0 connectport=abcd connectaddress=<WSL_IP>

3. 驗證與刪除規則

  • 查看現有規則:
netsh interface portproxy show v4tov4
  • 刪除轉發規則: netsh interface portproxy delete v4tov4 listenport=8080 listenaddress=0.0.0.0

3. 開啟防火牆

不管是使用方法1或2,對於同一區域網路內的主機,所有的傳入連線都是被 windows 防火牆阻擋的,因此需要再進一步的設定規則讓指定的端口可以通過。

I. 使用內建 GUI:「具備進階安全性的 Windows Defender 防火牆」

這個工具雖然名字很長,但它是 Windows 管理防火牆最標準、最乾淨的視覺化工具。

1. 開啟管理介面: 按下鍵盤的 Win + R 開啟「執行」視窗,輸入 wf.msc 並按 Enter

2. 新增規則:

  • 在視窗左側的選單點擊 「輸入規則」 (Inbound Rules)。
  • 在視窗右側的「動作」面板點擊 「新增規則...」 (New Rule...)。

3. 選擇類型: 選擇 「連接埠」 (Port),點擊下一步。

4. 指定 Port: 選擇你要的通訊協定(通常是 TCP)。

  • 選擇 「特定本機連接埠」,並在框框輸入你要開放的 Port(例如:8080,或是一段範圍 8000-8080,多個 Port 可用逗號分隔 80,443,8080),點擊下一步。

5. 允許連線: 選擇 「允許連線」 (Allow the connection),點擊下一步。

6. 選擇網路設定檔: 勾選這條規則適用的網路環境(網域、私人、公用)。

  • 如果你不確定,可以先全勾,或是為了安全只勾 「私人」 (Private),點擊下一步。

7. 命名與完成: 給這條規則一個好辨識的名稱,例如 WSL-Server,點擊完成。

日後如果你不想開放這個 Port 了,只要再次打開 wf.msc,在「輸入規則」清單中找到你命名的那條規則,對它點右鍵選擇 「停用規則」「刪除」 即可,非常直覺且乾淨。

II. 以系統管理員身分執行 PowerShell

習慣透過指令介面直接操作和管理防火牆可以使用這種方式,但是windows的指令較為不直覺,對新手不建議。

  1. 直接輸入以下指令:
New-NetFirewallRule -DisplayName "Allow WSL Port 8080" -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow