How to set up working X11 forwarding on WSL2 [closed]
Asked Answered
M

23

190

When moving from WSL1 to WSL2 many things change; apparently this applies to X11 forwarding as well.
What steps do I need to make in order to use X11 forwarding with WSL2 on Windows 10 as I did with WSL1?

Maddiemadding answered 8/4, 2020 at 21:49 Comment(3)
Tools commonly used by programmers must be taken with some level of common sense. It's well established that not all WSL2 questions are on-topic here, and this one should never have been reopened. We have sister sites for this reason, and Super User is much better for this. It might even be on-topic on Ask Ubuntu (assuming that distro is involved) or the Unix & Linux Stack. But no, this is not a question about "specific coding, algorithm, or language problems.'Wintertide
This answer helped me - #66768648Karlsbad
I would stongly suggest that it is a rarity for a non-programmer to even be aware of WSL. The X11 forwarding is not on topic, but for the qualification if the tool tool to be forwarded. (A certificate tool, say). Saying that a true programmer would rely upon the command line is crap, but it is also valid to recognise that this is a VirtualBox scenario. There are workarounds.Genipap
M
245

TL;DR:

Add the following to your ~/.bashrc:

export DISPLAY=$(ip route list default | awk '{print $3}'):0
export LIBGL_ALWAYS_INDIRECT=1

Enable Public Access on your X11 server for Windows.*

Add a separate inbound rule for TCP port 6000 to the windows firewall in order to allow WSL access to the X server, as described by the wsl-windows-toolbar-launcher people.


As pointed out by WSL_subreddit_mod on reddit and as you can read in Microsoft's documentation on WSL2, the WSL2 architecture uses virtualized network components. This means that WSL2 has a different IP address than the host machine. This explains why the X11 forwarding settings of WSL1 cannot simply be transferred to WSL2.

On the Ubuntu Wiki page about WSL you can already find a configuration adapted for WSL2 under Running Graphical Applications. A similar configuration is also suggested by the above mentioned Reddit User, who also contributes another part of the solution: Enable Public Access on the X11 server under Windows.

This means add the following to your ~/.bashrc:

export DISPLAY=$(ip route list default | awk '{print $3}'):0
export LIBGL_ALWAYS_INDIRECT=1

And Enable Public Access on your X11 server for Windows.*

The most important part to enable X11 forwarding for WSL2 on Windows 10 is still missing: the Windows firewall blocks connections via the network interface configured for WSL by default.
A separate inbound rule for TCP port 6000 is required to allow WSL access to the X server. After the rule has been created, as described by the wsl-windows-toolbar-launcher people, the IP address range can be restricted to the WSL subnet in the settings of the newly created rule, under Scope: 172.16.0.0/12.

*: If you use VcXSrv you can enable public access for your X server by disabling Access Control on the Extra Settings:
Disable access control VcXSrv
Or by calling vcxsrv.exe directly with the ac flag: vcxsrv.exe -ac as pointed out by ameeno on the github issue.

Alternatively this SO answer shows how to share keys via .Xauthority files, leaving you with intact access control.

