Skip to content

Use Windows ssh-agent from Linux with WSL2

Motivation

It's annoying to enter your ssh key password to unlock it every time you reboot. In newer versions of Windows, you don't have to, as Windows now has a native version of OpenSSH.

When you add keys to the ssh-agent (e.g.ssh-add C:\Users\me\.ssh\id_ed25519, it asks you for your ssh key password. The Windows GUI keychain function attaches this password to your Windows user password, so that when you log into your Windows account, the SSH keys in ssh-agent are automatically unlocked.

This is all fine and dandy until you start using WSL and want to SSH from your Linux environment. the Linux ssh-agent can't use the GUI keychain functionality if there is no GUI, the Linux keychain CLI tool doesn't store passwords between reboots, and Linux's ssh command can't communicate with the Windows ssh-agent.

Until now.

Tutorial

First, make sure you have the latest OpenSSH (>= 9.1.0) installed.

# (optional) Uninstall old OpenSSH version first in "Optional features" if it's already installed / enabled
Remove-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Remove-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0

Then, download the latest version here:

https://github.com/PowerShell/Win32-OpenSSH/releases

For this tutorial, we won't need to install the OpenSSH server, just the Client. Either click on the msi installer and select the option to install the Client but not the server, or you can do it like this (additional details here: https://github.com/PowerShell/Win32-OpenSSH/wiki/Install-Win32-OpenSSH-Using-MSI):

msiexec /i <path to openssh.msi> ADDLOCAL=Client

Ensure ssh-agent is running by making sure the named pipe exists. You can see if you find openssh-ssh-agent at this page in Chrome (NOT Firefox) file://./pipe//, or run the following command in PowerShell/CMD:

# Ensure named pipe for ssh-agent exists. ( Can use browser to browse to  ), or run
dir \\.\pipe\openssh-ssh-agent

Now that OpenSSH is set up, we need to install Go (using winget) so that we can install npiperelay

winget install -e --id GoLang.Go.1.19
# npiperelay saves the day!
go install github.com/jstarks/[email protected]

Now that npiperelay is installed, we just need to set up our Linux environment in WSL to connect to the Windows ssh-agent when bash starts. A slick way to do this is to use a systemd user service:

Create this file $HOME/.config/systemd/user/relay-ssh-agent.service:

[Unit]
Description=Relay ssh-agent from Windows to WSL using npiperelay
After=network.target

[Service]
ExecStart=socat UNIX-LISTEN:/tmp/ssh-agent-wsl,umask=007,fork EXEC:"npiperelay.exe -ep -s //./pipe/openssh-ssh-agent",nofork

[Install]
WantedBy=default.target

Link npiperelay.exe to /usr/local/bin so that it can be executed from anywhere in Linux

# Link npiperelay.exe from windows place in Linux path
ln -s /usr/local/bin/npiperelay.exe /mnt/c/Users/joba/go/bin/npiperelay.exe

Run systemctl --user start relay-ssh-agent.service to start the service! You can enable the service so that it runs whenever Linux starts.

Now start a new shell and run ssh-add -L to verify your Windows keys are accessible from your Linux console. You should now be able to ssh into any of your hosts from Linux without entering a password!

Published inDevelopment

Be First to Comment