故事要從「Microsoft ❤️ Linux」說起,自 2019 年 Satya Nadella 對 Linux 高調示愛以後,就有了 WSL,這場跨越商業模式的愛能不能順利走下去,讓我們看下去。

WSL 讓我們不用裝雙開機就可以在 Windows 內跑起一套接近完整的 Linux,之所以能這樣,背後依賴的是 Hyper-V 虛擬化技術,本質上 WSL 是一個特製的 VM,也因此我們會遇到的第一個問題就是「 WSL 如何與 Windows 透過 IP 互連?」

WSL 如何與 Windows 透過 IP 互連實際上是兩個問題,見下文。

服務開在 WSL,給 Windows 連入

第一個問題,服務開在 WSL,Windows 要如何連入?

假設在 WSL 的 8086 埠跑著一支服務,試著在 Windows 連連看,最簡單的測試方式就是拿瀏覽器開看會不會通,測試下面兩個網址:

  • http://localhost:8086/
  • http://127.0.0.1:8086/

在 Windows 以 http://127.0.0.1:8086/ 測試可能會被拒絕連線,因為如前面所說, WSL 本質上是一台特製的 VM,它有自己的 IP,而 127.0.0.1 是指向 Windows 自己,如果 Windows 沒有監聽 8086 埠的服務,那就會被拒絕連線。

另一方面,如果改用 http://localhost:8086/ 測試,則應該會成功,因為 Windows 很貼心的開啟了 WSL 的轉送機制,所有往 localhost 的請求都會轉給 WSL。

這邊有點違背直覺的是 localhost 竟然指向的不是常理的 127.0.0.1,而是 WSL,這點一旦疏忽,就有可能像我一樣,浪費一個下午搞不清摸不懂通與不通的難題。

至於 WSL 具體的 IP 是什麼,可以在 WSL 內的 shell 查詢:

$ ip addr

接著第二個問題,服務開在 Windows,WSL 要如何連入?

服務開在 Windows,給 WSL 連入

基於對「WSL 本質是 VM」的理解,兩者間也必然是各有各的 IP,有專門的方法可以在 WSL 內查到 Windows 的 IP:

$ cat /etc/resolv.conf

內容如下:

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.22.128.1

172.22.128.1 就是 Windows 在 WSL 網路的 IP,因此,只要開啟 http://172.22.128.1/ 應該也可以打開 Windows 的 web 服務了。

參考資料

使用 WSL 存取網路應用程式