Published: Jan 03, 2023

WSL - Use SSH Keys From Host

Introduction

WSL is a great addition to Windows since it allows running a full Linux distribution without the overhead of a virtual machine or dual boot setup. Recent versions are even able to run GUI applications using WSLg and fully utilize your GPU. While I would prefer to always use Linux there are still some issues that force me to run Windows sometimes (mostly related to limitations of x11 and wayland not being quite ready yet).

I like to create bash scripts to assist in tasks like testing or deployment and didn’t feel like rewriting them in batch or powershell just for the occasional use on Windows. Some of these scripts also rely on other utilities not available for Windows. Running those scripts using WSL was straightforward except when they needed access to my private SSH keys. The SSH keys are stored in a KeePass database and made available to the Windows Open SSH service while the database is unlocked.

Open SSH is able to “connect” to another Open SSH instance via SSH_AUTH_SOCK but Windows uses named pipes while Linux uses sockets. As usual there are multiple solutions, some of which are:

  • Run another instance of KeePass in WSL
  • Save the private key file on disk
  • Connect the named pipe and socket

This post will describe the last option.

Windows

On the Winows side npiperelay is used. There is no binary available, but thanks to golang it’s easy to build from source. Make sure golang is installed and run:

git clone https://github.com/jstarks/npiperelay
go install

Now you should be able to find npiperelay using which npiperelay.

WSL

On the WSL side socat is used. Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them. Socat can usually be installed using your package manager like apt install socat. Now create a new bash script to establish the connection:

socat 
    UNIX-LISTEN:"$HOME/.ssh/wsl-ssh-agent.sock",fork 
    EXEC:"$(which npiperelay.exe) -ei -s //./pipe/openssh-ssh-agent",nofork 2>&1 &

export SSH_AUTH_SOCK=$HOME/.ssh/wsl-ssh-agent.sock

That’s it. If you run ssh-add -L in WSL you should see your SSH key.