Maddiemadding answered 8/4, 2020 at 21:49 Comment(28)
I just tested your solution. Even with the "Disable access control" flag checked, I had to allow public access via Windows Defender ("Allow apps to communicate through Windows Defender Firewall"). However, I didn't have to add an extra inbound rule.Tovatovar
@Tovatovar The extra inbound rule should be added to avoid allowing access for all public networks as this can cause security issues.Maddiemadding
@Sören what exactly isnt working? If you could provide further information I might be able to help you.Maddiemadding
I made some slight modifications and got it to work. First, I used MobaXterm instead of VcXSrv since it seems more reliable from a firewall perspective. Second I used the following exported ENV variables. Key difference is I don't rely on /etc/resolv.conf. export DISPLAY=$(ip route | awk '/default via / {print $3; exit}' 2>/dev/null):0 export LIBGL_ALWAYS_INDIRECT=1Ecclesiastical
I think the IP is 172.17.0.1 in any case, now.Dominicdominica
@Dominicdominica hey, can you please provide an url to where you have this information from?Maddiemadding
I have just seen it on my device but I have not verified it.Dominicdominica
Actually I did some research and couldn't find anything about the IP of the wsl2 being 172.17.0.1 in any case. I did also check regularly the IP of my wsl2 which indeed sometimes is the above mentioned one but also quite often happens to be another one. So NO, the IP is NOT 172.17.0.1 in any case.Maddiemadding
The internal firewall is the issue missing in a lot of the other online discussions on this. Thanks including in your solution.Outpouring
@NicolasBrauer When using /nameserver which server name should we be adding?Sphenogram
@Sphenogram I don't quite understand what you mean. You do not need to add anything, just include the export in ~/.bashrc as it is.Maddiemadding
@NicolasBrauer - Thank you, I figured it out, but at the time, thought that nameserver was a stand in for the name of the users server (and so had to be replaced).Sphenogram
For Xming I had to disable Access Control using XLaunch (source: lanforge.wordpress.com/2018/04/06/setting-up-xming) otherwise I kept getting "No protocol specified" and "Error: Can't open display".Sension
To tighten the firewall even more I set the Scope settings in the Inbound Rule (Windows Defender Firewall) to 172.23.0.0/16 (ip address from my /etc/resolv.conf) in both Local and Remote IP Address settings.Sension
My /etc/resolv.conf contains several nameserver entries, none of which is my current IP-address, so this breaks. It appears there is assumptions about how this works.Olnay
The awkcommand on this page to put the host's IP into the DISPLAY variable doesn't work for me. What does work is export DISPLAY=127.0.0.1:0. Of course, this needs a running loopback device. I wonder, why so many answers try to figure out the host's IP when there is such a simple solution?Crowder
Why using awk when sed is good enough: sed -n 's/nameserver //p' /etc/resolv.conf | head -n 1Conundrum
For authorization, you could also generate an ~/.Xauthority file by running xauth generate $DISPLAY . in WSL while VcXsrv is running with the authorization control disabled (-ac). Then do cp ~/.Xauthority /mnt/c/Users/<your login>/, and next time you start VcXsrv, use the -auth C:\Users\<your login>\.Xauthority parameter instead of -acDottiedottle
I originally set it up using these steps. However my system updated to Windows 11 and it wasn't working anymore. 11 has native support and doesn't need an XServer or any special config. I just ran though the steps here learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps updating WSL (wsl --update in Powershell) and updating my video driver (I used GeForce Experience to update). Then removed the DISPLAY override and everything worked great!Vienna
@jonespm, YES!, I'm anxious for Window 11, primarily because of the WSL updates. Have you installed the preview or was it already available to you? For me the site states that 'Windows 11 isn’t here yet' :-(Hambrick
@marcus I was in the Insiders slow ring (beta channel) and my computer automatically updated to 11 a few weeks ago. I like it so far and was happy to see this unexpected addition!Vienna
I found sometimes WSL switch also allocates 192.160.0.0/11 so add that to your scopeMolina
I tried pursuing the access control route out of curiosity. I found an easier way than using xhost, vcxsrv will load C:\Program Files\vcxsrv\X0.hosts as its defaults, so maybe make a startup script to add the WSL IP to that.Molina
I don't see any windows with ubuntuBorchert
@user924, assuming you are running Windows 11, please, refer to learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps. One of the prereqs is vGPU ready drivers.Hambrick
checking the logs I found that I had to add my WSL IP is the xo.hosts. after this it worked for meCrab
You can also use ip route list default | awk '{print $3}' to extract your windows IP in WSL.Guanabana
@Windel, perfect! Having to resort to resolv.conf did not sound good to me. I'll edit the proposed answer with this approach.Hambrick
N
62

For some people who allowed only for private networks like me,

although they Should have been Both Ticked

enter image description here

It should have stop signs on Windows Defender firewall

enter image description here

Double click it and allow the connection for both private and public,

enter image description here

So all the 4 items should be ticked green.

Then the above answer from @NicolasBrauer was working for me.

Like disabling the access control when you XLaunch and

export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=1
Noellenoellyn answered 30/7, 2020 at 13:39 Comment(5)
For whom is interested in a general tips for WSLNoellenoellyn
The accepted answer's link to firewall changes shows some more details about limiting access to port 6000 and IP range 172.16.0.0/12 (which is good) but it is not specific to a program (like this answer). For MobaXterm my exe name was xwin_mobax.exe. They also didn't really explain how to navigate to the correct place in Windows Defender Firewall. These extra pictures helped complete the puzzle.Aubree
Here's another place to toggle the firewall setting for VcXsrv. The security alert did not show up in my case.Balderdash
remember to update that rule, when the app is updatedTrichome
thanks, the firewall was blocking connectionUndine
O
53

I come up with a solution using vxcsrv on windows 10, as others pointed out. Also working on windows 11.

