Management Windows Subsystem for Linux Lead image: Lead Image © Devon, Fotolia.com
Lead Image © Devon, Fotolia.com
 

WSL puts Linux on Windows desktops

Sublease

Windows 10 supports the native execution of Linux binaries from various distributions through the Windows Subsystem for Linux. Even graphical Linux applications can make their way onto the Windows desktop. By Christian Knermann

Since Satya Nadella took over the helm of Microsoft in 2014, Redmond's aversion to Linux and open source software in general has given way to a new openness. As a result, Linux virtual machines (VMs) now run without complications on the Hyper-V hypervisor and in the Azure cloud.

The Windows Subsystem for Linux (WSL) adds a new compatibility layer to Windows 10. As the name implies, WSL is not a hypervisor that runs complete Linux systems in the form of virtual machines, but an interface that directly supports the execution of Linux ELF64 binaries [1].

WSL Architecture

The subsystem introduces what are known as pico processes [2], which run in user mode, forming the shell for unmodified executable Linux applications. To do this, they forward their system calls to the pico provider drivers lxss.sys and lxcore.sys in kernel mode and translate the system calls to their Windows counterparts. In the case of Linux system calls that have no direct equivalents in the Windows kernel, the drivers emulate the Linux kernel.

The surrounding enclosure is the LXSS Manager service, which runs in user mode and becomes active as soon as a user launches a Linux distribution with WSL. The LXSS Manager then creates a Linux instance, in which it launches the init followed by the Bash shell and all other executable files as pico processes (Figure 1). In early versions of WSL, as soon as the user closed the WSL console, the LXSS Manager cleaned up the respective Linux instance, which meant it was not possible to run background processes. However, Microsoft has since added this option [3]. If processes are still active in the background, a Linux instance now lives on, even if an interactive window is no longer open for the user.

The WSL comprises the LXSS Manager and pico processes in user mode, as well as the pico provider drivers in kernel mode (source: [4]).
Figure 1: The WSL comprises the LXSS Manager and pico processes in user mode, as well as the pico provider drivers in kernel mode (source: [4]).

Partially Compatible Filesystems

Because the Linux instances are not complete VMs isolated from the Windows operating system, the processes can interact directly with Windows and its filesystems. However, the filesystem strategies for folder and file management and for handling permissions differ between the two worlds. WSL meets this challenge by imitating the Linux Virtual File System (VFS) and by wiring interfaces to several filesystems through VFS [5]. Thus, TmpFs maps the memory-resident temporary Linux filesystem. The Linux pseudo-filesystems also have their counterparts in WSL in the form of ProcFs and SysFs (Figure 2).

WSL provides interoperability between Linux and Windows filesystems through multiple interfaces (source: [5]).
Figure 2: WSL provides interoperability between Linux and Windows filesystems through multiple interfaces (source: [5]).

The primary WSL filesystem is VolFs. It is used for the root directory of the respective Linux instance. VolFs provides full support for Linux filesystem permissions, which can be edited by commands such as chmod, and other features such as symbolic links, case-sensitive folders and files, FIFOs, and sockets. The root directory of each instance is located in the %userprofile%\AppData\Local\Packages\<Name-and-ID-of-Linux-Instance>\LocaleState\rootfs path in Windows.

The literature on WSL – and partly in Microsoft's own online documentation – still has references to the %userprofile%\AppData\Local\lxss path, which is where the root directory lived in the first implementation of WSL launched by Microsoft in 2016 in cooperation with the Linux distributor Canonical, known for its Ubuntu distribution. However, this path only has historical significance. In current Windows installations, this original variant of WSL no longer exists.

When dealing with the root directory, note that you can view the folders and files under Windows but not change them because NTFS does not support all of the Linux special features. Although NTFS can distinguish between upper- and lowercase, the permissions are not compatible, and not all characters in folder and file names that Linux supports are also allowed in Windows. VolFs takes care of these differences and stores them as metadata in the NTFS extended attributes. If you were to use Windows to add new folders and files to the root directory, these extended attributes would be missing and VolFs would be unable to use the data. Likewise, the extended attributes would be lost from existing data, which would thus become unusable for VolFs as soon as you change them under Windows. It was not until build 18342 (1903) of Windows 10 that this situation improved; Windows can now access root directories thanks to the introduction of shares in the form \\wsl$\<Name-of-Distribution>.

Exchange with DrvFs

Originally, interoperability between the worlds was only guaranteed by DriveFS, or DrvFs for short, which does not support all the functions that Linux supports. DrvFs restricts the names of folders and files to the character set that Windows uses and is compatible with Windows permissions. Data stored in DrvFs can be case sensitive, but Microsoft warns that not all Windows applications can handle this.

