sfmontyo
sfmontyo

Reputation: 699

How to Setup VcXSrv for use with WSL2

How do you setup VcXSrv.exe on Windows 10 to work with WSL2 without disabling access control? Every description on the internet shows to disable the access control, but this allows any program on the local network to log your keystrokes and mouse movements among other things.

Upvotes: 23

Views: 39019

Answers (4)

Muntashir Akon
Muntashir Akon

Reputation: 9441

With mirrored networking enabled in WSL2, you can setup VcXSrv without any additional complexity and run it as if it's native to your distro.

First, you need to disable WSLg and enable mirror networking at C:\Users\{UserName}\.wslconfig:

[wsl2]
guiApplications=false
networkingMode=mirrored

Then, configure a VcXSrv shortcut to enable multiwindow, clipboard, and OpenGL acceleration:

  1. Add a shortcut for your VcXSrv to some location.
  2. Go to properties and append the following at the end of Target: (notice the space at the front)
 -multiwindow -clipboard -wgl
  1. Rename it to something like VcXSrv Multiwindow and run it (end any previous instance using Task Manager if applicable)
  2. (Optinal) Add it to startup applications: https://support.microsoft.com/en-us/windows/configure-startup-applications-in-windows-115a420a-0bff-4a6f-90e0-1934c844e473

Finally, configure ~/.bashrc (or any other profile) to use the display:

# X11 server on Windows
export DISPLAY=:0
export LIBGL_ALWAYS_INDIRECT=1
export GDK_SCALE=1
export GDK_DPI_SCALE=2

You can change the scaling parameters based on how you have configured your Windows display in order to avoid any blurry or zoomed-out effects.

BONUS

With this option enabled, you can easily create WSL2 shortcuts to launch your favorite app directly like this:

  1. Open Windows Explorer and navigate to C:\Users\{UserName}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs

  2. Create a new shortcut with target set to C:\Program Files\WSL\wsl.exe

  3. Open properties of the shortcut and modify the Target to add some parameters like your distro followed by your the Linux GUI app:

 -d {Distro} --cd ~ -- DISPLAY=:0 LIBGL_ALWAYS_INDIRECT=1 GDK_SCALE=1 GDK_DPI_SCALE=2 {app-name}
  1. You can also change the icon to the app's icon if you prefer.

Upvotes: 0

Pulsares
Pulsares

Reputation: 39

Complementing sfmontoyo's solution, I prepared a script to deal with this scenario. Steps to use it:

  • Shortcut creation
  • Script creation
  • Automation

Shortcut creation

simply create a shortcut to VcXSrv.exe, right click on properties and set target to, for example:

"C:\Program Files\VcXsrv\vcxsrv.exe" -multiwindow -clipboard -wgl -auth "\\wsl.localhost\<distro_name>\home\<distro_username>\.Xauthority" -logfile "c:\users\<windows_username>\VcXSrv.log" -logverbose 5

where:

  • <distro_name> is the name of the Linux distribution, for example Debian
  • <distro_username> is the username within your Linux distribution, for example john_doe_at_debian
  • <windows_username> is the username within your Windows OS, for example john_doe_at_windows

Script creation

In a file named .set-xauthorisation.sh in your distro user's root folder, copy the following code into a script called set-xauthorization.sh:

#!/bin/sh

CURRENT_IP=$(grep -oP '(?<=nameserver\s)[\d.]+' /etc/resolv.conf)
export DISPLAY="$CURRENT_IP:0.0"

xauthorise() {
  local PASSPHRASE=""
  local VERBOSE=0

  while getopts ":p:v" opt; do
    case ${opt} in
      p )
        PASSPHRASE=$OPTARG
        ;;
      v )
        VERBOSE=1
        ;;
      \? )
        echo "Invalid option: $OPTARG" 1>&2
        ;;
      : )
        echo "Invalid option: $OPTARG requires an argument" 1>&2
        ;;
    esac
  done
  shift $((OPTIND -1))

  : > ~/.Xauthority # make sure there is a .Xauthority file
  local X_AUTH_RAW_LIST=$(xauth -n list)
  local XAUTH_IP=$(echo "$X_AUTH_RAW_LIST" | awk -F':' '{print $1}')
  local X_AUTH_LIST=$(echo "$X_AUTH_RAW_LIST" | awk '{print $1}')

  conditional_echo() {
    local content=$1
    [ $VERBOSE -eq 1 ] && echo "$content"
  }

  enforceNoEntries() {
    local entries=$1

    if [ -z "$entries" ]; then
      conditional_echo "No entries to remove."
      return
    fi

    echo "$entries" | while read -r display; do
      conditional_echo "Removing $display."
      xauth remove "$display"
    done
    conditional_echo "Entries deleted."
  }

  setXauthority() {
    local PASSPHRASE=$1
    local DISPLAY_IP=$2
    local magiccookie=$(echo "$PASSPHRASE" | tr -d '\n\r' | md5sum | awk '{print $1}')
    local command="xauth add $DISPLAY_IP:0.0 . $magiccookie"
    conditional_echo "$command"
    eval $command
  }

  if [ "$CURRENT_IP" != "$XAUTH_IP" ]; then
    enforceNoEntries "$X_AUTH_LIST"
    setXauthority "$PASSPHRASE" "$CURRENT_IP"
    conditional_echo "Xauthority updated."
  else
    conditional_echo "No change in DISPLAY IP."
  fi
}