XServer Windows - WSL1 & WSL2:

Install X-Server Windows

https://sourceforge.net/projects/vcxsrv/

Set Display forward in WSL Distro

Configure Display:

  • If you running WSL1:
export LIBGL_ALWAYS_INDIRECT=1
export DISPLAY=localhost:0
  • If you running WSL2:
export LIBGL_ALWAYS_INDIRECT=1
export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0

and then (install x11-apps):

sudo apt update
sudo apt install x11-apps

Start XLaunch on Windows

  • Multiple Windows
  • Start no client
  • disable Native opengl
  • enable Disable access control

Test it

In wsl: enter xcalc - Calculator should open in Windows10

If everything worked

And you want to persist the settings in your wsl distro. Store them in your ~/.bashrc.

sudo nano ~/.bashrc

Copy the two lines (from Set Display forward in WSL Distro - Configure Display) to the end and save it.

Add it to autostart

  1. Run Dialog see Start XLaunch on Windows
  2. Save configuration
  3. Press Windows + R
  4. Enter: shell:startup
  5. Copy saved configuration: *.launch (Generated in step 2) to this folder (step 4)

Now the XServer will be started with windows startup.

I’m using it for ROS. Works for me.

My XServer isn’t available over internet so its okay to disable access control.

Oversleep answered 15/3, 2021 at 20:29 Comment(6)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.Bentonbentonite
It doesn't work.Liebman
What is not working. Do you checked the boxes in the windows alert (like described here: https://mcmap.net/q/134710/-how-to-set-up-working-x11-forwarding-on-wsl2-closed)Oversleep
the part "Start XLaunch on Windows" with access control helped meGarvy
this works perfect, if you are having a problem try turning off your network firewallKara
Can confirm this works on a clean installation of Windows 11 without having to install VcXsrv. In my case, I was missing x11-apps and the environment variables.Stearoptene
S
27

Using /etc/resolv.conf nameserver won't work for me since I disabled resolv.conf generation in /etc/wsl.conf (I have a custom resolv.conf).

Ultimately you want the WSL2 host IP address, which should also be your default route. Here's my ~/.bashrc entry for my Debian WSL2 distro:

export DISPLAY=$(ip route | awk '/^default/{print $3; exit}'):0
Smashup answered 25/7, 2020 at 19:49 Comment(2)
ip route | wc -l 151 how is this supposed to work? or in other words: whats the route we are looking for. a single route is somewhat rare these days....Pettifer
i love you! lifesaverKnisley
S
26

How to Setup X11 forwarding in WSL2

This answer assumes that you already have a working XServer and PulseAudio configuration running on your Windows host because you already were using WSL1. (You also may have to add the -ac parameter to the command line to get your XServer of choice to work with WSL2.)

The way that I do this, and to ensure that I get X11 forwarding no matter whether I am using a static IP address or DHCP on the Windows host, or even whether my hostname or network location changes, I add the following to my ~/.bashrc file:

# Get the IP Address of the Windows 10 Host and use it in Environment.
HOST_IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r')
export LIBGL_ALWAYS_INDIRECT=1
export DISPLAY=$HOST_IP:0.0
export NO_AT_BRIDGE=1
export PULSE_SERVER=tcp:$HOST_IP

After doing the above, no matter what my Hostname or IP address of the Host is, it will be placed in the environment each time a BASH session is started in WSL2. Test it by running firefox from the command line and watch a YouTube video. You should be able to hear the sound as well as see the app itself to watch the video. Test by launching other GUI apps from the command line in addition.

What it does: It uses the host command to pull the IPv4 Addresses associated with the Hostname from the output, greps the address that matches the line that contains your Windows Host IPv4 address, strips the rest of the information except for the IP Address, and then awks that and prints it into the variable, with the output trimmed. This then is used to provide the necessary IP address as a string for use in the environment variables that allow for forwarding of X11 and sound output.

Hopefully it works for you if the other methods don't work for you (as they didn't for me).

Most CLI apps can be run either from the BASH Prompt or from Windows Terminal. If you want to make a shortcut, most CLI apps can be set up like either of the following examples (no need for X11 forwarding in such cases except apps like Links2):

C:\Windows\System32\wsl.exe -e htop
C:\Windows\System32\wsl.exe lynx

If you want to create desktop shortcuts for Linux GUI apps, unless you can get the environment variables from your ~/.bashrc file to be used before launching the programs, you will have to create shortcuts using the following template, and put the program name in place of {yourprogram}:

