amtoaer

晓风残月

叹息似的渺茫,你仍要保存着那真!
github
x
telegram
steam
nintendo switch
email

Accessing WSL2 on Windows

Many people have encountered issues with communicating with the Windows host when using WSL. In everyday programming, it is common to access databases, web servers, and other services deployed in WSL from Windows. Windows itself does mapping, for example, starting an HTTP server with the following command:

➜ source git:(master) python -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

At this point, accessing localhost:8000 on Windows will open the server correctly. However, in some other scenarios (such as database connections), this mapping may fail. Could it be because WSL only maps the ports for HTTP services? (doubtful)

To solve the above problem, we need a way to ensure that the Windows host can easily access WSL. Here are three solutions listed, and I will describe my solution in detail.

Manually Find the LAN IP of WSL and Use That IP for Access#

This method is the simplest and most straightforward. Manually find the IP of WSL and access it.

Execute the ifconfig command in WSL to get a lot of output:

 source git:(master) ifconfig
.....
eth0: .......
        inet 172.21.255.188  .....
.....

Find the IP address after inet above, which is the LAN IP of WSL.

However, the IP of WSL changes every time it starts up, so this method is not a good choice if you frequently need to access WSL.

Connection Mapping#

Use HobaiRiku/wsl2-auto-portproxy to map all TCP ports in WSL to Windows localhost (UDP is not supported yet).

To use this method, simply download the binary file when you need to access WSL, and run it without any additional operations.

Add WSL IP to the hosts file in Windows#

The drawback of the first method mentioned earlier is that the IP changes every time it starts up, which makes us think of domain names.

As we all know, domain name resolution first looks for the hosts file. If it is not found, it will use DNS. Therefore, this method is to add the IP of WSL and a custom domain name to the hosts file in Windows, so that you only need to access the domain name you set.

The implementation idea is similar to "modify domain name resolution records when the local IP changes" in DDNS. It needs to achieve "modify the hosts file when the WSL IP changes". And we know that the change of WSL IP actually means the startup of WSL. So the final requirement becomes: Write the IP into the hosts file in Windows when WSL starts.

Starting from this requirement, two ideas have emerged:

  1. Complete this process on Windows. The specific method is to bind a custom task to the event triggered when WSL starts. This task obtains the IP by executing ifconfig in WSL and writes it to the hosts file through regular expression matching.
  2. Complete this process on WSL. The specific method is to add a startup script, which obtains the local IP by any means and writes it to /mnt/c/Windows/System32/drivers/etc/hosts (because Windows drives are automatically mounted under /mnt in WSL).

Idea 1#

The core of Idea 1 is a custom task, and the specific workflow can be implemented in many ways. One of the simpler ways is to use shayne/go-wsl2-host. This project automatically adds a custom task triggered when WSL starts, and it should work theoretically (unfortunately, it didn't work properly for me, and I don't know why).

Idea 2#

Idea 2 has fewer implementations because there was no effective "startup" method in the past for WSL. However, this obstacle has disappeared with the support of systemd in WSL, as mentioned in WSL's support for systemd. Therefore, I created a project using this approach.

To use this project for Arch Linux:

  1. Make sure WSL can read and write the /mnt/c/Windows/System32/drivers/etc/hosts file properly.
  2. Download the .pkg.tar.zst file from the release and install it using sudo pacman -U.
  3. Enable the service using sudo systemctl enable --now wah.service.

For other distributions, simply replace the second step above with manual installation:

install -D -m 755 $srcdir/wah $pkgdir/usr/bin/wah
install -D -m 755 $srcdir/wah.service $pkgdir/usr/lib/systemd/system/wah.service
install -D -m 755 $srcdir/domains $pkgdir/etc/wah/domains

The other steps remain the same.

By default, this project will use the domain name arch.wsl. If you need to customize it, you can edit the /etc/wah/domains file. For multiple custom domain names, please separate them with a single space.

This project will automatically add the address of WSL to the bottom of the hosts file and update it every time WSL starts:

image-20221129130815511

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.