Automation

Call the script in your .bashrc or .zshrc with, for example:

. ~/.set-xauthorisation.sh
xauthorise -p "<your_xauth_password>" -v

where:

  • <your_xauth_password> is a password that can not be guessed, for example, an_unguessable_password

Notes

  • In addition to the .Xauthorization file handling this script exports $DISPLAY variable for use within the shell.
  • Once you are satisfied with its behaviour, you can omit the verbose switch -v when calling xauthorise.

Upvotes: 0

john mba
john mba

Reputation: 7

This worked for me; Updating the WSL with wsl --update and restarting WSL with wsl --shutdown that will force the WSL to restart and after the update to check run the following command:

  • echo $DISPLAY you will have this value :0
  • xhost + you will see

access control disabled, clients can connect from any host

if you still experience problems restart your windows and try again. you can go through this github trend on this issue to learn more.

Upvotes: -1

sfmontyo
sfmontyo

Reputation: 699

Rather than disabling access control on VcXSrv, you should use the .Xauthority file to share keys between your X11 clients and the VcXSrv X11 server. The .Xauthority contains a collection of authorization keys indexed by the DISPLAY . You'll need to setup this file with a key for your particular Windows host and share that file between the VcXSrv and your X11 clients running on your WSL2 distro. To setup this, follow these steps:

Run your WSL2 distro (Assuming this is a debian based one) and install xauth, md5sum and gawk or awk. We'll also install some X11 client to test our setup. In this case, we'll install gnome-terminal but you can install something else if you want. On an Ubuntu distro, you can do:

sudo apt install -y xauth coreutils gawk gnome-terminal 
xauth list # this should be an empty list
magiccookie=$(echo '{some-pass-phrase}'|tr -d '\n\r'|md5sum|gawk '{print $1}')
xauth add host.docker.internal:0 . $magiccookie
cp ~/.Xauthority /mnt/c/Users/{WindowsUserName}

Add the following to either your ~/.bashrc in your WSL2 distro home dir

     export DISPLAY=host.docker.internal:0

We need to create either an XLaunch configuration file (i.e. config.xlaunch ) or a shortcut to VcXSrv.exe with the desired command line args. XLaunch is a simple launcher that assists in setting up the arguments and in turn calls vcxsrv.exe. We'll ignore using XLaunch and just create our own shortcut with the appropriate arguments. We want to run VcXSrv.exe with these args:

vcxsrv.exe -multiwindow -clipboard -wgl -auth {.XAuthority file} -logfile {A Log file} -logverbose {int log level}

From above, we copied the .Xauthority file to /mnt/c/Users/{WindowsUserName}/.Xauthority which means our desired command line is:

vcxsrv.exe -multiwindow -clipboard -wgl -auth "c:\users\{WindowsUserName}\.Xauthority" -logfile "c:\users\{WindowsUserName}\VcXSrv.log" -logverbose 5

Feel free to omit the logfile and logverbose options if you're not debugging any issues. So you can just do:

vcxsrv.exe -multiwindow -clipboard -wgl -auth "c:\users\{WindowsUserName}\.Xauthority"

Remember to replace {WindowsUserName} with the name of your folder under c:\Users.

To create the shortcut, navigate to where VcXSrv.exe is installed. The default location of this is

C:\Program Files\VcXSrv\VcXSrv.exe

In the explorer file window, right click on the VcXSrv.exe and click "Create Shortcut" . This will create a shortcut on your desktop.

Right click over the created shortcut icon, and select properties.

In the Shortcut tab, append the arguments above after the executable . It should look something like:

"C:\Program Files\VcXSrv\VcXSrv.exe" -multiwindow -clipboard -wgl -auth "c:\users\{WindowsUserName}\.Xauthority"

In the General tab of the Properties dialog, change the name to be "VcXSrv with XAuthority".

Click ok.

Now you can start the X11 server by double clicking on the shortcut.

If you wish to have the X11 server started at startup, follow the instructions here: https://support.microsoft.com/en-us/windows/add-an-app-to-run-automatically-at-startup-in-windows-10-150da165-dcd9-7230-517b-cf3c295d89dd

Now back in the WSL distro terminal, you should be able to run the gnome-terminal or other X11 client and have it display securely on the VcXSrv X11 server running on the Windows host.

export DISPLAY=host.docker.internal:0
gnome-terminal

This should result in the gnome-terminal being displayed on your X11 Server. Further, the xauthority file will be used to allow only authorized clients to connect to your X11 server.

Upvotes: 34

Related Questions