With regard to access privileges, you should note that WSL can map the permissions set under Windows in Linux but, of course, cannot revoke them. As the above path to the root directory shows, the Linux instances under Windows are user specific. Each Windows user receives their own Linux instance, and the data is stored in the user's personal profile. Within a Linux instance, users always have root privileges, but it does not automatically make you an admin outside of Windows. You can therefore only write from within Linux with sudo to locations that you are allowed to write to in Windows.

Under these conditions, the setup is bidirectionally compatible, and you can work with the usual Linux tools (e.g., awk and sed), as well as with Windows tools in VolFs-connected drives.

Installation

To begin, open PowerShell with administrative privileges and install WSL with:

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux

After successfully completing the install, the system has to reboot. Next, open Microsoft Store. A search for Linux reveals numerous results, including several well-known distributions, such as openSUSE, various versions of SUSE Enterprise, Debian, Ubuntu, and Kali Linux, which is popular among pentesters and forensics experts. For this example, install Kali Linux and Ubuntu. As soon as the store has finished downloading the distributions, you will find both as icons in the start menu. Clicking on them opens a console window with a Linux shell. Alternatively, you can start Linux instances at the Windows command prompt by typing kali or ubuntu. The generic wsl command starts the configured default Linux distribution. You can find out which this is with the Windows command wslconfig /list, which lists all Linux distributions installed in WSL. If you installed Kali Linux first, it is automatically the default. Typing

wslconfig /setdefault Ubuntu

changes the default to Ubuntu. If a Linux instance without an interactive shell is still active with background processes, you can terminate it with:

wslconfig /terminate <Name-of-Distro>

The first start is followed by a basic configuration of the distribution. You are prompted to create a user with a password that does not have to be the same as your Windows user account password. At this point, you can update both Linux instances with the familiar commands

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get clean

because of the similar substructure used by Kali Linux and Ubuntu.

Working with the Filesystem

By default, the Linux shell sets the working directory to /home/username; in the Windows NTFS filesystem, this is equivalent to the path:

%userprofile%\AppData\Local\Packages\<Name_and_UID_of_Linux_instance>\LocaleState\rootfs/home/username

Alternatively, WSL also adds an entry to the Windows Explorer context menu. If you hold down the Shift key in any folder and right-click the context menu, you will find an Open Linux Shell here entry that starts the distribution configured as the default in the desired directory.

However, this initially only works for the system's connected drives. WSL automatically mounts all known Windows drives with their respective drive letters under paths such as /mnt/c and /mnt/d. If you also plug in a USB stick that Windows connects as drive E:, you first have to mount it with DrvFs under Linux:

sudo mkdir /mnt/e
sudo mount -t drvfs E: /mnt/e

This works just as well with network shares that are connected by drive letters under Windows, or alternatively, you can mount a drive directly with

sudo mkdir /mnt/share
sudo mount -t drvfs '\\server\share' /mnt/share

by specifying the Universal Naming Convention (UNC) path.

Linux and Windows Commands

In the shell, all commands and applications available under Linux are available for working with Windows folders and files. However, even without having a Linux shell open permanently, interoperability between the two worlds is ensured [6]. Thanks to wsl.exe, you can launch individual Linux commands (path specifications must, of course, follow the conventions for Linux) directly from a Windows command prompt: Open the cmd.exe command prompt and type:

wsl ls -la "/mnt/c/Program Files"

You will then see the output of the ls command in Windows; WSL executes this on the default Linux instance. Conversely, you can run Windows executable files in an open Linux shell just as easily. Typing notepad.exe opens the Windows editor in the shell. Passing in parameters to the respective application when calling it is also possible. Path specifications, in turn, need to comply with Windows conventions.

X11 Applications with RDP

At the command line, at least, WSL brings Windows and Linux closer together and makes work more flexible. Microsoft did not intend users to launch graphical Linux applications in WSL, but you do have several approaches to achieve this. The creators of Kali Linux take a detour via the Remote Desktop Protocol (RDP) on top of Linux's own X Window System (X11) and provide a script that you can download and execute in the Kali shell with the commands:

wget https://kali.sh/xfce4.sh
sudo sh xfce4.sh

The script downloads and sets up the Xfce desktop environment customized for Kali and the free Xrdp RDP server with all dependencies, which takes a while and is reflected in additional memory requirements of more than 1GB. Typing

sudo /etc/init.d/xrdp start

starts the RDP server, which then accepts connections on TCP port 3390. With the use of the graphical client of the remote desktop connection or

mstsc.exe /v:127.0.0.1:3390