C:\Windows\System32\wsl.exe LIBGL_ALWAYS_INDIRECT=Yes IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') DISPLAY=$IP:0.0 PULSE_SERVER=tcp:$IP {yourprogram}

You do not have to place the full command line for many programs. For PERL-based programs or Python-based programs, you sometimes will have to add the path for PERL and PYTHON, as well as your program's full path, to run such GUI programs in Linux using WSL2. For one of my perl programs, I have to do it this way:

C:\Windows\System32\wsl.exe IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') ; export LIBGL_ALWAYS_INDIRECT=Yes export DISPLAY=$IP:0.0 ; cd /mnt/c/Users/{yourusername}/Desktop ; /usr/bin/perl ~/wget-gui.pl

You may have to experiment a bit to get some apps working properly. For example, you might need to dbus-launch an app, and will need to add that command to the shortcut just before the program name.

C:\Windows\System32\wsl.exe LIBGL_ALWAYS_INDIRECT=Yes IP=$(host `hostname` | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r') DISPLAY=$IP:0.0 PULSE_SERVER=tcp:$IP dbus-launch --exit-with-session gedit

And you might have to use a shorter variable name in some circumstances. Some apps just won't work well, if at all, but this situation is improving over time. Also, don't try to run the above from a Windows Command Prompt or from PowerShell. It will throw errors about 'grep' not being recognized as an internal or external command, etc.

Following is a screenshot of a few Linux GUI apps running on my Windows 10 system, with working X11 forwarding on WSL2.

enter image description here

Swiss answered 5/1, 2021 at 10:8 Comment(5)
Finally! That's the only solution that helped, tried everything. Just copy/pasted the first block of commands and voila! Thanks!Topazolite
You're welcome! Glad that it is working for you. It adds a second or two processing time but that is a small price to pay for a working configuration that is IP address agnostic.Swiss
I use this in wsl2 for .bashrc and this work for me now.Rina
Thank you! this is the only solution that worksPirouette
Thank you mate! Now I have my x-server working properly :)Vulva
F
12

Copied my answer from this github issue.

The idea is to use the ability to communicate over stdio.

Prerequisite

  • Just so we can use socat in Windows host, you need a distribution running WSL1. I am sure you can do this in powershell but I didn't have time to research this. Maybe someone can write a stdio->tcp redirector in powershell, then we wouldn't need to have 2 WSL distros.

How to forward X-server connection

  1. Have your favorite X server running on Windows. By default they would listen to port 6000.
  2. In the WSL2 distro, run the following command in the background (ubuntu is the name of the WSL1 distro with socat installed):
mkdir -p /tmp/.X11-unix/
socat UNIX-LISTEN:/tmp/.X11-unix/X0,fork EXEC:"/mnt/c/Windows/System32/wsl.exe -d Ubuntu socat - TCP\:localhost\:6000"

Basically this sets up a tunnel from the normal X unix domain socket into the host's port 6000.

How to forward any TCP connection back to host

Let's assume there is a tcp service running at port 5555 on Windows. In the WSL2 distro, run the following command in the background (ubuntu is the name of the WSL1 distro with socat installed):

socat TCP-LISTEN:5555,fork EXEC:"/mnt/c/Windows/System32/wsl.exe -d ubuntu socat - TCP\:localhost\:5555"

How to forward any TCP connection from host into WSL2

This is simply doing the same thing, but in the opposite direction. You can run the following in your WSL1 distro:

socat TCP-LISTEN:5555,fork EXEC:"/mnt/c/Windows/System32/wsl.exe -d ubuntuwsl2 socat - TCP\:localhost\:5555"

Performance

On my PC, it can handle up to 150MB/s of data so it's not the fastest but fast enough for most applications.

Fiasco answered 22/8, 2020 at 15:10 Comment(1)
YEAH! thats the way to go. I added it to my startx script: #!/bin/bash # start Xming X11 if not running if /mnt/c/Windows/System32/tasklist.exe | grep -q Xming.exe; then echo found X server else echo did not found Xserver - starting it /mnt/c/Program\ Files\ (x86)/Xming/XLaunch.exe -run '\Users\user\Desktop\config.xlaunch' & # also start the X11 pipe mkdir -p /tmp/.X11-unix/ socat UNIX-LISTEN:/tmp/.X11-unix/X0,fork EXEC:"/mnt/c/Windows/System32/wsl.exe -d Ubuntu-18.04 socat - TCP\:localhost\:6000" & echo wait a sec sleep 1 fiPettifer
F
7

