60

This question is related to my question about making a WSL2 address static. Since that looks like it isn't possible I am trying to come up with a workaround.

I am thinking I can run a shell script in WSL2 at boot that will write the WSL2 machine's address to a file on the host system. A powershell script will look for that file, and when it finds it it will run:

netsh interface portproxy add v4tov4 listenport=4000 listenaddress=0.0.0.0 connectport=4000 connectaddress=<WSL2 IP>

If possible I'd like to eliminate the need to run a shell script in Linux.

One possibility it via netsh interface ipv4 show neighbors. 172.27.154.150 is the current ip address of my WSL2 machine, but I am not really sure how to write a script to isolate that IP address.

PS C:\Users\Nick> netsh interface ipv4 show neighbors

Interface 1: Loopback Pseudo-Interface 1


Internet Address                              Physical Address   Type
--------------------------------------------  -----------------  -----------
224.0.0.22                                                       Permanent
239.255.255.250                                                  Permanent

Interface 7: Ethernet0


Internet Address                              Physical Address   Type
--------------------------------------------  -----------------  -----------
192.168.163.2                                 00-50-56-fa-e9-9e  Reachable
192.168.163.254                               00-50-56-fc-61-94  Reachable
192.168.163.255                               ff-ff-ff-ff-ff-ff  Permanent
224.0.0.22                                    01-00-5e-00-00-16  Permanent
224.0.0.251                                   01-00-5e-00-00-fb  Permanent
224.0.0.252                                   01-00-5e-00-00-fc  Permanent
239.255.255.250                               01-00-5e-7f-ff-fa  Permanent
255.255.255.255                               ff-ff-ff-ff-ff-ff  Permanent

Interface 19: Bluetooth Network Connection


Internet Address                              Physical Address   Type
--------------------------------------------  -----------------  -----------
224.0.0.22                                    01-00-5e-00-00-16  Permanent

Interface 14: vEthernet (Default Switch)


Internet Address                              Physical Address   Type
--------------------------------------------  -----------------  -----------
172.21.47.255                                 ff-ff-ff-ff-ff-ff  Permanent
224.0.0.22                                    01-00-5e-00-00-16  Permanent
224.0.0.251                                   01-00-5e-00-00-fb  Permanent
239.255.255.250                               01-00-5e-7f-ff-fa  Permanent
255.255.255.255                               ff-ff-ff-ff-ff-ff  Permanent

Interface 25: vEthernet (WSL)


Internet Address                              Physical Address   Type
--------------------------------------------  -----------------  -----------
172.27.154.150                                00-15-5d-f2-6b-94  Stale
172.27.159.255                                ff-ff-ff-ff-ff-ff  Permanent
224.0.0.22                                    01-00-5e-00-00-16  Permanent
224.0.0.251                                   01-00-5e-00-00-fb  Permanent
239.255.255.250                               01-00-5e-7f-ff-fa  Permanent

EDIT: See this answer for the script I wrote to automate starting SSHD in WSL and routing traffic to it

Nick
  • 1,263
  • 2
  • 12
  • 15
  • Note that a recent change in WSL2 made it so that it always attempts to re-use the same address. While it's still not "static", and *can* (in theory) change, for many use-cases it should be find to assume that the address will remain constant. – NotTheDr01ds Aug 15 '23 at 19:22

5 Answers5

80

From Windows powershell or cmd use the command:

wsl hostname -i

This should return an IP address if WSL is running. It appears to start the default distro if not running, and then return the address of that. (takes a few seconds longer to return)

Note that while this should work for the simple case, it might not work for every distro that you might run inside WSL. In that case, you should consider Hashbrown's answer (which involves a more complicated command, but may work better)

wojtow
  • 1,039
  • 9
  • 7
  • 6
    This doesn't seem to work for me. With WSL2 running: - I run `wsl hostname -I` from powershell in windows and get 172.24.128.1 - But in WSL2 I run `ifconfig` and get 172.24.137.181 as the IPv4 address – aproximation Mar 20 '21 at 14:07
  • 8
    @aproximation - is it possible that you have more than one wsl instance running? `wsl -l -v` would list them all. If you have more than one, the command to use would be `wsl -d "distroname" hostname -I` – wojtow Mar 22 '21 at 01:35
  • I think you're on to something - thanks! It looks like I have Legacy (v1) and Ubuntu (v2) installed, and there's an asterisk next to the Legacy WSL despite me using WSL2. That asterisk signifies which install is primary, doesn't it? Do you happen to know the command I'd use to mark the v2 WSL as the primary WSL? – aproximation Mar 23 '21 at 14:52
  • 3
    @aproximation `wsl --set-default "distroname"` (where distroname is exactly the string from `wsl --list` that you want set as the default (primary). `wsl --help` will list all the other things you can do. – wojtow Mar 29 '21 at 16:29
  • 1
    Thank you, @wojtow! That did it for me! ...sometimes I wish windows had an equivalent of 'man [command]' that I could use to find info on the command line tools... – aproximation Apr 02 '21 at 20:37
  • It works if you use lowercase `-i` as the parameter. – jnovacho Sep 23 '21 at 14:01
  • It's not working for me, i'm trying to get docker wsl instance and when i use "wsl -d docker-desktop hostname -i" (WITH MINUS I), it gives me "127.0.1.1" while i want "172.21.173.74". Downvoted – 4x10m May 01 '22 at 16:25
  • @4x10m The answer was originally written for basic WSL usage whereas docker-desktop is a special case. Hashbrown's answer should give you the results that you seek, but it's a significantly complicated command for the simple case. I'm adding a caveat to my original answer. – wojtow May 02 '22 at 19:26
  • Tested on Debian WSL and it is working. In fact I upvoted. It might be interesting to know why is that. – 4x10m May 03 '22 at 20:08
33

For me my WSL has multiple interfaces so hostname isnt appropriate. In this instance you can use this:

wsl -- ip -o -4 -json addr list eth0 `
| ConvertFrom-Json `
| %{ $_.addr_info.local } `
| ?{ $_ }

Change -4 to -6 for ipv6, and eth0 to your interface of choice.


Also, if you need the IP address of the host from the vm you can run this (on the host)

$wsl    = wsl -- ip -o -4 -j addr s eth0 | ConvertFrom-Json | %{ $_.addr_info.local } | ?{ $_ }
$master = (Get-NetIPAddress).IPAddress | ?{ $_ -match ($wsl -replace '^((\d+\.){2}).*$','^$1') }
$wsl,$master #access wsl from master using the first ip, the converse from the latter
Hashbrown
  • 2,782
  • 4
  • 32
  • 47
  • This version is ready to use with Powershell scripts. wsl hostname -I doesn't work in Powershell for some reason.. Thanks! – Shinebayar G Sep 24 '21 at 19:23
9

For checking your WSL IP address from the WSL machine:

ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'
dunxd
  • 1,125
  • 2
  • 13
  • 25
HRX_
  • 99
  • 1
  • 1
0

run this on your wsl terminal:

ip add | grep "eth0"
asma
  • 109
  • 3
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 02 '23 at 10:57
0

I am using this powershell script "SetDockerHost.ps1" to set my local DOCKER_HOST env variable:

$wslip = ((wsl hostname -I) -split " ")[0]
$dockerhost = "tcp://" + $wslip + ":2375"
setx DOCKER_HOST $dockerhost
Write-Host "Set: setx DOCKER_HOST $dockerhost"
Read-Host -Prompt "Press Enter to exit"
max
  • 101