完美解決 WSL2+mitmproxy 無法連接的問題 / windows子系統的端口映射及其原理
1 問題描述
項目需要,需要抓一下發送自手機app的數據包做degub。同時需要轉發到內網環境,所以需要做一個中間人轉發。然而用wsl2,不能直接訪問虛擬機的虛擬ip,所以只能考慮把數據包發送到windows下,再轉發給wsl。
先說明,這個問題在wsl1中是不存在的,因為wsl1和windows共用了同一套端口,不會有port forwarding 的問題。
現在我的問題是:按照流程安裝完畢后,一切均正常,只是手機端連接不上。在已經PC和手機端都已經安裝證書的情況下,手機一直不通ping,甚至無法接入互聯網。同時,在wsl上也看不到任何來自手機端的連接請求。如果你遇到了一樣的問題,那么大概率是因為wsl2的端口映射導致的。
2 解決方案
解決這個問題需要建立一個從windows 到wsl2 的端口映射關系。這個過程一般分為兩步
- 1, 使用cmd建立一個端口映射關系。為此,需要准備三個值:windows下的源端口、wsl虛擬機ip地址、wsl下的目標端口
以上三個量中,windows下的源端口自己設置(不要和已有的應用程序發生沖突),wsl虛擬機ip地址一般是之前在ip addr中看到的地址,wsl下的目標端口是mitmproxy監聽的端口號(默認為8080)。明確這三個值后,執行指令:(listenport是windows下源端口,我這里是8001,connectaddress是wsl的虛擬地址)
(記得以管理員身份執行)
netsh interface portproxy add v4tov4 listenport=8001 listenaddress=0.0.0.0 connectport=8080 connectaddress=xxx.xxx.xxx.xxx
之后使用netsh interface portproxy show all 查看自己建立的端口映射。我這里是這樣的

(如果想要刪除的話,執行netsh interface portproxy delete v4tov4 listenport=8001 listenaddress=0.0.0.0)
- 2, 設立windows 出站規則
如果這時還不行,那么大概率是windows防火牆擋住了這些訪問的數據包。可以使用以下方法解決:
依次打開防火牆與網絡保護-->高級設置-->入站規則。點擊新建規則

這里第一步選擇端口-->選擇TCP-->點擊特定本地端口,填入之前選擇的windows源端口(我這里是8001)--點擊第一個允許連接,之后一路繼續就好了。一直到配置完成。之后同理,完成UDP協議的轉發設置。
- 設置mitmweb
在經歷之前的兩步之后,正常情況下,已經可以在shell里面看到訪問log了。此時手機連接后,也可以正常瀏覽一些網頁,但是對一些app可能有時候仍舊存在連接問題。
這個時候,仍需要對mitmproxy做一些關於ssh的校驗設置。
使用指令mitmweb -k進行監聽,並訪問對應的網頁,勾選Don't verify server certificates。不再對服務端證書進行驗證。問題得解。

(題外話:有的人(比如我)這個位置可能無法勾選,並會在命令行中彈出一個錯誤log,這個時候需要到左邊edit options再進行一步操作,手動勾選ssl_insecure。如圖

)
最后,由於wsl的虛擬地址不是固定的,每次都重新設置端口映射的話可能會很麻煩,所以讀者可以考慮設置一下啟動時自動配置ip地址,我自己寫了一個小腳本,可以在開機時自動設置端口映射至wsl下的虛擬ip地址。有需要的同學可以去我的github下載。
3 原因
其實出現的核心原因在於WSL2 的網絡機制。如果在cmd中使用ipconfig查看,可以發現多了一項wsl2 虛擬地址。這一重大改變允許wsl擁有自己的一些底層網絡功能,但是同時也讓運行在wsl上的網絡應用更難訪問。引用一段官方文檔上的介紹:
WSL 2 做了架構的巨大變更,使用了虛擬化技術,並仍在努力改進網絡支持。由於 WSL 2 現在運行在虛擬機中,因此你從 Windows 訪問 Linux 網絡應用程序需要使用該 VM 的 IP 地址,反之亦然,你需要 Windows 主機的 IP 地址才能從 Linux 中訪問 Windows 網絡應用程序。
4 內容參考
https://docs.microsoft.com/zh-cn/windows/wsl/compare-versions#whats-new-in-wsl-2