at the Windows command line, you can then start the Kali Linux desktop. After completing your work, log off from the desktop and quit the RDP server in the shell,

sudo /etc/init.d/xrdp stop

to ensure that the Linux instance terminates cleanly when leaving the shell and does not continue to run in the background.

This approach is quickly put into operation, but the problem is that the X11 protocol tunnels in RDP and thus only starts complete desktop sessions and not individual applications.

X Server X410 Application Window

A more elegant solution without a detour via RDP requires an X server on Windows. The X410 X server is unfortunately not free of charge, but it was specially developed for integration with WSL; you can pick it up as an app from the Microsoft Store [7]. If you launch the app, it initially only shows up as an X icon in the system tray. You then need to use the icon's context menu to configure the operating mode.

In Windowed Apps mode, X410 acts as a window manager and waits for you to start individual applications in a Linux instance that behave like native Windows applications, are displayed in separate windows, and can be positioned and resized arbitrarily on the Windows desktop. The Floating Desktop, on the other hand, expects a complete Linux desktop session to start and displays it in a window (Figure 3). The Full Desktop executes the Linux desktop, not surprisingly, in full-screen mode.

The X410 X server displaying the Linux desktop and individual X11 applications directly in Windows.
Figure 3: The X410 X server displaying the Linux desktop and individual X11 applications directly in Windows.

If not already installed, install the Xfce window manager in your Linux instances. On Ubuntu you can do so with the command:

sudo apt-get install xfce4 xfce4-terminal

Kali Linux comes with a customized version of Xfce, in which case, you need to type

sudo apt-get install kali-desktop-xfce

The steps that follow are identical in the two distributions. Make sure that X410 is started in Floating Desktop mode; then, export the DISPLAY environment variable in the shell and start the desktop environment:

export DISPLAY=127.0.0.0.1:0.0
xfce4-session

The desktop session then starts on Windows in its own window. To accelerate startup, permanently add the DISPLAY variable to the login script of the Linux shell:

echo "export DISPLAY=127.0.0.1:0.0" >> ~/.bashrc

In Windows, create a batch script with the content:

start /B x410.exe /desktop
ubuntu.exe run "if [ -z \"$(pidof xfce4-session)\" ]; then export DISPLAY=127.0.0.1:0.0; xfce4-session; pkill '(gpg|ssh)-agent'; taskkill.exe /IM x410.exe; fi;"

You can replace the ubuntu.exe with kali.exe and start the X window manager and the Linux desktop in one fell swoop. The how-tos on the X410 website explain how to get started in an even more elegant way without an annoying console window and how to make the Linux desktop look better.

No Desktop At All

If you prefer to do without the complete desktop environment, a variation of this approach also works for individual applications:

start /B x410.exe /wm
ubuntu.exe run "if [ -z \"$(pidof xfce4-session)\" ]; then export DISPLAY=127.0.0.1:0.0; firefox; pkill '(gpg|ssh)-agent'; taskkill.exe /IM x410.exe; fi;"

The /wm option launches X410 in Windowed Apps mode; in the shell command, an application (in this case, the Mozilla Firefox browser) replaces the Xfce desktop environment. The DPI Scaling | High Quality option in the context menu of the tray icon ensures that the windows are upscaled to HiDPI displays. However, in the environment here, this caused some fuzziness in the view.

Therefore, it makes more sense to scale supported applications natively in Linux on displays with very high resolution. This can be achieved for Firefox from the previous example and other applications that use the GTK GUI toolkit and its GDK library (top command) and for applications based on the Qt GUI toolkit (bottom command):

export GDK_SCALE=2
export QT_SCALE_ FACTOR=2

Afterward, Linux applications can hardly be distinguished from native Windows applications, even with HiDPI resolution.

No Support for Daemons

WSL reaches its limits if you need to run a daemon because it lacks a full-fledged launch environment such as Systemd. Commands like reboot, shutdown, and systemctl do not work, and it is therefore not possible to install server services for automatic startup. Even hardware-related commands such as the dd image-building tool do not work. A physical Linux system or one installed in a VM is still the better choice for these sorts of tasks.

Conclusions

Depending on the application, WSL is a practical alternative to full-blown Linux VMs. Compared with the VMs isolated in Hyper-V or similar hypervisors, the WSL advantage is direct interaction with files and folders under Windows. With the tools presented here, even graphical Linux applications under Windows are no longer a problem. Moreover, Microsoft is continually expanding the range of functions [8].

The roadmap for the future version 2 of WSL includes support for Docker containers, as well as migration of the architecture from an emulated to a modified Linux kernel – and the kernel will be completely open source [9].