I'm using WSL2 on Windows 10.
My dev stack is using a local webserver (localwp or wamp) on the host OS.
I use WSL2 as the main terminal (SSH, Git, SASS, automation tools, ...).
What I need is a way to connect to my host services (MySql) from the WSL2 system using a server name instead of a random IP address.
It is already possible for the Windows host to connect to WSL2 services with "localhost". Is there a solution to do it the other way?
You should use hostname.local to access Windows from WSL2 because that will use the correct IP. Note that hostname should be replaced with the result of the hostname command run in WSL2.
You can check the IP by running ping $(hostname).local from WSL2.
You also need to add a firewall rule to allow traffic from WSL2 to Windows. In an elevated PowerShell prompt run this:
New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow
The command above should allow you to access anything exposed by Windows from WSL, no matter what port, however bear in mind that any apps you've launched get an automated rule created for them when you first launch them, blocking access from public networks (this is when you get a prompt from Windows Firewall, asking whether the app should be allowed to accept connections from public networks).
If you don't explicitly allow, they will be blocked by default, which also blocks connections from WSL. So you might need to find that inbound rule, and change it from block to allow (or just delete it).
See info here:
https://github.com/microsoft/WSL/issues/4585#issuecomment-610061194
Well, your title and your question body don't seem quite aligned.
The question title says "use localhost", but then in the body you say "using a server name."
Accessing the Windows 10 service via the name "localhost" from WSL2? Let's just go with "no". I can think of a possibility of how to make it work, but it would be complicated.
But I think the second is really what you are looking for, so a couple of options that I can think of for accessing the Windows host services by hostname in WSL2:
First, and hopefully the easiest, WSL2 supports mDNS (WSL1 did not), so you should be able to access the Windows host as {hostname}.local (where {hostname} is the name of the Windows host (literally, in bash, ping $(hostname).local, since the assigned WSL2 hostname is that of the host Windows 10 computer). That works for me. While I don't recall having to do anything special to enable this, this Super User answer seems to indicate that you have to turn it on manually.
The second option would be to add your Windows host IP to /etc/hosts. If your Windows IP is static, then you could just add it manually to /etc/hosts and be done. If it's dynamic, then you might want to script it. You can retrieve it from inside WSL2 via:
powershell.exe "(Test-Connection -ComputerName (hostname) -Count 1).IPV4Address.IPAddressToString" (and other methods) and then use something like sed to change /etc/hosts.
Add the following code to ~/.bashrc or ~/.zshrc, and then use winhost to access the host ip。
sed -i -e '/winhost/d' /etc/hosts
win_ip=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
win_host="$win_ip winhost"
echo $win_host >> /etc/hosts
The last time I was facing this issue,
I downgraded to WSL1, and all the connections started working perfectly.
You can use:
wsl --set-version Ubuntu 1
This is the easiest approach to fix all connection related issues in WSL2.
Related
(I've provided a simple working solution in response)
I recently moved from macOS to WSL 2. I have two node servers running within WSL 2 (Ubuntu distro). Each must be accessible through a custom hostname for development vs production purposes. I've had difficulty accessing the node servers via custom hostnames (ie set in some ../etc/hosts file) especially given WSL 2's dynamic IP that changes per WSL/pc 'boot'. How does one go about setting custom hostnames in WSL 2?
Scenario:
Each node.js app server (again running within WSL 2) must be accessed from the browser with the following urls/custom hostnames:
www.app1.com:3010
www.app2.com:3020
After searching around I have found the following relatively simple process works. I thought I'd share and save some time and headache for those new to WSL 2. Note, although I'm using node as the server stack, this process should more or less be the same for other app/web server stacks.
Note the following SE post is the basis of the solution. It's also worthwhile to examine MSFT's reference on WSL vs WSL 2. Also note, I haven't provided deep rationale on why these steps are required, why we might need custom hostnames, ipv6 options in ../etc/hosts, the meaning of 127.0.0.1, loopback addresses, WSL 2 and distro management, etc. These are subjects beyond the scope of this post.
Simple scenario:
nodeApp1: node application server with custom hostname: 'www.app1.com' on port 3010 (or whatever)
nodeApp2: node application serverwith custom hostname: 'www.app2.com' on port 3020 (or whatever)
Each node.js app server (again running within wsl 2) can be accessed from the browser with the following urls:
www.app1.com:3010
www.app2.com:3020
Two key items:
The correct etc/hosts files to be modified is on the Windows side (not WSL distro) at: C:\Windows\System32\drivers\etc\hosts (yes in Windows folders). This is a 'hot' update so no need for WSL 2 reboot. The content for this scenario is:
127.0.0.1 localhost
127.0.0.1 www.app1.com
127.0.0.1 www.app2.com
255.255.255.255 broadcasthost
::1 localhost www.app1.com www.app2.com
Please add C:\Users\"you"\.wslconfig with the following content (yes in Windows folders):
[wsl2]
localhostForwarding=true
Note: there's a reference to this in WSL 2 Ubuntu distro's /etc/hosts.
Also note, this requires WSL shutdown and reboot. Shutting down your terminal is insufficient. Also total machine boot is not
required. Simply run:
wsl --shutdown (in Powershell) or
wsl.exe --shutdown (within Ubuntu)
Then restart the Windows Terminal app (or any WSL terminal) to access the updated WSL 2 environment. The apps with custom urls/hostnames will now work in the browser permanently and WSL 2's dynamic IP is circumvented.
Background
I have a command-line application that I use to connect to a remote device on port 1234. I cannot change the port number, and I do not have access to the source to rebuild this tool. I'm currently working in a lab where all ports except SSH are blocked. To get around this, I create a tunnel, i.e.:
ssh -L 1234:remotehost:1234 sshuser#remotehost
Now, I can just point my CLI program at localhost:1234 to connect with my CLI tool to the desired host.
Problem
This CLI tool needs to run for about an hour straight, and I have about 200 remote hosts to test with it. I would like to parallelize this task. Unfortunately, I can only create a single tunnel on my local machine using port 1234.
Question
Is there a (trivial/simple/automated) way to jail/sandbox my CLI tool so that I can launch 100 instances in parallel (i.e. via a shell script) so that each instance "thinks" it's talking to port 1234? For example, does Docker or KVM provide some sort of anonymous/on-demand compute node feature that I could setup rapidly? I'd rather not have to resort to manually deploying and managing a slew of VirtulBox hosts via vagrant.
The simple answer is that you can use multiple IP addresses locally. Each local IP address on the client will allow you to create another tunnel. Currently, you are using localhost. But your client also has an IP address. You can prove my point by trying this syntax:
ssh -f -N -L 127.0.0.1:1234:remotehost1:1234 sshuser#remotehost1 # this is default
ssh -f -N -L <local-IP1>:1234:remotehost2:1234 sshuser#remotehost2 # specifying non-default value <local-IP1>
Now, you just need to figure out how to give your client multiple IP addresses (secondary addresses). Then you can expand this beyond 2 parallel sessions.
I've also added -f and -N to your ssh syntax to put ssh into the background (-f) and to not issue any commands.
Using -R tunnels in the past, I've found that I need to enable GatewayPorts on the server (/etc/ssh/sshd_config). In the case of -L , I don't see the need. However, the ssh man-page explicitly mentioned GatewayPorts associated with the -L function. You may need to play around a bit. I just tried this out on my Mac and I was able to get it going without any GatewayPorts considerations.
I have deployed a topology of VMs in a VNET on Azure. There is one jumpbox which has access to all these machines and is part of VNET. There are some 25 machines which this jumpbox provides access to.
I want to be able to simultaneously run commands and scripts on all the VMs through this jumpbox.
I installed cssh and it shows following error:
Can't find DISPLAY -- guessing unix:0' at /usr/share/perl5/App/ClusterSSH.pm line 1981.
Can't connect to display unix:0': No such file or directory at /usr/share/perl5/X11/Protocol.pm line 2264.
See this answer here: https://unix.stackexchange.com/a/76777
In essence:
Setup Public Key authentication between the jumpbox and your servers.
for host in $(cat hosts.txt); do ssh "$host" "$command" > "output.$host" ; done
pssh is probably the better tool for this job:
https://www.linux.com/news/parallel-ssh-execution-and-single-shell-control-them-all
cssh should also work, just don't do X11 stuff with it or make sure you have X11 forwarding enabled. Actually, i'm lying, i have no idea if it works without xterm.
Ive got 4 dev VMs for four projects (all VMware Player VMs w/ubuntu 15.04 host) where each is running VNC (ports 5900, 5901, 5902, 5903) respectively.
I downloaded noVNC and saved to /var/www/html (my apache2 server on same host). Based on the ReadMe I then ran on my terminal
./utils/launch.sh --vnc localhost:5900
I received a missing websockify error, so downloaded it and placed it into the util folder. I then ran the same command and it worked! The terminal told me to Navigate to a url and sure enough I could control my VM.
However -- I'm wondering how can I use noVnc to access all 4 VM's? Is there some simple way to extend the port to a range like in iptables or firewalld?
./utils/launch.sh --vnc localhost:5900-5903
Okay, Ill answer for myself here in case it helps someone in the future...
First, create a token file where each line has a nickname, ip address, and port.
I created a file named token.list where each line looks like:
localhostnickname1: localhost:5900
localhostnickname2: localhost:5901
...
Then I use my terminal to go into the websockify folder so I can see the run file. I issue it the command:
./run --web /path/to/noVNC --target-config /path/to/token.list localhost:6080
Finally, I open my web browser and go to :
http://localhost:6080/vnc_auto.html?path=?token=localhostnickname1
Where localhost1 is the nickname of my first server on the first line of token.list
This link was my reference. If you want to serve this outside of localhost -- change the parameter localhost:8060 from localhost to an IP
I am using Cygwin X and Debian. I can forward my X session via SSH but what happens is that I seem to loose the display forwarding in the X session once in a while (from Cygwin to Linux). So i am guessing that that is an imnplementation thing with Cygwin because I never loose X11 display in the same ssh session when I use Linux to Linux.
This also happens when a X11 forwarded app tries to fork another process lets say I run Thunderbird and I click on a url inside an email. Naturally Thurderbird will try to start the default web browser but it is not doing it with Cygwin X server and here is the message I get when SSH session gives up the display for various reasons that I am not able to know.
"Error: cannot open display: localhost:10.0"
The other issue is that since the ssh gives up the display variable, I have to restart my ssh session to get it working which also kills other apps that I might be running during the ssh session.
Anyway after struggling with this for a while I am thinking that I want to be able to open my apps on another display without using ssh forwarding. I am using it internally and it is almost a closed lan so I am not worried about the security for now. I just want to be able to run the app on the Linux then see the app on the Pc that is running Cygwin.
I tried basic DISPLAY variable thing like "export DISPLAY=MY_CYGWIN_PC_IP:0.0" (on Linux Pc) but it does not work.
So I am wondering about how I can achieve this. What are the proper settings to achieve what i need?
Your direction was OK. export DISPLAY is what you want. But it is not enough.
On the target, you need to type
xhost +from.where.the.windows.are.coming.com
It gives the X server the permission to allow remote windows from this computer.
Beware, it is not really secure! A possible attacker could not only windows shown by you, but even control your mouse/keyboard. But for simple solutions, or if you can trust the remote machine and the network between you, it may be ok.
If not, there is an advanced authorization, based on preshared keys. It is named xauth. Google for xauth.
The Xorg server has an option to disable the remote windows, and there are distributions, (f.e. ubuntu!) who turn this option by default on. You can test it - if you can telnet to the tcp port 6000, it is allowed.
If you are using ssh -X, don't. Use ssh -Y
Cygwin XWin server randomly loses connection
Basically to work as old times , we need enable xdmcp on display manager and use X11 , Xwayland seems to me that doesn't work either.
sddm doesn't support xdmcp , but gdm does , you need edit /etc/gdm/custom.conf and add
[security]
DisallowTCP=false
[xdmcp]
Enable=true
xhost + ip_of_remote_computer
echo $DISPLAY (the number of the display usually :0 or :1)
after you can verify :
netstat -l | grep xdmcp
udp 0 0 0.0.0.0:xdmcp 0.0.0.0:*
lsof -i :xdmcp
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
gdm 862335 root 12u IPv4 71774686 0t0 UDP *:xdmcp
on remote host :
export DISPLAY="ip_of_server:0" (see if is 0 or other number in echo $DISPLAY on server mention above )
xclock &
References:
http://www.softpanorama.org/Xwindows/Troubleshooting/can_not_open_display.shtml
https://tldp.org/HOWTO/html_single/XDMCP-HOWTO/
https://wiki.archlinux.org/title/XDMCP