Seamless Integration: Using Windows SSH Keys and ssh-agent in WSL2

Published: Posted by Patrick Henninger

Since the inclusion of OpenSSH support in Windows 10, using SSH in Windows has become easier than ever for Linux users. However, working with SSH in WSL can be a complicated topic, as Microsoft's documentation lacks comprehensive guidance on using Windows 10 OpenSSH with WSL. While there are several guides available on this topic, I have noticed that they are not complete and frictionless. Therefore, I've decided to share my setup, which aims to achieve the following goals:

  1. Share Windows 10 SSH keys and configuration with WSL2.
  2. Share Windows 10 ssh-agent with WSL2.

By achieving these goals, you'll be able to use the same SSH keys you use on Windows 10 inside your WSL2 distro without the need for manual copying or passphrase management in a separate keychain. You will only have to enter the password once for both Windows 10 and WSL2.

Enable the Windows 10 ssh-agent service

By default, the OpenSSH ssh-agent service is not enabled in Windows. In order to enable it open PowerShell with administrator privileges and run the following commands:

Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent

The ssh-agent service will now be automatically initiated on boot.

Mount the ".ssh" directory

Start by backing up your existing ".ssh" directory (if any) using the following command (in WSL2):

mv .ssh .ssh-backup

Ensure that the ".ssh" directory exists by running the following command (in WSL2):

mkdir $HOME/.ssh

Add the mountpoint to the fstab file using the following command (in WSL2):

echo >> "C:\\Users\\$(wslvar USERPROFILE)\\.ssh\\ /home/$USER/.ssh drvfs rw,noatime,uid=1000,gid=1000,case=off,umask=0077,fmask=0177 0 0"

Connect to Windows 10 ssh-agent

As the Windows 10 ssh-agent uses named pipes instead of sockets, we need to use npiperelay and socat to establish the connection. Since WSL2 allows running .exe binaries, we can create a setup that automatically starts everything only when you use WSL2.

Install npiperelay inside your WSL2 distro with the following commands (in WSL2):

cd ~
wget https://github.com/jstarks/npiperelay/releases/latest/download/npiperelay_windows_amd64.zip
unzip npiperelay_windows_amd64.zip -d npiperelay
rm npiperelay_windows_amd64.zip

Install socat using the following command (in WSL2):

sudo apt install -y socat

Add the following lines to your .bashrc file (in WSL2) to automatically start npiperelay and socat when your WSL2 user logs in:

# Connect Windows 10 ssh-agent
export SSH_AUTH_SOCK=$HOME/.ssh-agent.sock
ss -a | grep -q $SSH_AUTH_SOCK
if [ $? -ne 0 ]; then
    rm -f $SSH_AUTH_SOCK
    (setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"$HOME/npiperelay/npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork &) >/dev/null 2>&1
fi

Verifying the Setup

To ensure that everything is working as intended, follow these steps:

Restart your WSL2 distro by running the following command in PowerShell on your Windows machine:

wsl --shutdown

In PowerShell and your WSL2 distro, run the command below to list the SSH keys known to the ssh-agent:

ssh-add -l

Compare the output from both environments. If the results match, you have successfully shared your SSH keys and ssh-agent with WSL2.

That's it! You have now simplified SSH usage in the Windows Subsystem for Linux (WSL) by seamlessly integrating Windows SSH keys and the ssh-agent. Enjoy a frictionless experience while using SSH in your WSL2 environment.

Note: This will also work with DevContainers on Windows as well as on WSL2 :)