Making WSL 2 More Usable as a Linux User on Windows

󰃭 2024-03-17

Intro/Backstory

Like any recipe website, this is relevant for context, but ultimately you’ll want to skip to the next heading if you only want to know how I made WSL 2 work better on Windows

Recently I’ve acquired a regular T470 that thankfully still had a working Thunderbolt 3 port, and put my main laptop install of Arch on there.

It was good for a time even with it’s i5-7300U meaning I couldn’t run some VM workloads on my laptop the same as before.

However long standing issues with this Arch install were getting in the way of me attending Teams meetings without audio problems, along with just general glitches that get in the way of getting work done. Too be fair if I recall my current “TimeWarp” Arch install I’ve had since atleast 2017 with my T430 I had in college, however it could be older than that since I had an Arch install on a Lenovo laptop I had back in 2014-2015 that I had also named “TimeWarp”

Since I didn’t want the T470p to go to waste I decided to put Windows 11 on it since the i7-7820HQ inside and the laptop itself was on Microsoft’s supported devices list for Windows 11 (Keyword here is “was”. This laptop is no longer on the list as of October 2021 apparently, but it’s nice to see the Microsoft Surface Studio 2 and some random Dell Precision make the cut to be officially supported)

Windows 11 did install regardless, however certain hardware wasn’t being detected properly and due to this some drivers failed to install due to the hardware not being “present”, so I installed Windows 10 freshly for now. Likely I’ll just have to do an inplace upgrade an a year or two from now to submarine the currently working drivers in.

Anyways, main problem here is that I’ve used Linux as my daily driver for over a decade at this point and that I miss my terminal programs and my package manager.

Thankfully WSL has greatly improved over the years, and we now have WSL 2 basically granting a transparent linux experience in Windows with minimal tradeoffs.

Back when WSL 2 came out initially I didn’t like it due to it’s reliance on Hyper-V since that got in the way of me running VMWare Workstation, well it’s been years since I’ve ran anything VMWare on my systems (And likely won’t again due to the pricing changes Broadcom has recently introduced). So I was keen on seeing how WSL 2 works now especially since it supports GUI apps now.

Mapping the Hosts %USERPROFILE%\.ssh folder into WSL 2

The first problem I wanted to solve was that I wanted to share my SSH keys and config between my laptop and WSL (I use VSCode Remote SSH quite a bit for work and personally along with regular ssh for quick access)

You could symlink the folders together like I did initially, however SSH notoriously will complain if your SSH keys have insecure permissions

[zelec@TG-PF0Z9B2J ~]$ ln -s /mnt/c/Users/Zelec/.ssh ~/.ssh
[zelec@TG-PF0Z9B2J ~]$ ssh -i ~/.ssh/id_ed25519 [email protected]
The authenticity of host 'notarealserver.com (1.2.3.4)' can't be established.
ED25519 key fingerprint is SHA256:bla-bla-bla.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:1: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'notarealserver.com' (ED25519) to the list of known hosts.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0777 for '/home/zelec/.ssh/id_ed25519' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/home/zelec/.ssh/id_ed25519": bad permissions
[zelec@TG-PF0Z9B2J ~]$ 

The unfortunate thing is how Windows maps the /mnt folders by default and that we can’t change the permissions inside of linux to make those files appear safe to OpenSSH, thankfully we can fix both of these issues.

Setting automount options in /etc/wsl.conf

With WSL when it boots up it will check the /etc/wsl.conf ini file and do spesific actions when booting the system.

For example under the [boot] heading you can make the system load up a full copy of systemd by setting systemd=true, or run arbitrary commands on bootup by setting command="mount --make-shared /" to make podman work inside the system.

What we want to setup in the file is the [automount] heading, with that we can change the settings for how the system mounts the /mnt folder. Specifically if we set the options section with the right settings.

Here is my /etc/wsl.conf file for example:

[boot]
systemd=true
command="mount --make-shared /"

[automount]
options="metadata,umask=022,fmask=133"

The main part to focus on is the metadata setting here, from what I understand this will tell WSL to keep track of file permission changes independent of Windows.

Finally is your standard umask and fmask permission fencing.

Rambling about Octal permissions in Linux

For the uninitiated unix permissions follow an “octal” permission set, each file/directory along with having an owner and group assigned have 4 permission numbers that have a value of 0-7 assigned to them, these numbers designate who can read, write, or execute.

For example your .ssh folder normally has a permission set of 0700

I won’t get into a deep dive of permission sets, but here are the basics

The first number designates special properties for ownership, the second number designates the owner’s permission, the 3rd number designates the group permissions, the 4th number for everyone else that isn’t the owner or a member of the group.

While file ownership is straight forward for permissions, directories are a bit stranger when it comes to read/write/execute

  • Read for directories allows you to list the contents of the directory
  • Write for directories allows you to add new or delete existing files to said directory
  • Execute for directories grant you access to the folder, allowing you to pass into subdirectories you already know of.
    • For example if you needed access to /tmp/foo/bar but didn’t need to see the rest of the files in /tmp/foo, having the executable bit turned on allows you to do cd /tmp/foo/bar while not letting you do ls /tmp/foo

Octal works by turning the 3 states of read, write, and execute into numerical values.

  • Read being 4
  • Write being 2
  • and Execute being 1

They have the unique property of every value from 0-7 only has one way of resolving back to the primordial numbers here

A file with the permission set of 0751 for example would evaluate something like this:

Entity TargetPermission NumberReadWriteExecute
Special0---
Owner7XXX
Group5X-X
Other1--X

How does this all relate back to umask, fmask, and also dmask?

These ‘masks’ remove octal permissions, with a umask and fmask of 000 set, a file will auto assign it’s permissions as 0777

umask affects both files and directories, while fmask and dmask affect files and directories respectively.

So a umask of 022 and a fmask of 133 will cause new files/folders generated by linux under the /mnt folder to autoset a permission set of 0755 for directories and 0644 for files

Anyways with all of that out of the way, we can fix the permissions on our symlinked .ssh folder

[zelec@TG-PF0Z9B2J ~]$ chmod 700 ~/.ssh/id_ed25519
[zelec@TG-PF0Z9B2J ~]$ chmod 700 ~/.ssh/id_rsa
[zelec@TG-PF0Z9B2J ~]$ ssh -i ~/.ssh/id_ed25519 [email protected]
Enter passphrase for key '/home/zelec/.ssh/id_ed25519':
Linux notarealserver 6.1.0-18-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Wed Mar 13 21:22:08 2024 from 4.3.2.1
[root@notarealserver ~]$

Congratulations your whole .ssh folder is now connected with your host machine.