For those who may work with simulation engines such as ROS/Gazebo, Unity and so on, another configuration is needed.

Add these to ~/.bashrc:

export DISPLAY=$(awk '/nameserver / {print $2; exit}' /etc/resolv.conf 2>/dev/null):0
export LIBGL_ALWAYS_INDIRECT=0

Be sure to enable both Public Access and Private Access for your X11 server in windows. Also disable any access control your X11 server supports.

If you use VcXSrv uncheck Native opengl. Final config for VcXSrv will be like:

enter image description here

Alternative good X11 servers with less difficulties are X410 and MobaXterm. For some details about this configuration refer here and here.

Fronnia answered 19/7, 2020 at 7:55 Comment(0)
M
6

Windows 11, and Windows 10 22H2 (build 2311) and later, include WSLg. It just works™ 🎉

Drivers for vGPU (Intel AMD Nvidia) are recommended.

The "System Information" App will tell you your current build number.


Note: WSL1 is not compatible with WSLg. New WSL2 instances will just work™.

Existing WSL2 systems will need to be "updated":

  1. In administrative PowerShell: wsl --update
  2. wsl --shutdown to force a restart of the WSL

Don't forget to remove any other modifications to DISPLAY that you may have made.

Proof that it works

Mucker answered 23/8, 2021 at 20:8 Comment(4)
#61860708Numeration
It just works but then it glitches.. Now I can't seem to get XLaunch working in tandem with WSLg when I need to do actual work.. :( Any idea how to get XLaunch working with WLSg at the same time, or how to disable WLSg so XLaunch will work like it did before?Nickelic
This maybe?Mucker
WSLg works in Windows 10 22H2 build 2311 and later. Install all Windows updates and it comes as part of WSL2. If your update doesn't get you all the way to build 2311 you may need to install KB5020030 to get you up to a build that allows the WSL2 version of WSL2 to be installed.Ringdove
S
3

I don't know if that's specific to my configuration but these solutions don't work on my computer. They return the address 192.168.0.254 which is my gateway and not my host computer.

To make it work I had to use the following on my Ubuntu/WSL2 :

export DISPLAY="`ip -4 address | grep -A1 eth0 | grep inet | cut -d' ' -f6 | cut -d/ -f1`:0"
Sec answered 30/6, 2020 at 19:12 Comment(0)
M
3

You can get connect to the X server without disabling access control on the server. You use xauth on the server to generate a cookie, then load it into Linux with xauth on the Linux side. You can get the server IP from /etc/resolv.conf. The following is in my .bashrc:

