WSL預設的網路模式是NAT,會讓Ubuntu跑在內網,並自動取得一個IP。
此時你會發現,在WSL內跑一個伺服器服務,只有本機能連線,無法從Windows以外的網路存取WSL服務。
例如跑Apache伺服器,僅能在Windows電腦的瀏覽器打http://localhost:80
連線,無法從外部網路存取,一律是Connection refused
!
這時候該怎麼辦呢?
以前的作法是調整WSL的網路卡,變成橋接模式(Bridged Mode Networking),不過這得手動調整Hyper-V網路卡,設定很不方便。
最新版本的WSL提供了一種鏡像網路模式(Mirrored Mode Networking),可以替代橋接網路部份功能。
1. 環境#
- Windows 11 23H2
- WSL 2.2.4
- Ubuntu 22.04,未啟用UFW防火牆
2. 調整WSL2網路為鏡像模式#
在
C:\Users\使用者名稱\
資料夾,新增設定檔.wslconfig
填入以下內容,啟用鏡像網路模式
[wsl2]
networkingMode=mirrored
- 以系統管理員開啟Windows終端機,執行以下指令,允許Windows本機用WSL的IP連線到WSL服務:
[experimental]
hostAddressLoopback=true
- WSL會吃到Windows Hyper-V防火牆的規則。以系統管理員執行以下指令,開放Hyper-V防火牆,允許所有連入連線
Set-NetFirewallHyperVVMSetting -Name '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' -DefaultInboundAction Allow
或者,新增Hyper-V防火牆規則,只開放特定通訊埠,這邊是Apache預設的80/tcp
New-NetFirewallHyperVRule -Name "MyWebServer" -DisplayName "My Web Server" -Direction Inbound -VMCreatorId '{40E0AC32-46A5-438A-A0B2-2B479E8F2E90}' -Protocol TCP -LocalPorts 80.
- 重啟WSL
wsl --shutdown
wsl
- WSL就會得到一個可從外部存取的區域IP。目前僅支援IPV4,不支援IPV6。
ip addr
# 請查看eth0網卡的IP,應該是192.168開頭的
- 執行Apache伺服器服務
sudo apt install apache2
sudo systemctl start apache2
- 如此一來就能用上面得到的IP存取Apache伺服器了。這裡的例子是使用同一網段下的另一台電腦存取Apache伺服器。
3. 修正Docker網路問題#
使用網路鏡像模式下,Docker可能會出現read: connection reset by peer.
無法連線的錯誤。
必須停用Docker調整iptables的功能:
echo '{ "iptables": false }' | sudo tee -a /etc/docker/daemon.json
sudo systemctl restart docker