The Windows Subsystem for Linux is a convenient solution for people who want to use Linux development tools on Windows machines. However, since it’s implemented as an operating system running within a lightweight virtual machine within another operating system, it’s sometimes inconvenient to synchronize your tools and settings between Windows and Linux.
This article describes an elegant solution for keeping in sync your SSH keys and configuration files. It goes through and details some of the answers presented on the corresponding question on the Super User Stack Exchange, before presenting the one I’ve come up with.
Copying the files over
Let’s first look at the “official” solution for sharing your SSH config/keys between Windows and your WSL distro. This article on the Microsoft blog gives indications on how to copy the SSH config/keys directory over to Linux and then change the permissions appropriately. This is also the accepted answer on the Super User question mentioned above.
To copy all of your SSH keys/config files from Windows to the WSL distro, you can use
cp --recursive /mnt/c/Users/<your Windows username>/.ssh/ ~/
And don’t forget to update the corresponding file permissions:
chmod 700 ~/.ssh/ chmod 600 ~/.ssh/*
While this works and is a quick fix, the disadvantage is that changes to your SSH config or to your keys will not be automatically reflected across OSes. You’d have to remember to copy the files again or manually make changes in both places each time you need to modify them.
C: drive with Linux metadata support
All of your Windows drives are implicitly available in WSL under the
/mnt directory, mounted using the DrvFs driver. If you check out this directory, you will see entries such as
/mnt/d etc., which allow you to access the
You might think it’s enough to create a symbolic link from
~/.ssh, but you’ll run into issues with the permissions. Turns out that, by default, WSL mounts those Windows drives with all permissions given to all users, which is a security risk the SSH client will not accept. Furthermore, any
chmod changes you perform on folders within the mounted drives will be ineffective.
The trick, as described by user @plwalsh88 in this answer, is to first enable the
metadata option on the DrvFs mounts. This will make the file system able to track and remember the Linux-specific permissions, even though they are set on files from a Windows drive.
To do this, create or update the
/etc/wsl.conf file and change the automounting options to the ones recommended in the answer:
[automount] options = "metadata,umask=022,fmask=111"
After saving the modifications, exit the terminal and restart your WSL distro. Then proceed to creating a symlink:
ln --symbolic /mnt/c/Users/<your Windows username>/.ssh/ ~/.ssh/
And updating the file permissions, just like in the solution described above:
chmod 700 ~/.ssh/ chmod 600 ~/.ssh/*
Note, however, that this is a change in the default WSL 2 configuration and might incur some overhead or cause compatibility issues. There’s also a risk that Windows programs editing your might remove the associated Linux permission metadata.
Directly mounting the
.ssh directory using
It would be nice if we could make the minimal amount of changes to get the
.ssh directory to be available directly in Linux. There’s a way to do this using the DrvFs file system driver, combined with Linux’s built-in
fstab config file. 1
fstab, short for file system table, is a configuration file used by the startup process to determine which file systems need to be automatically mounted where. This is how Linux knows where to find your root file system, or the swap partition, and so on.
C:\Users\<your Windows username>\.ssh\ /home/<your Linux username>/.ssh drvfs rw,noatime,uid=1000,gid=1000,case=off,umask=0077,fmask=0177 0 0
The first argument must be the Windows-specific path to the folder you want to mount in WSL. The second argument indicates the target mount location.
The third argument is a bunch of flags, passed directly to DrvFs:
rwindicates we want to be able to read and write the mounted directory. Change this to
roif you don’t want to allow Linux tools to edit your SSH config files.
noatimedisables the updating/tracking of file access times, a feature which isn’t so useful in modern times.
gidflags indicate it should be mounted as being owned by your user’s ID (change these if your user’s ID aren’t
1000, the default on most distros. Find your IDs by running the
caseoption indicates that newly created subdirectories inside the mounted directory shouldn’t be considered case sensitive (which isn’t the case for Windows folders).
- The last two mount flags ensure the directory’s permissions are as restricted as possible.
fstab parameters aren’t relevant for our use case.
This will make Linux automatically mount the indicated folder at the target location whenever the distro is started. You just have to restart your WSL distro and everything will work as expected.
There are usually many ways to achieve the same desired outcome. This post shows that by investigating the problem, understanding how things work and thinking creatively, we can find the solution which best fits our needs.