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 certain 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, with a detailed description of my solution.

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 use it for access.

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 and run it when you need to access WSL, no additional operations are required.

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, and if not found, it uses 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 record 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 start of WSL, so the final requirement becomes: write the IP to the hosts file in Windows when WSL starts.

From this requirement, two ideas have emerged:

  1. Complete this process on Windows, specifically by binding a custom task to the event triggered when WSL starts. This task matches the IP by executing ifconfig in WSL with regular expressions, and writes it to the hosts file.
  2. Complete this process on WSL, specifically by adding a startup script. In this script, obtain the IP of the local machine by any means and write it to /mnt/c/Windows/System32/drivers/etc/hosts (because the drive letter of Windows is automatically mounted to /mnt in WSL).

Idea 1#

The core of Idea 1 is a custom task, and the specific workflow can be implemented in many ways. A relatively simple option is shayne/go-wsl2-host, which automatically adds a custom task triggered when WSL starts. It should work theoretically (unfortunately, it didn't work properly for me, 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 that WSL can read and write the /mnt/c/Windows/System32/drivers/etc/hosts file normally.
  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 process 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 are exactly 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 use a single space as the separator.

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.