Open jkasten2 opened 4 years ago
Same issue here.
IP address of Windows machine is 192.168.1.95 and the eth0 interface in Ubuntu on WSL2 is getting 172.18.47.17.
I originally had Ubuntu on WSL1 running and then upgraded the installation to WSL2 but same problem. Then I uninstalled Ubuntu altogether and reinstalled fresh but same issue after reinstall.
Prior to using WSL2 I had an instance of Ubuntu setup as a Hyper-V VM on the same machine (Hyper-V NIC bridge already existed).
Same issue. I have a rstudio server running in docker container in WSL2 and wanted to access it from other machine but failed. Really need some fix/idea on it.
I can confirm this issue. I can no longer access the service running in subsystem from my mobile device, which is within the same wifi network with my windows laptop.
It's not a bug with WSL 2, WSL 2 is running as a hyper-v virtual machine. The hyper-v adapter can be found in network adapters. You can use port forwarding to forward the port with netsh as below.
Example command below will forward tcp from port 3000 of the WSL 2 client to port 3000 of the host OS.
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.18.28.x
Next allow incoming and outgoing ports on port 3000 in firewall.
It's not a bug with WSL 2, WSL 2 is running as a hyper-v virtual machine. The hyper-v adapter can be found in network adapters. You can use port forwarding to forward the port with netsh as below. Example command below will forward tcp from port 3000 of the WSL 2 client to port 3000 of the host OS.
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.18.28.x
Next allow incoming and outgoing ports on port 3000 in firewall.
Hi! Did you try it on your end? It didn't work for me when I was trying to access it from another machine in the same network. Although I did work when I use the windows host.
I tried it. It worked but the craziest thing is happening, the ip address is changing on reboot. Don't forget to add inbound and outbound rules. Microsoft will fix this issue in the future
Introduction
With the introduction of WSL 2 Beta, Microsoft has made changes to the system architecture. The changes include changing from the default bridged network adapter to a hyper-v virtual network adapter. The implementation was not completed during the launch of the beta program. This makes accessing of network resources under WSL 2 complex. The work around is to forward the TCP ports of WSL 2 services to the host OS. The virtual adapter on WSL 2 machine changes it's ip address during reboot which makes it tough to implement a run once solution. Also a side note, windows firewall will block the redirected port.
The work around is to use a script that does :
Configuration
The script must be run at login ,under highest privileges to work, and Powershell must be allowed to run external sources.
PowerShell Configuration
Enable power shell to run external scripts, run the command below in power shell with administrative privileges.
How To: Go to search, search for task scheduler. In the actions menu on the right, click on create task. Enter Name, go to triggers tab. Create a new trigger, with a begin task as you login, set delay to 10s. Go to the actions and add the script. If you are using Laptop, go to settings and enable run on power.
Finally: I am no expert at security nor scripting and technically new to the windows OS.
Update The update adds the feature to remove unwanted firewall rules. Here is the script.
$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
if( $found ){
$remoteport = $matches[0];
} else{
echo "The Script Exited, the ip address of WSL 2 cannot be found";
exit;
}
#[Ports]
#All the ports you want to forward separated by coma
$ports=@(80,443,10000,3000,5000);
#[Static ip]
#You can change the addr to your ip config to listen to a specific address
$addr='0.0.0.0';
$ports_a = $ports -join ",";
#Remove Firewall Exception Rules
iex "Remove-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' ";
#adding Exception Rules for inbound and outbound Rules
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Outbound -LocalPort $ports_a -Action Allow -Protocol TCP";
iex "New-NetFireWallRule -DisplayName 'WSL 2 Firewall Unlock' -Direction Inbound -LocalPort $ports_a -Action Allow -Protocol TCP";
for( $i = 0; $i -lt $ports.length; $i++ ){
$port = $ports[$i];
iex "netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr";
iex "netsh interface portproxy add v4tov4 listenport=$port listenaddress=$addr connectport=$port connectaddress=$remoteport";
}
@edwindijas Awesome, that worked for me! 👍 🎉 I can access my running Linux service from any system on my network via my Windows host IP! Thanks for all the detail and Task Scheduler suggestion too.
In addition, this workaround means localhost
works too.
I was trying to go down another route by forcing bridge mode of WSL virtual adapter, that didn't work. Just including it here for completeness.
PS C:\WINDOWS\system32> Set-VMSwitch WSL -NetAdapterName 'Name_of_your_phsyical_windows_NIC'
Set-VMSwitch : Failed while adding virtual Ethernet switch connections.
External Ethernet adapter 'Name_of_your_phsyical_windows_NIC' is already bound to the Microsoft Virtual Switch
protocol.
At line:1 char:1
+ Set-VMSwitch WSL -NetAdapterName 'Name_of_your_phsyical_windows_NIC'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-VMSwitch], VirtualizationException
+ FullyQualifiedErrorId : InvalidParameter,Microsoft.HyperV.PowerShell.Commands.SetVMSwitch
@edwindijas Linked your comment as a workaround for this issue in my original post https://github.com/microsoft/WSL/issues/4150#issue-456591548.
The script only opens ports you desired. And the ports are redirected to WSL machine. That said, I am no security expert, if you have a better suggestion, I am open to suggestions.
my method to solve this problem: refresh ip in win10:hosts file
WSL 2 TPC NETWORK FORWARDING
Introduction .... Configuration
The script must be run at login ,under highest privileges to work, and Powershell must be allowed to run external sources.
PowerShell Configuration
Enable power shell to run external scripts, run the command below in power shell with administrative privileges.
I saved your script in a file called "wslbridge.ps1" and then in Windows Scheduler just set Powershell.exe as Action and as argument I wrote this (instead of setting the Unrestricted ExecutionPolicy):
-ExecutionPolicy Bypass c:\scripts\wslbridge.ps1
Thanks
I wrote a Windows Service that automatically writes the WSL2 VM's IP address to the Windows hosts file. You can then just always reference "wsl.local" from your host machine and it will resolve to the WSL2 VM.
I've been using this for a week now and just open-sourced it.
I've collected a few WSL2 hacks into a repo: https://github.com/shayne/wsl2-hacks
One thing I wanted to point out, relevant to this thread, was "Access localhost ports from Windows", a way to access ports bound to 127.0.0.1
/ localhost
from the Windows host.
Thanks @edwindijas, it is a great workaround.
For people using Debian, which does not come with ifconfig
out of the box, you can try:
$remoteport = bash.exe -c "ip addr | grep -Ee 'inet.*eth0'"
Also, the hint from @gstorelli of using -ExecutionPolicy Bypass
inside the arguments of your Task Scheduler
script action is awesome!
Thanks, guys!
If there are multi wsl2 in your system, remember use this command on cmd to change the wsl2 which you want to bind these port as the default one, because bash.exe will run command in the default wsl2 environment:
# list the wsl on you system
wslconfig /l
# set Debian as default for example
wslconfig /setdefault Debian
@edwindijas I was hoping to make my Google Chrome (inside my Kali Distro) recognize my Chromecast, but i couldn't find anywhere the actual ports chromecast uses to connect, however now i can access my Kali from anywhere trought SSH.
You can now use localhost to connect in recent WSL2 versions
You can now use localhost to connect in recent WSL2 versions
That's really sort of a different problem -- you can use "localhost" from the host itself, but there's no obvious way to get there from a different machine on the network:
WSL2 is running on Windows host A WSL2 on Windows host A is running server application B You can connect to the application from host A by just doing "localhost:port" You can't connect to the application from Windows Host C in any obvious way.
You can connect to the application from host A by just doing "localhost:port" You can't connect to the application from Windows Host C in any obvious way.
If you open the port, why would you not be able to connect to host A from host C by just doing "host-A-ip:port"?
This behaviour shouldn't be any different then it is for linux.
I don't know the technical reason for it, but it doesn't work by default, and is what brought me here.
You can connect to the application from host A by just doing "localhost:port" You can't connect to the application from Windows Host C in any obvious way.
If you open the port, why would you not be able to connect to host A from host C by just doing "host-A-ip:port"?
This behaviour shouldn't be any different then it is for linux.
Although you can open Win app by localhost:port from WSL2, but they are definitely not sharing the same network like WSL1.
This is working in WSL1, but in WSL2 it's not. Still waiting form a solution.
Hi, Is there any update on this? I can access my apache in wsl2 fine but it seems like it is not on the same company network as Windows which causes some issues.
This only solves it from Windows to WSL i guess? But i am relying on the otherway around, WSL to Windows, which seems to be broken too.
Scenario: I am using the Docker Client within WSL, Docker Desktop (Server) on the Host (Windows). It can only be accessed by tcp://localhost:2375. This worked prior to upgrading to WSL2.
This only solves it from Windows to WSL i guess? But i am relying on the otherway around, WSL to Windows, which seems to be broken too.
Scenario: I am using the Docker Client within WSL, Docker Desktop (Server) on the Host (Windows). It can only be accessed by tcp://localhost:2375. This worked prior to upgrading to WSL2.
That is a different issue and you should search/create a new issue in this list for that.
That is a different issue and you should search/create a new issue in this list for that.
I think this use-case would also be solved with a proper bridged network like in WSL1, wouldn't it?
Wait I am confused, I cannot access my WSL Ubuntu from another computer or even from a Hyper-V VM on the same machine and I have disabled the firewall so changing firewall rules don't fix anything for me.
How do you make this work without a firewall? How can I allow my WSL to get its own IP from the DHCP server on my network so that it can be accessed via that?
Not sure why this is complicated can't it just be a passthrough as well, windows wins first if somethings on the requested port, however, if not just auto bridge/route to the WSL. However I think just like VM's get their own IP if you have bridge mode setup, why can't the WSL instance get its own ip in a similar fashion would be a better out of the box option.
my method to solve this problem: refresh ip in win10:hosts file
WSL 2 TPC NETWORK FORWARDING
Here is the script.
For those who kindly posted solutions I strongly recommend to add advices how to do this manually too. To only post scripts which update a host file etc. is not a very secure official advice, since some users do not understand what the script is doing. For example: try to find a solution on google to manually update the host file and how the line has to look like to bridge to the wsl2 ip and you will find nothing but this issue thread here.
As long as this issue https://github.com/shayne/go-wsl2-host/issues/7 still persists I actually do not recommend to have (Has Workaround) in title of this issue here. From what I understood in other issue comments, it is rather referring to Shaynes addition now than to the original Workaround linked in the OT?`The provided workaround is harming a system slidely with an additional service running and cannot be removed easely for basic users at the moment. I think this needs to be considered before installing it.
If you do not wish to clutter your system with scripts and you have access to a different computer on your network through ssh you can do:
ssh -R 0.0.0.0:8080:localhost:80 -N root@othercomputer
Remember to enable GatewayPorts
in sshd_config, as outlined in the following question: https://superuser.com/questions/588591/how-to-make-ssh-tunnel-open-to-public
It is probably possible to forward the port to the same windows machine that is running wsl, but I haven't bothered to check.
This approach can be used to expose the server publicly as well, using a service like serveo.net
At least with Windows 10 version 1903 build 19018.1 with WSL2, it appears binding a service to a port on 0.0.0.0 can also be used without having to find the IP address of eth0. From WSL2 if a service (e.g. httpd) is bound to a port (e.g. 8085) using address 0.0.0.0 (interface sit0@NONE the V6overV4 virtual adapter), then the service can be accessed from Windows using localhost. Applying the firewall rules above (allowing inbound & outbound rules and portproxy) will disable access via localhost but allow a (remote) host to access the service on WSL2 via the Windows IP address. Deleting the rules will allow localhost to be used again. This could make it a little easier for switching between testing on the local Windows OS and a remote machine.,as it would not necessary to spot the service to switch the binding between localhost and the IP address of eth0.
The script by @edwindijas seems to break WinRM. After using it I am stuck with the following error when trying to use WinRM:
WinRM firewall exception will not work since one of the network connection types on this machine is set to Public
Although I am very definitively connected to a Private Network.
WimRm creates an HTTP listener this way, but fails to create the HTTPS listener.
I tried to reboot and to delete the Firewall rule that the script created but the error persists.
Just found something interesting related to SEO, our web page: https://tech.yj777.cn/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3-wsl2/ was referer from this page. Because our page referred this page. So for those can read Chinese, you can also take a look into that article. Sorry, not that much related.
On WSL-1 I could have an apache web server using vhosts to serve a number of websites. In my windows hosts file I just needed to have entries to the vhost domains assigning them the loopback IP address 127.0.0.1.
This was great, I could replicate setup's like for example, having two websites using services form a third; a couple of Wordpress sites, say, my-wp-site-1.local and my-wp-site-2.local that use a plugin to communicate with a rest based API service hosted at, say, my-api-site.local. I could set my hosts file to resolve all of those domains to 127.0.0.1, then setup the corresponding vhosts.conf files in WSL-1 /etc/apache2/sites-available, a2ensite them, reload apache and hey presto my wp sites would appear in my browser for http://my-wp-site-1.local or http://my-wp-site-2.local and their plugin could use the web services at http://my-api-site.local.
I addition, the web files could be in the windows file system so my windows based coding IDE worked as normal, but also accessed in WSL-1 via /mnt so the webserver running there could access them (vhosts.conf's) and I could use git commands there in the bash terminal to push/pull code to origin.
It wasn't a very portable setup, but still better than anything I'd had before.
Then came WSL-2 and I saw that it could use Linux containers. This looked even better; there is potential for a portable setup. I can have my vhosting wp server in one container for my-wp-site-1.local and my-wp-site-2.local, my rest api server my-api-site.local in another (they have different php mods and stuff) and I imagined each container could run with it's own IP address assigned so I can again use the windows hosts file to resolve domains so that http requests go to the correct container.
And better still, this setup would mirror what I could implement, say, in AWS under ECS or Fargate.
Sadly, I was soon to be frustrated at how difficult this was to achieve and disappointed that such a promising development fell short of providing what I needed. I can't seem to find a way of setting this up that is within the limits of my basic networking knowledge. I also think that my use case is very probably a common one so for WSL-2 to be useful to people with it, it should not be this hard to achieve what I have described.
I hope cleverer minds that mine can find a way to make this happen so that I don't need an elaborate setup to achieve it.
Things I've noticed while trying to make it work: ifconfig in my my WSL-2 session shows: eth0: inet 172.19.71.88 docker0: inet 172.17.0.1
and in my container when I start the apache daemon I see: root@a50e655f4b8c:/# service apache2 start
So the container is getting allocated another IP address in WSL-2's network by incrementing the last octet , and I guess each new container would get the same.
If I try to browse to 72.17.0.2 from windows, the request times out as the address can't be reached. I understand that a fix for this was to add magic that caused localhosts to give you access, but that doesn't allow me to use my local dev domain names as was the case when using 127.0.0.1 under WSL-1.
I have no idea if the following suggestion I'm going to make is possible, but from an end user perspective it would make this kind of setup easier. I would configure my router to reserve an IP address range to be excluded from DHCP (say 192.168.0.1 to 192.168.0.50), and then add my dev domain names to my hosts file using ip address from within that range. I would then use the docker run command using, the --ip option, like --ip 192.168.0.1
Better still would be a flag that let me pass a local domain name and which and updated docker run command could do the lookup on my hosts file to get the corresponding ip address.
Until this issue is solved, I am using ngrok. It allows you to expose localhost
with public ngrok urls.
One liner forward ports. Listenport is the world visible port, connectport is the port on the linux (and windows localhost) side of things.
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=80 connectaddress=localhost connectport=8888
If you're using the windows firewall you're going to need to open the port in that before other computers can access it still.
@gmorenz does this workaround persist after restart?
Please note that in case of multiple distros running as WSL2, you still need network bridging, and workaround using port forwarding would quickly become unusable (and not "just" awkward as is), eg. running same service type on multiple WSL2 distros, using same ports.
Bump!
What we want? We want bridge network on WSL2. When we want? NOW
WSL 2 TPC NETWORK FORWARDING
Introduction
With the introduction of WSL 2 Beta, Microsoft has made changes to the system architecture. The changes include changing from the default bridged network adapter to a hyper-v virtual network adapter. The implementation was not completed during the launch of the beta program. This makes accessing of network resources under WSL 2 complex. The work around is to forward the TCP ports of WSL 2 services to the host OS. The virtual adapter on WSL 2 machine changes it's ip address during reboot which makes it tough to implement a run once solution. Also a side note, windows firewall will block the redirected port.
This works great for me, except for forwarding a WOL magic packet coming from inside WSL2, I tried forwarding port 7,9 (the common WOL ones) but its not working since it probably doesn't work the same way, any ideas how to forward that packet?
thanks
Just seconding that we either need a separate issue, or we need to remove the "Has Workaround" title. AFAIK, it is simply not possible to access a server hosted under WSL2 from a remote computer. I have completely disabled the firewall, forwarded ports, everything. On-box, all is smooth -- localhost:port works for my web dev work. However, viewing my dev sites in a mobile browser is impossible without ridiculous workarounds (deploying the site on another "real" linux box, for instance).
Here's the 10,000th vote for a proper bridged networking mode.
My temporary workaround is to use the https://github.com/shayne/go-wsl2-host service to map the dynamic IP every time WSL starts. This works really well and you only need to reinstall it when a new insider build installs. Then I use this command to map my external services:
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=dns.to.wsl
Portproxy can take a DNS address for the connectaddress argument. This allows it to always work as long as you use the IP mapping service.
You still need to open your Windows firewall to the listen port just like you would for any service running on Windows.
I can now access my WSL2 host from any network computer and even internet clients if I open my external firewall.
But, yes, PLEASE Microsoft, allow bridged network mode. Took me way to long to figure this out.
Im trying to get Traffic over UDP working with WSL 2. It seems that i can't forward UDP Ports. I have set my firewall to not block the Ports. Any ideas how to solve my problem? I know for sure a Network Bridge would solve all my and others Problems. Also the "Has Workaround" is not precise becouse it does not work completely. Edit: Found a solution to my problem: You can set the WSL vEthernet Adapter to Bridge-Mode in Hyper-V Manager. Although this works, you cannot use it with GUIs.
my method to solve this problem: refresh ip in win10:hosts file
PermissionError: [Errno 13] Permission denied: '/mnt/c/Windows/System32/drivers/etc/hosts'
+1 for this issue. The workaround is not sufficient for the WSL experience in my opinion, as it creates a border between the two environments rather than working hand in hand as it does on WSL 1. Hope we'll get bridged network mode soon, as right now staying on WSL 1 provides a better experience for a couple of use cases (e.g. using adb, hosting local web servers etc.).
+1 for this issue. The workaround is not sufficient for the WSL experience in my opinion, as it creates a border between the two environments rather than working hand in hand as it does on WSL 1. Hope we'll get bridged network mode soon, as right now staying on WSL 1 provides a better experience for a couple of use cases (e.g. using adb, hosting local web servers etc.).
I can only agree with you as it truly does create a border between the host and the VM. Therefore I went back to WSL 1. I think we are all waiting for a proper bridged network mode. And proper support for GUI.
I'm struggling from days with it, I tried all workarounds without success. I've created a proxy that creates a tunnel to the WSL2 IP, but it's very limited in this case, we need a real bridge
RIP all hopes of improved WSL2 networking, with WSL2 going to release with W10 2004.
That really sucks. Maybe in future updates...
That really sucks. Maybe in future updates...
Btw, can you explain a bit what exactly you did when bridging the adapter in Hyper-V? Is it creating true bridge (becoming a workaround) or is it just for limited scope of situations. No GUI mentioned, I assume you did it via Powershell
Workaround: To put WSL2 into bridged Network Mode you have to:
Although it does activate a network bridge, it completely isolates the Subsystem from the Host. If the network adapter you choose to bridge to is not connected, it is not possible to use X-Server to work with a GUI. Follow these steps at your own risk, it may mess up your WSL since this is officially not supported. Furthermore, I was not able to share the connenction of the Bridge with the Host-System (even though i choose to when creating the bridge). Hope this helps you out :)
Issue
WSL 2 seems to NAT it's virtual network, instead of making it bridged to the host NIC. My goal is for a service running in Ubuntu in WSL 2 to be accessible from anywhere on my local network.
Issue Details
Your Windows build number:
Microsoft Windows [Version 10.0.18917.1000]
What you're doing and what's happening: Running
ipconfig
on my Windows 10 host machineRunning
ifconfig
in Ubuntu WSL 2Accessing 172.18.72.60 from my Window host does work, however this IP is not accessible from another system on my network.
What's wrong / what should be happening instead: I would expect to
ifconfig
in Ubuntu WSL 2 to have an IP address in the same network as my host machine.Searching the docs: The only detail I have found about WSL 2 networking is the following that notes that it will have it's own IP and that localhost is something that will be used for WSL 2 in the future. https://docs.microsoft.com/en-us/windows/wsl/wsl2-ux-changes This is fine, however I would like the IP WSL 2 is getting to be on my local LAN which means I need to configure the virtual NIC to be bridged.
Workaround
See @edwindijas https://github.com/microsoft/WSL/issues/4150#issuecomment-504209723