Unlike WSL1 where you simply need to point the DISPLAY environment variable to localhost or 127.0.0.1, you must figure out a way to connect back to X410 in WSL2; when you start WSL2, it gets its own IP address and works more like an isolated Hyper-V virtual machine.

X410 provides the following connection methods for X-Window client apps running in WSL2 to connect back to X410 running in Windows.

TCP

Starting from version 3.0.0, X410 is automatically added to the Windows Defender Firewall inbound rules for full TCP public access while its installation. Hence you won't see the security alert message box mentioned in our previous version of this post. In version 3.0.0 and later, you can select inbound connections just for WSL2 and/or Hyper-V virtual machines within X410 and improve your system security.

Before setting up the DISPLAY environment variable, you first need to enable [ WSL2 ] option under [ X410 Settings ] » [ Access Control ] » [ TCP (IPv4) ]. You can also just enable 'Allow full public access' option, but when you enable that full access option, you're also allowing other programs running in any computer to connect to X410. If you just want to run X-Window GUI programs in WSL2, you should just enable the WSL2 option in X410 for security reasons.

Extract a Windows host IP from /etc/resolv.conf

When you start WSL2, Windows automatically creates a '/etc/resolv.conf' file that contains an IP address that points to the Windows host as a default nameserver.

This address may get changed when Windows is rebooted or WSL2 is restarted. So, you should dynamically extract an address from that file and assign it to the DISPLAY environment variable as shown below.

export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0




Please note that you can stop Windows from creating the /etc/resolv.conf file and manually assign your own nameservers. In such case, you cannot use the script shown above; you need to adjust the 'awk' command according to the changes you made to your /etc/resolv.conf file.

Extract an IP from 'ip route' Linux command

If your WSL2 distro has the 'ip' command, you can use its 'route' command-line switch to get the IP address for Windows host. The IP address for Windows host is reported as a default gateway in 'ip route' command and you can use that output for setting up the DISPLAY environment variable:

export DISPLAY=$(ip route | grep default | awk '{print $3; exit;}'):0.0





Enable 'Allow full public access'

When you enable 'Allow full public access' option, you can use any address that is reachable from WSL2. For example, if your Windows host has a static IP address, you can directly use that address for the DISPLAY environment variable. If your Windows host acquires an IP address from a DHCP server and that IP address changes periodically or whenever you reboot Windows, you can try using the computer name you assigned for your Windows along with a '.local' suffix. For example, if the name for your computer is 'mypc', try using 'mypc.local' as an address.

export DISPLAY=<computer_name_with_local_suffix>:0.0

As mentioned above, when you enable 'Allow full public access' option, you're also allowing other programs running in any computer to connect to X410. Hence, if you decide to use this option, you should also configure Windows firewall and protect your computer.

VSOCK

X410 also supports using VSOCK for connecting back to Windows host from WSL2. If you're having problems while using the TCP method (ex. X410 connections are severed or hanged after your computer is coming back from Windows sleep mode, Linux GUI apps are terminated when your Wi-Fi is switched to a different access point or network, Linux GUI apps become unresponsive after VPN is activated or turned off, etc.), try using the VSOCK method described below. As VSOCK is based on a different communication mechanism that focuses on directly connecting virtual machines and their host, you should get much stable experience that doesn't affected by the TCP/IP network changes in your Windows.

Please note that unlike Hyper-V virtual machines, you don't need to add any Windows registry entry.

Microsoft has not yet announced any official way to use the VSOCK for WSL2. Hence, we're using a heuristic method for locating the virtual machine for WSL2 and setting up X410 for the VSOCK. Starting from version 3.2.0, X410 also includes alternate codes that can more reliably detect WSL2 and set itself up for the VSOCK. However, those new codes require additional user privileges for accessing Hyper-V related API's in Windows. Hence, if you're having problems setting up the VSOCK for WSL2, try enabling those codes by adding yourself to the 'Hyper-V Administrators' group as outlined in the following post.

Add yourself to Hyper-V Administrators group and freely use Hyper-V related commands without becoming a full system administrator

Use socat for relaying X-Window data

X-Window client programs don't natively support connecting to an X-Window server via VSOCK. Hence, you need to use a relay background program that accepts data from your X-Window client programs and forwards them to X410 and vice versa.

