Leveraging WSL2 for Systems & Cloud Administration, Cybersecurity, and Software Development

+

Win11 Desktop running 3 WSL2 instances

There’s quite a bit going on in the Windows 11 desktop pic shown at the top of this post. To see the details, you can pinch zoom the pic if you are on a phone or touchscreen device, or right-click the pic and choose to open it in a new browser tab if you are on a desktop computer.

  • In the upper left, I’m running a Linux container with a sample Python web app in Podman Desktop that listens to port 3333 and outputs “Hello World!” when accessed in Microsoft Edge.
  • In the lower left, I’m running an Ubuntu 24.04 Linux system. The Ubuntu terminal displays the output of neofetch and has also executed the graphical xbill game on the Windows desktop. XBill is a Linux-only game from the 1990s where you had to smack Bill Gates before he replaced the operating system on computers with Windows. While not shown, this Ubuntu system is also used to centrally control my on-premises and cloud servers using dozens of Ansible playbooks and roles that I have created on it.
  • In the upper right, I’m running OWASP ZAP and Metasploit in a graphical Kali Linux desktop that has hundreds of other cybersecurity tools installed.
  • In the lower right PowerShell window, the output of wsl --list indicates that these three Linux systems are not standalone operating systems. Instead, they are tightly integrated into the Windows operating system using the Windows Subsystem for Linux.
  • And in the lower middle, you’ll see from Windows Task Manager that all of this uses less than half my memory (only 14.5GB of the 32GB available).

Understanding Windows Subsystem for Linux (WSL)

Windows Subsystem for Linux, version 2 (WSL2) is what makes it possible to run the three Linux systems shown earlier alongside Windows 11 in under 15GB of memory. But it wasn’t the first version of WSL. Microsoft released the first version of WSL (WSL1) for Windows 10 in 2016, and it functioned by translating Linux programs to run on the Windows kernel. It originally supported basic shell commands only, but Microsoft later provided the ability for graphical Linux programs to be translated to the Windows desktop. While it was perfectly functional (as described in my earlier blog post), the performance was dismal (notably disk I/O) and not every Linux program could be translated effectively to run on Windows.

WSL1 was simply not useful from a professional standpoint. Thus, most IT administrators who used a Windows workstation in the late 2010s to manage servers (including the plethora of Linux servers that comprise 95% of the cloud) ran a full virtual machine (VM) of Linux on their Windows system so that they could run the Linux software they needed (e.g., Ansible). Cybersecurity workers did the same, since nearly all cybersecurity tools run exclusively on Linux. Kali is a popular cybersecurity-focused Linux distribution for this purpose. Because nearly all web and cloud apps are designed to run on Linux servers, software developers also needed to run a Linux VM that integrated with their developer tools so that they could test their apps before deployment. Luckily, Windows 10 Professional and Enterprise editions contain a component for running virtual machines next to Windows called Hyper-V.

Unfortunately, VMs operate as a full operating system running alongside Windows on Hyper-V as shown below. Say that the Ubuntu and Podman VMs are configured with 4GB of memory each, and the Kali VM is configured with 8GB. When all three VMs are running, 16GB of memory is being used on top of what Windows needs (approx. 10GB today). Thus, you’d expect to see 26GB of memory used on the system. Moreover, you need to manually start, stop, and manage each VM, as well as use a program that can interact with them using a network protocol, such as SSH, VNC, or RDP.

Win11 running 3 Hyper-V VMs

So, Microsoft decided to work on their problems with WSL1 to provide a better solution for running Linux on Windows. They released WSL2 in 2019 and later added seamless Windows integration for Linux graphics (including X.org and Wayland based graphical apps) in 2021. Instead of translating Linux commands and programs to run on the Windows kernel, WSL2 leverages a subset of Hyper-V (called the Virtual Machine Platform) to run a custom Linux distribution (including a Linux kernel) that seamlessly integrates with Windows as shown below. Better yet, the Virtual Machine Platform and WSL2 are available on Home edition of Windows 10 and 11, so you don’t need to upgrade to the Professional or Enterprise editions.

Win11 running 3 WSL VMs

On a technical level, WSL2 Linux distributions function much like virtual machines – they run a real Linux kernel on the Virtual Machine Platform, which means they can execute any Linux program with near native performance. But WSL2 integrates all input, graphics, and network access directly into Windows, and allows Linux and Windows filesystems to directly access each other. For example, from Windows, you can navigate to the Linux icon in the navigation pane of File Explorer to see a folder that represents the / (root) filesystem of each distribution:

Win11 File Explorer Linux distributions

Entering the kali-linux folder will give you access to the root filesystem of the Kali distribution:

Win11 File Explorer Kali Root Filesystem

Alternatively, you can access the files in Windows within any WSL Linux distribution by navigating to /mnt/driveletter (e.g., /mnt/c for C:\ and /mnt/d for D:\). For example, to list the contents of C:\ from Ubuntu, you could run the following command:

Accessing /mnt/c from Ubuntu

Installing a WSL2 Linux distribution

To install a WSL2 Linux distribution, open the Terminal app to get a PowerShell prompt. Next, run the wsl --list --online command to display the available distributions from the Microsoft repository, noting the short name of each. This is the name you can use alongside the --distribution option to the wsl command to install it. For example, to install Ubuntu 24.04, you can run wsl --install --distribution Ubuntu-24.04 and to install the latest Kali Linux, you can run wsl --install --distribution kali-linux. The first time you install a distribution, the wsl command will also install the WSL2 and Virtual Machine Platform components of Windows, which will require that you reboot afterwards.

After the wsl --install --distribution command downloads the distribution of your choice, it will run it within the Terminal app and ask you to choose a name and password for a regular user account. This regular user account is what the distribution automatically logs you in as each time you run it in the future. I like to choose a name of woot since this regular user is given the ability to run administrative commands as the root user via the sudo command (so, it’s almost root).

Following this, I run the sudo passwd root command to set the root user password. Next, I run the su - command to switch entirely to the root user so that I can run many administrative commands without having to prefix each one with sudo.

Since both Kali and Ubuntu are Debian-based distributions, you can use the apt command to install and update software within them. The first command I always run is apt update && apt upgrade -y. This refreshes the list of online software repositories and uses that list to upgrade all packages to the latest versions. Next, I install the software I need on each system.

  • For Ubuntu, I run the apt install net-tools btop neofetch ansible command to install the legacy network commands (including ifconfig), the btop command (for monitoring performance), neofetch (for system information), and Ansible (which includes the ansible and ansible-playbook commands for managing my fleet of servers). If you choose to install graphical programs (e.g., xbill as shown earlier, or firefox), make sure you append & when running them at a shell prompt (e.g., xbill &). This ensures that you obtain another shell prompt right away without having to wait for the graphical program to exit.

  • For Kali, I run the apt install kali-win-kex kali-linux-large command to install the Kali desktop and hacking tools. After this, you can run kex --esm --ip -s to get a full Kali desktop, as shown in the pic at the top of this post. You can instead run kex --sl -s to run Kali graphical apps in seamless mode – in this case, you execute the hacking tools from a Kali shell prompt (e.g., zaproxy for OWASP ZAP) and they run directly on the Windows desktop, much like xbill.

When you close your Linux shell in the Terminal app, the associated WSL2 Linux distribution is stopped and no longer uses system resources. However, you can easily return to it at any time by choosing the distribution icon from the Start menu (e.g., Ubuntu), or open a Terminal app and choose your distribution from the drop-down menu, as shown here:

Terminal menu

You’ll notice that the podman-machine-default distribution shown on the menu isn’t something that shows up in the output of wsl --list --online. This is because that distribution was installed automatically by the Podman Desktop developer software. Most developer software that can run Linux containers or Kubernetes clusters for testing web and cloud apps perform the installation, management, updating, starting, and stopping of WSL2 Linux distributions automatically in the software itself. When you open Podman Desktop, it starts the podman-machine-default distribution, and when you close Podman Desktop, it stops the podman-machine-default distribution.

Other WSL2 Information

From a PowerShell prompt within the Terminal app, you can run the wsl --list command to see the WSL2 Linux distributions you have installed, the wsl --list --running command to see the distributions you currently have running, the wsl --shutdown command to stop all running distributions, and the wsl --unregister distributionname command to uninstall a specific distribution (by short name).

The / (root) filesystem for each distribution is formatted using ext4 and stored in a dynamically-expanding virtual hard disk file called ext4.vhdx with a maximum size of 1TB in the C:\Users\username\AppData\Local\Packages\distributionname\LocalState\ folder. Each virtual hard disk shows up as a different SAS disk within the Linux distribution itself, and WSL2 creates a 4GB disk that is used for shared virtual memory (swap) between all distributions. For example, if you run the lsblk command within a WSL2 Linux distribution, you may find that sda (SAS disk A) is Ubuntu’s / filesystem, sdb (SAS disk B) is shared swap, sdc (SAS disk C) is Kali’s / filesystem, and sdd (SAS disk D) is the / filesystem for the Podman distribution.

All WSL2 Linux distributions are given a private IPv4 address on the 172.x.x.x network behind a virtual NAT router on Windows that bonds to the active Internet connection. You can also use a UNC path of \\wsl$\ in any command or program to access the folders that represent the / filesystems of each distribution (equivalent to the Linux icon in File Explorer shown earlier).

When running commands like neofetch and btop within a WSL2 Linux distribution, you’ll notice that while WSL2 allows each distribution to use all CPU cores, only half the memory is displayed. For example, on a Windows system with 32GB of memory, WSL2 Linux distributions will only see 16GB. While this is often more than adequate, if you’d like your distributions to see all 32GB of memory, you can create a C:\Users\username\.wslconfig file in Windows with the following contents and reboot your system:

[wsl2]
memory=32GB