k=$('/mnt/c/Program Files/VcXsrv/xauth.exe' -f 'C:\Users\xxx\Documents\scratch.xauth' -i -n -q 2>/dev/null <<EOF
generate localhost:0 . trusted timeout 604800
list
quit
EOF
)
if [ -n "$k" ]
then
        export DISPLAY=$(sed '/^nameserver/ {s/^nameserver\s\s*\([0-9][0-9.]*\)[^0-9.]*$/\1/;p;};d' /etc/resolv.conf):0
        xauth -q add $DISPLAY . ${k##* }
        export LIBGL_ALWAYS_INDIRECT=true
fi
unset k
Malayalam answered 13/1, 2021 at 21:37 Comment(3)
For Cygwin/X I didn't need to generate the cookie, instead I used k=$(/mnt/c/cygwin64/rootfs/bin/sh.exe -c '/bin/xauth -n list'|grep "^$DISPLAY") to get the existing cookie. I moved the export DISPLAY=... line above that line. I also needed to add a .xserverrc file containing exec /usr/bin/XWin -listen tcp "$@" to the cygwin home directory (echo 'exec /usr/bin/XWin -listen tcp "$@"' >> ~/.xserverrc in cygwin) to enable tcp access for the cygwin x server.Sonatina
@TS can you elaborate on how you got Cygwin/X working with WSL2 as a new answer? I have VcXsrv working, but I've heard Cygwin/X may solve some of the graphical glitches I'm having. Unfortunately, I was unable to get any GUI apps to launch from the WSL2 terminalHypomania
Thank you for posting how to do this correctly. All the other answers are fairly dangerous, as an X server that allows unauthenticated connections will allow not only mischief but also makes it trivial to attach a keylogger—just do xinput list to get the keyboard ID, then xinput test <n> to see all the key events.Prothalamion
B
2

I used the following bash to set display:

export DISPLAY=$(powershell.exe -c ipconfig | grep -A4 WSL | tail -1 | awk '{ print $NF }' | tr -d '\r'):0
Bourassa answered 10/10, 2020 at 6:30 Comment(1)
In WSL2 this gives the wrong IP address for the X Server. Works fine in WSL1 but not in my WSL2 configuration. When using WSL2, you don't want to forward X11 to the IP address of the running WSL instance. It is running on the Windows host, so you need the host IP address rather than the WSL address. This works in WSL 2, for any IP address: export DISPLAY=$(host hostname | grep -oP '(\s)\d+(\.\d+){3}' | tail -1 | awk '{ print $NF }' | tr -d '\r')Swiss
T
2

The solution from https://github.com/microsoft/WSL/issues/4793#issuecomment-588321333 uses VcXsrv as the X-server, and it is where I'm getting this answer (slightly edited for readability). Note that the original is being updated by its author, so don't forget to re-check.

To make it work:

  1. On Windows, with the following, change E:\VcXsrv to where your installation is, and save it as xxx.bat in your Windows startup folder, e.g., C:\Users\Me\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup, and you can make it run when boot if you like:
@ECHO OFF

REM Start WSL once to create WSL network interface
wsl exit

REM Find IP for WSL network interface
SET WSL_IF_IP=
CALL :GetIp "vEthernet (WSL)" WSL_IF_IP
ECHO WSL_IF_IP=%WSL_IF_IP%
setx "WSL_IF_IP" "%WSL_IF_IP%"
setx "WSLENV" "WSL_IF_IP/u"

REM Change E:\VcXsrv to your VcXsrv installation folder
START /D "E:\VcXsrv" /B vcxsrv.exe -multiwindow -clipboard -nowgl -ac -displayfd 720
GOTO :EOF



:GetIp ( aInterface , aIp )
(
    SETLOCAL EnableExtensions EnableDelayedExpansion
    FOR /f "tokens=3 delims=: " %%i IN ('netsh interface ip show address "%~1" ^| findstr IP') DO (
        SET RET=%%i
    )
)
(
    ENDLOCAL
    SET "%~2=%RET%"
    EXIT /B
)
  1. In WSL, edit ~/.bashrc file to add following lines:
export DISPLAY=$WSL_IF_IP:0
unset LIBGL_ALWAYS_INDIRECT

That's all to make WSL2 work automatically. The idea is to get the private LAN IP of WSL interface on Windows, and use Environment variable to pass it to WSL. WSL then updates this LAN IP to DISPLAY for X-Server connection.

The clipboard works well, too, with this setup. I tested this with a WSL2 install of Ubuntu 20.04 LTS.

Tabernacle answered 27/11, 2020 at 15:41 Comment(3)
Please don't disable the firewall entirely for the wsl interface.Maddiemadding
@Maddiemadding I removed that part, I think.Tabernacle
Thank you very much, tried several other things but got some problems, this is working fine !Subirrigate
P
2

I do not want to mess with public access to X server and Windows firewall. My solution is using ssh with X forwarding (works for VirtualBox as well). Additionally, WSL auto-forwards from host to guest listening sockets, so I don't care which IP is actually assigned to guest.

So the steps are these:

  1. Install VcXSrv. Run it with all defaults but set Display number to 0 (-1 will choose 0 if no X instances are already running). Do not start any client in it (this gives a benefit that you can start more apps on the same X server instance).
  2. Open WSL and configure ssh server. For me it's as simple as sudo service ssh start. Create a Windows shortcut with command line: wsl sudo service ssh start.
  3. Install Git for Windows. I actually use it only because its version of ssh is capable of going into background with ssh -f. Windows version of ssh is buggy on this feature, otherwise it's suitable without going to background or with ssh -n.
  4. Configure passwordless login from Git-Bash to the guest. ssh [email protected] should work at this point, because the host port is forwarded to the guest.
  5. Verify X forwarding works from Git-Bash: DISPLAY=127.0.0.1:0 ssh -Y [email protected] xeyes. I think xeyes is installed with each X distribution.
  6. Install file manager or terminal of your choice in WSL. For example, pcmanfm. Create a Windows shortcut: "C:\Program Files\Git\git-bash.exe" -c "DISPLAY=127.0.0.1:0 ssh -Y -f [email protected] 'bash -l -c pcmanfm >/dev/null 2>&1'". Here bash -l flag helps setting up environment which may or may not be important depending on apps you run.

Of course, I can do the same without git-bash by using VcXSrv built-in ssh client but it requires converting ssh keys to PuTTY format and I had git-bash already installed. Also, with built-in client display reuse did not work for me.

Paradisiacal answered 25/2, 2021 at 23:17 Comment(0)
W
2

2021 answer for Windows 10

Check this answer if getting IP from resolv.conf doesn't work.

Find your Windows IP address using following command in your WSL2 (yes, .exe file inside linux):

ipconfig.exe 

Use command below to set display (fill YOUR_IP_ADDRESS with your IP):

export DISPLAY=YOUR_IP_ADDRESS:0

Check if your GUI app works correctly.

Automation can be little different for each case but I'll give example:

ipconfig.exe | grep 'IPv4 Address' | grep '10\.' | cut -d ":" -f 2 | cut -d " " -f 2 

Explanation: I found all IPv4 addresses (3 IPs in my case). I know that my IP starts only from '10.' so I chose this line using second grep. Next I processed whole line to get the IP only.

Wen answered 8/9, 2021 at 14:47 Comment(0)
O
1

I would rather set up an ssh server in the guest, install an X11 server like Xming on the host and connect to localhost via putty with X11 forwarding. No fiddling with firewall rules, host IP is not required.

Occidentalize answered 10/10, 2020 at 9:6 Comment(0)
A
1

I'm not sure why but none of the above answers worked for me. I'm running on an ROG Zephyrus with AMD and Nvidia graphics which I'm sure caused issues.

The firewall settings described by whme are important, but the linux environment variables did not work for me. I had several entries in the config file labeled as nameserver, non of which allowed connections.

I ended up setting them to:

export DISPLAY=$HOSTNAME:0.0
export LIBGL_ALWAYS_INDIRECT=

I'm using VcXsrv as the X-server. I had to also set the parameters to -nowgl

Automatism answered 27/10, 2020 at 5:20 Comment(3)
Unfortunately this is not working for me to start git citoolsCloutman
$HOSTNAME eventually resolves in WSL2 as 127.0.0.1 and as the network is virtualized, it's not the localhost of the windows host, it's the localhost of the wsl2 instance where the X11 server is not listing.Bodwell
Nothing on this page worked for me :( crrazy stuff, win 10 wsl2, nothing extraordinareRural
N
0

I found there is a official document fro Ubuntu which is comprehensive for your reference. As we know, this tip will work on Debian/WSL2 as well. https://wiki.ubuntu.com/WSL

Thanks for Kennyhyun and other people's shares. All of them are some how or some way works on my computer to enable X11 server on WSL2 hosted on Windows10. Since the WSL2 is as a VM not longer be the same infrastructure as WSL1 anymore. It did take me some time to go through it.

Please let me add something briefly about how to make app on WSL2 show up.

  1. run 'ip route' on WLS2 terminal.

    ip route default via a.b.c.1 dev eth0 a.b.c.0/20 dev eth0 proto kernel scope link src x.x.x.x

  2. add this IP address of the "dev eth0" into "export $DISPLAY="

    export $DISPLAY=a.b.c.1:0.0

  3. Run xming server. Then you could run the APP which is running on the WSL2 Linux. But for the X11, you may need to follow the document from Ubuntu.

Narco answered 13/10, 2020 at 16:14 Comment(0)
R
0

I found a solution that worked for me, following: Set Graphics on WSL2

1.      Start ssh service
1.1.   Open WSL
1.2.   Type: sudo service ssh start
2.      Get Windows (WSL net) IP
2.1.   Open Powershell
2.2.   Type: (ipconfig | Select-String -Pattern 'WSL' -Context 1, 5).Context.PostContext | Select-String -Pattern 'IPv4'
2.3.   Get the received IP
3.      Set environment variable
3.1.   In WSL2 terminal type: export DISPLAY=172.23.64.1:0.0 with the IP of the windows entity (2.3) instead of the place holder
4.      Launch Xming
4.1.   Open Xlaunch and go with the defaults In Specify parameter settings: Check No Access Control
5.      Good luck!

Following link: https://docs.google.com/document/d/1ao3vjbC3lCDc9kvybOT5PbuGhC4_k4g8LCjxX23VX7E

Rowlandson answered 17/11, 2020 at 11:0 Comment(0)
S
0

Here are two articles I wrote that walks through setting up x11 for different types of use cases:

  1. Install a Program With a Graphical User Interface in WSL2: This article walks through installing vcxsrv, adding the environment variables to the bashrc configuration file, and programmatically scheduling vcxsrv to launch with command-line parameters at startup. It also covers installing and launching Firefox as a standalone program in WSL2.
  2. Install Ubuntu Desktop with a Graphical User Interface in WSL2 This article walks through installing vcxsrv, dotNet, genie, and the Ubuntu desktop. It covers creating the scripts that exports the environment variables, launches vcxsrv, starts the gnome desktop environment, and creates the shortcut that ties them all together. It also covers running the Ubuntu desktop, preventing a screen lock bug, and installing the Snap Store.
Stolon answered 12/12, 2020 at 18:44 Comment(1)
Fixed, thanks @HectorJStolon
U
0

I also experienced hardships in opening X11 GUIs from WSL.

I had a problem detecting the correct IP and sometimes the X11 server took weird offsets which sometimes appeared as random on 0-17.

I coded the following script to automate this issue, but it has few dependencies:

  • This was tested and run under CentOS7 image
  • install X11-apps on your linux distribution to have `xset
  • install "timeout" app
  • Execute script by source ./find_display_ip.sh. note the source! You will want to have DISPLAY environment variable on your running shell.
  • Run the script only through "Windows Terminal" or something that incoprates windows "PATH" inside the WSL shell. This didn't use to be default for me in windows prompt `cmd, for example.
  • Obviously make sure your X11 server has full access ("xhost +" or "X11 remote access" is full)

Without further a due, this is the script source code:

#!/bin/bash

start_index=$1
start=${start_index:-0}
# check current settings
declare -i stop=0
if [ ! -z "$DISPLAY" ]; then
    timeout 1s xset -display $DISPLAY q &> /dev/null;
    [[ "$?" -eq 0 ]] && echo "Already Set to $DISPLAY" && stop=1;
fi

# scan displays 0-17
for port in $(seq $start 17);
do
    [[ 1 -eq $stop ]] && break;
    grp="ipconfig.exe | grep IPv4 | tr -d '\015' | sed 's#.*: \(.*\)\$#\1:${port}.0#;'"
    for ipd in $(eval $grp)
    do
        echo Trying $ipd;
        timeout 1s xset -display $ipd q &> /dev/null;

        # command was sucessful
        [[ "$?" -eq 0 ]] && export DISPLAY=$ipd && echo $ipd was set && stop=1;

        ##echo "Trying next IP...";
    done
done
Uppish answered 11/6, 2021 at 19:58 Comment(0)
I
-1

I've managed to work with the out-of-the-box VcXsrv firewall configuration (i.e., no need to override/disable any firewall rules) by using the LAN adapter IP of the Windows host. Added the below to my ~/.bash_aliases

export DISPLAY=$(pwsh.exe -c ipconfig | grep -A 3 lan | grep IPv4 | head -1 | awk '{ print $NF }'):0

where lan is my Connection-specific DNS Suffix (yours may differ, in which case you should replace it in the command line above).

Irtysh answered 9/9, 2020 at 15:18 Comment(3)
.bash_aliases should be used for...alias, not export variables And you're launching a command on windows from wsl2 to get the output of ipconfig, pass it to 2 grep, one head and one awk... and every time you open a shell. The pwsh.exe alone on my laptop takes 1.125s to run!Bodwell
Sadly, this doesn't work for me for two reasons. There is no pwsh.exe on my system. I assume that you meant powershell.exe or have some alias on your Windows system. The output when using powershell.exe ends up being the following on my system: :02.168.0.5. That of course won't work as that is only part of the address and the string order is flipped for some reason.Swiss
For once if you're on a wifi grep would have to search for wlan instead and on the other hand setting DISPLAY alone still doesn't solve the firewall blocking communication on public networks by default.Cyd
M
-1

The following workaround works for me:

Set-NetFirewallProfile -Name $(Get-NetConnectionProfile).NetworkCategory -DisabledInterfaceAliases $(Get-NetAdapter | Where-Object Name -like 'WSL').Name

Maniac answered 6/10, 2020 at 12:24 Comment(1)
What you are doing is entirely disabling the firewall for the wsl network adapter. This is a security risk and should be avoided.Maddiemadding
S
-1

My mistake was that I took the nameserver of my linux wsl2 instance while my xserver runs on windows. So the DISPLAY variable had to be set to my windows ipv4 address. Just type ipconfig in powershell or cmd and use the ipv4 ethernet address.

Strident answered 24/3, 2021 at 15:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.