新版本下如何通过外部网络访问wsl
眾所周知,wsl2是windows下的linux子系統,并且采用類似于虛擬機NAT的管理方式。一般情況下,外部網絡很難直接訪問到wsl上的服務,除非使用端口轉發。而現在,微軟更新了wsl 2.0.0,采用鏡像網絡配置,完美解決了所有網絡上的問題。
研究起因
想直接看新版本解決方案的點這里
由于在編譯他人代碼時需要linux環境,我就放在了wsl下編譯運行,然后在本地,我就嘗試用ifconfig得到的虛擬機ip,成功連接上了wsl服務器。但是,當我試圖用局域網下其他設備連接時,很顯然,根本不可能連接上。這是因為wsl2采用了類似于NAT的網絡模式,windows作為宿主機,隔離了局域網下其他設備和wsl的連接。為了外部訪問wsl,我也試過一些方法。
舊版本端口轉發方案
在舊版本,常用的方法是端口轉發,根據官方文檔,在有管理員權限的powershell下,輸入如下指令:
netsh interface portproxy add v4tov4 listenport=<yourPortToForward> listenaddress=0.0.0.0 connectport=<yourPortToConnectToInWSL> connectaddress=(wsl hostname -I)
在此示例中,需要更新
<yourPortToForward>到端口號,例如listenport=4000。listenaddress=0.0.0.0表示將接受來自任何 IP 地址的傳入請求。 偵聽地址指定要偵聽的 IPv4 地址,可以更改為以下值:IP 地址、計算機 NetBIOS 名稱或計算機 DNS 名稱。 如果未指定地址,則默認值為本地計算機。 需要將<yourPortToConnectToInWSL>值更新為希望 WSL 連接的端口號,例如connectport=4000。 最后,connectaddress值必須是通過 WSL 2 安裝的 Linux 分發版的 IP 地址(WSL 2 VM 地址),可通過輸入命令:wsl.exe hostname -I找到。---官方文檔
然后,我將wsl中的8303端口映射在了windows下的8304端口下,我看到,在wsl中,服務器照常運行。
netstat -ano | findstr 8304
也能看到8304端口正常監聽。但是,在我訪問wsl運行的游戲服務器(游戲名:DDraceNetwork),客戶端顯示“udp疑似被攔截”。本來我認為這是端口轉發失敗了,但是我忽然注意到本地8304端口只有tcp。于是查詢了有關資料,得到了netsh只支持tcp的結論。因此,netsh方案失敗。
舊版本橋接模式方案
后來,我希望用hyper-v創建一個虛擬交換機,相當于一個可通外網的虛擬網卡,并讓wsl連接。結果,出現了許多問題。
- 當前版本下,wsl2已不支持更改連接方式為
bridge橋接模式,從根本上杜絕了這一方法 - 當我創建了虛擬交換機后并將其接入網橋,他直接把我Windows下的網絡干廢了。
試圖用Vmware創建交換機,結果根本找不到選項
最后,我發現了官網給出了新方案!
新版本鏡像網絡模式方案
由于本人入坑wsl時間晚,在此之前,我對wsl1只是道聽途說。據我了解,wsl1建立在兼容層上,與windows共存,因此wsl1的網絡配置與windows一致,外部網絡也可以很輕松地接入wsl。而wsl2則是基于hyper-v的虛擬機,采用的是新一套的NAT方案,較為獨立。所以對于wsl2也要用和普通虛擬機一樣的網絡方案,如NAT轉發和橋接。
而現在,在Windows23H2更新中,或是22H2中的insider,wsl2更新了鏡像網絡解決方案,這個方案將會解決幾乎一切wsl上的網絡問題。而此方法,也將隨著時間推移,成為wsl2的默認解決方案。
在此貼出微軟官方文檔:
使用 WSL 訪問網絡應用程序 | Microsoft Learn
wsl版本檢測
要啟用鏡像網絡模式,首先要保證你的windows系統是23H2以上,或是加入了windows體驗計劃。除此之外,由于版本更新已有一段時間,如果你不確定是否可以使用,可以在cmd輸入wsl --version查看wsl版本是否是2.0.0以上。如果是,那就可以。
配置wsl文件
在windows用戶根目錄下,新建個名為.wslconfig的文件,選擇合適的編輯器打開它。
如果不知道自己的用戶根目錄,可以在cmd下輸入
echo %USERPROFILE,即可看到路徑經過實驗,我甚至發現上面的命令只能在cmd命令提示符下執行,powershell還不行!!!
在文件中輸入如下內容:
[experimental]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
然后,執行wsl --shutdown,等待大約8秒后重新啟動wsl,即可成功改變網絡策略。
你可以通過在wsl虛擬機內執行ifconfig,看到原本有的IP地址現在沒了,即可證明mirrored模式啟用成功。現在你可以用phpstudy等軟件在windows下建立一個網站,然后用linux訪問,會發現linux可以訪問windows的服務。
比如說:我在windows下用80端口建立的網站,在linux下執行curl localhost,顯示的是windows的網站。
再比如說:我在linux下用apache在81端口建立了個網站,在windows下用瀏覽器訪問http://localhost:81,可以看到linux的網站。
那么,wsl的新版本網絡配置也就成功了…………
…………
嗎?
解決遺留的坑
很遺憾地告訴大家,我上面給出的配置文件少了一句話,而這句話才是本文的重點。為什么會單獨拿出來講,這是因為我在20分鐘查找資料的過程,沒有一篇文章講到這個。現在我們先來看看問題在哪里。
首先,我們要先知道windows的IP地址,不要求上百度看公網IP,只要一個局域網內的外部IP,也就是你電腦直連路由器分配給你的IP,假設是192.168.1.101,那么我現在在瀏覽器訪問http://192.168.1.101,可以成功看到宿主機創建的網站。
現在在讓我們訪問http://192.168.1.101:81,也就是linux下的網站端口,結果發現,無法訪問!
也就是說:
- localhost:81 可以!
- 192.168.1.101:81 不行!
那就奇了怪了,我也是成功在官網找到響應的配置選項,只要在最后加上那么一行:hostAddressLoopback=true就行了。
最后的配置文件:
[experimental]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
hostAddressLoopback=true
重啟wsl,問題解決,我的游戲服務器也能進入了,只是服務器列表不顯示[滑稽]
尾聲
我在這里貼出wsl2關于mirrored模式的一些其他配置選項,可以更好的幫助各位配置wsl。
| 設置名稱 | 值 | 默認值 | 說明 |
|---|---|---|---|
useWindowsDnsCache** |
bool | false | 僅當 experimental.dnsTunneling 設置為 true 時才適用。 如果此選項設置為 false,則從 Linux 隧道傳輸的 DNS 請求將繞過 Windows 中的緩存名稱,以始終將請求放在網絡上。 |
bestEffortDnsParsing** |
bool | false | 僅當 experimental.dnsTunneling 設置為 true 時才適用。 如果設置為 true,Windows 將從 DNS 請求中提取問題并嘗試解決該問題,從而忽略未知記錄。 |
initialAutoProxyTimeout* |
string | 1000 | 僅當 experimental.autoProxy 設置為 true 時才適用。 配置啟動 WSL 容器時,WSL 等待檢索 HTTP 代理信息的時長(以毫秒為單位)。 如果代理設置在此時間之后解析,則必須重啟 WSL 實例才能使用檢索到的代理設置。 |
ignoredPorts** |
string | Null | 僅當 experimental.networkingMode 設置為 mirrored 時才適用。 指定 Linux 應用程序可以綁定到哪些端口(即使該端口已在 Windows 中使用)。 通過此設置,應用程序能夠僅偵聽 Linux 中的流量端口,因此即使該端口在 Windows 上用于其他用途,這些應用程序也不會被阻止。 例如,WSL 將允許綁定到 Linux for Docker Desktop 中的端口 53,因為它只偵聽來自 Linux 容器中的請求。 應在逗號分隔列表中設置格式,例如:3000,9000,9090
|
hostAddressLoopback** |
bool | false | 僅當 experimental.networkingMode 設置為 mirrored 時才適用。 如果設置為 True,將會允許容器通過分配給主機的 IP 地址連接到主機,或允許主機通過此方式連接到容器。 請注意,始終可以使用 127.0.0.1 環回地址 - 此選項也允許使用所有額外分配的本地 IP 地址。 |
具有 path 值的條目必須是帶有轉義反斜杠的 Windows 路徑,例如:C:\\Temp\\myCustomKernel
具有 size 值的條目后面必須跟上大小的單位,例如 8GB 或 512MB。
值類型后帶有 * 的條目僅在 Windows 11 中可用。
值類型后顯示 ** 的條目需要 Windows 版本 22H2 或更高版本。
作者:Sxrhhh
個人網站:https://www.sxrhhh.top
博客園:Sxrhhh - 博客園 (cnblogs.com)
轉載請注明出處.
在個人網站持續更新中……
總結
以上是生活随笔為你收集整理的新版本下如何通过外部网络访问wsl的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FolkMQ 内存型消息中间件,v1.0
- 下一篇: 税盘是干什么用的 什么叫税盘