You can use a popular utility program called 'socat' for the relaying data purpose. It should already be included in most software package systems such as apt. For example, the following command installs socat in Ubuntu:

sudo apt install socat




Once socat is installed, you can check its version by using its '-V' command-line switch:

$ socat -V
socat by Gerhard Rieger and contributors - see www.dest-unreach.org
socat version 1.7.4.1 on Jun 19 2021 02:10:43
   running on Linux version #1 SMP Wed Aug 25 23:20:18 UTC 2021, release 5.10.60.1-microsoft-standard-WSL2, machine x86_64
features:
  #define WITH_STDIO 1
  ...
  #define WITH_VSOCK 1
  #define WITH_PROXY 1
  ...



If you're using socat version 1.7.4.0 or higher, it already natively supports VSOCK and you simply need to use the following format for connecting to X410:

VSOCK-CONNECT:<cid>:<port>


<cid> should be '2' that points to your Windows host (VMADDR_CID_HOST) and <port> should be '6000 + <display_number>' (if you configured X410 to be a display number '0', it should be '6000'. For display number '1', it becomes '6001' and so forth). If you assigned '0' for the display number of X410 (this is the default display number when you install and start X410), you can execute socat as the following:

socat -b65536 UNIX-LISTEN:/tmp/.X11-unix/X0,fork,mode=777 VSOCK-CONNECT:2:6000 &



Once socat is properly executed, you should notice the 'X0' file in the '/tmp/.X11-unix' directory as indicated in the above example. That Unix socket file is used for accepting connections from X-Window client apps.

You should then set the DISPLAY environment variable to ':0.0'.

export DISPLAY=:0.0



If you're using an earlier version of socat that doesn't natively support VSOCK, you can still use it for the VSOCK data relay. The following socat command is equivalent to the VSOCK example shown above:

socat -b65536 UNIX-LISTEN:/tmp/.X11-unix/X0,fork,mode=777 SOCKET-CONNECT:40:0:x0000x70170000x02000000x00000000 &




When you use any network traffic relay program including the socat mentioned above, please note that such program will be created as a subprocess of the shell you're launching it from. Hence it will be automatically terminated when you close or exit the shell even if you push the relay program to background by appending an ampersand (&) sign as shown above.

If you want to have your relay program available to all WSL2 sessions and consoles even when you close the shell where it was started, you need to detach it from the shell. You can accomplish that by using nohup command or tools like daemonize.

Modify XCB (X protocol C-language Binding) library source codes

If you don't want to use any intermediate data relay program and have your X-Window client apps directly connect to X410 via VSOCK, you can try directly modifying XCB library source codes.

XCB library is commonly used in X-Window client programs for connecting to an X-Window server; XCB library is the one that actually decodes the DISPLAY environment variable and makes connections to the server.

You can find more information about replacing your existing XCB library with a modified version in the following post:

Transparently adding native support for VSOCK in X11 apps (patching libxcb)

Once you have the modified version in your WSL2 distro, you can simply use the following DISPLAY environment variable and have your X-Window client apps directly connect to X410 without using any background data relay program:

export DISPLAY=vsock/:0




Please note that if your program has its own routines for decoding the DISLAY environment variable, the modifying XCB library method shown above will not work. For example, if you enable the X11 forwarding feature in an OpenSSH client, you will get an error message similar to the following:

vsock/: unknown host. (Name or service not known)
Error: Can't open display: localhost:10.0

OpenSSH has built-in codes for decoding the DISPLAY environment variable, and it obviously doesn't recognize the vsock/ method since it's not in an official X-Window specifications.

In such cases, you need to use an intermediate data relay program like the ones shown in Option 1. But, fortunately, Windows 10 and later has a built-in SSH client that is a port of OpenSSH client. Hence you can transparently invoke that SSH client from WSL2 when you need X11 forwarding; you can simply execute ssh.exe instead of ssh. Using the built-in SSH client for X11 forwarding should actually give you better performance as it connects directly to X410; they're both natively running in Windows and there is no need for any virtual machine network traffic conversion.

For more information about using X11 forwarding with the built-in SSH client in Windows and X410, please read the following post:

Built-in SSH X11 forwarding in PowerShell or Windows Command Prompt

Share This Story, Choose Your Platform!