1

Problem

Can't connect to Windows X Server (VcXsrv) from WSL2 due firewall rules (sometimes it works, but sometimes it doesnt; it's very strange). Changing the firewall rules is not possible.

But any connection from Windows to WSL2 just works.

Idea

Is it possible to run a client/server pair as an intermediary service, to mirror any service on the WSL and make it accessible from the WSL?

------------Windows Host------------
| [Windows X Server] <--- [Client] |
-----------------------------↑------
                             |
----------------WSL----------v---------
| [XGui Client] ---> [Mirror service] |
---------------------------------------

1 Answer 1

1

But any connection from Windows to WSL2 just works

As background, it's important to understand that the WSL2 network is NAT'd behind a virtual, Hyper-V switch. It really is a separate layer 2 network from the Windows host.

Communication from Windows to WSL2 is considered outbound traffic from Windows, and inbound to WSL2, so no firewall rules are needed. By default, Windows allows most outbound traffic, and your Linux distribution running under WSL2 accepts most inbound traffic.

We can use that to our advantage in this case ...

Is it possible to run a client/server pair as an intermediary service, to mirror any service on the WSL and make it accessible from the WSL?

You have this tagged and that's a reasonable idea. I've used socat before in a similar way successfully, but (a) it's been a while, (b) I'd need to reproduce the recipe I used and tweak it to the X server, and (c) socat's options are kind of a pain to work through. It's powerful, but not necessarily easy to use.

So let me propose a built-in, much easier alternative -- ssh from Windows to WSL2 with X forwarding. It's really designed to do just this type of traversal.

  • Enable the OpenSSH client for Windows (see [doc] (https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?tabs=gui#install-openssh-for-windows). No need for the server in this case, since you'd have to open a firewall rule for that (which you've said you can't). It's already installed with Windows, you just need to enable the feature.

  • Enable the SSH server in your Linux distribution under WSL2. You don't mention which distribution you are running, but under Ubuntu (the default distribution), you need to (if I recall correctly):

    • Edit the sshd config: sudo -e /etc/ssh/sshd_config and choose a different port -- Let's say 2222.
    • Optionally enable PasswordAuthentication if you won't be using a key.
    • Ensure that X11Forwarding=yes, which it already should in Ubuntu.
    • Save and exit.
    • sudo service ssh start
    • If you get a message about host keys missing, try sudo dpkg-reconfigure openssh-server and then restart the service.
  • From Windows, start XLaunch (VcXsrv) with the default options + "Disable access control".

  • From PowerShell:

    $env:DISPLAY="localhost:0"
    ssh -Y -p 2222 wslusername@localhost
    

    Note: See this SU answer for why the localhost is critical in this case.

  • You should be logged into the WSL2 instance, with X forwarding in place. xterm, etc. should launch into VcXsrv.

3
  • Awsome! This works, thank you. I have some questions though: Is my assumption correct, that the ssh client, will automatically set an DISPLAY environment variable on the ssh host (wsl)? How is the connection working exactly? Does that correspond to my description in the question post? Thanks a lot!
    – Arber
    Aug 31, 2022 at 8:06
  • 1
    @Arber Glad it helped! I originally was going down a different path that was more similar to your description (forwarding port 6000), but X is a tricky beast. The ssh -X (or -Y) mechanism's are "smart" about X forwarding. For other types of services, I still use ssh, but with its "port forwarding" (rather than X-forwarding) arguments. See my answer here for an example (although in the opposite direction). The "port forwarding" is more like your original description than this one. Aug 31, 2022 at 14:26
  • 1
    And yes, ssh -Y automatically sets the DISPLAY variable inside the connection to WSL. You'll see that it has changed to something like localhost:10.0 to map it to the SSH server's "proxy". Aug 31, 2022 at 14:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .