/wsl2-ssh-agent

A bridge from WSL2 ssh client to Windows ssh-agent.exe service

Primary LanguageGoMIT LicenseMIT

wsl2-ssh-agent

This tool allows from WSL2 to use the ssh-agent service on Windows host.

How to use

1. Install wsl2-ssh-agent

Put wsl2-ssh-agent binary in your favorite directory in WSL2, for example, $HOME/.

curl -L -O https://github.com/mame/wsl2-ssh-agent/releases/latest/download/wsl2-ssh-agent

If you are under ARM64 architecture, download the arm64 binary instead:

curl -L -O https://github.com/mame/wsl2-ssh-agent/releases/latest/download/wsl2-ssh-agent-arm64

Change permisions so the binary is executable:

chmod 755 wsl2-ssh-agent

If you are using ArchLinux, you can install the wsl2-ssh-agent package from the AUR (maintained by @Hill-98).

2. Modify your shell's rc file

bash or zsh

Add the following line to .bashrc (or .zshrc if you are using zsh).

eval $($HOME/wsl2-ssh-agent)

fish

Add the following lines to config.fish

if status is-login
  $HOME/wsl2-ssh-agent | source
end

3. Reopen your terminal

Close and reopen the terminal and execute ssh your-machine. The command should communicate with ssh-agent.exe service.

Troubleshooting

Make sure that ssh-agent.exe is working properly

  • Open the "Services" app and check that "OpenSSH Authentication Agent" service is installed and running.
  • Check that ssh your-machine works perfect on cmd.exe or PowerShell, not on WSL2.

Check the log of ssh

  • You may want to run ssh -v your-machine and read the log. If everything is good, you should see the following log.
debug1: get_agent_identities: bound agent to hostkey
debug1: get_agent_identities: agent returned XXX keys

Check the log of wsl2-ssh-agent

  • Run wsl2-ssh-agent in verbose and foreground mode and read the log. This is an example output.
# Stop the existing server if any
$ $HOME/wsl2-ssh-agent -stop

# Run in foreground mode
$ $HOME/wsl2-ssh-agent --verbose --foreground
[L] 2023/02/10 20:30:00 check the version of ssh.exe
[L] 2023/02/10 20:30:01 the version of ssh.exe: "OpenSSH_for_Windows_8.6p1, LibreSSL 3.4.3"
[L] 2023/02/10 20:30:01 ssh-agent.exe seems to be old; ignore OpenSSH extension messages
[L] 2023/02/10 20:30:01 start listening on /home/mame/.ssh/wsl2-ssh-agent.sock
[L] 2023/02/10 20:30:01 invoking [W] in PowerShell.exe
[W] 2023/02/10 21:51:09 ready: PSVersion 5.1.22621.963
[L] 2023/02/10 20:30:02 [W] invoked successfully
[L] 2023/02/10 20:30:05 ssh: connected
[L] 2023/02/10 20:30:05 ssh -> [L] (XXX B)
[L] 2023/02/10 20:30:05 ssh <- [L] (5 B) <dummy for OpenSSH ext.>
[L] 2023/02/10 20:30:05 ssh -> [L] (5 B)
[L] 2023/02/10 20:30:05 [L] -> [W] (5 B)
[W] 2023/02/10 21:51:12 [L] -> [W] -> ssh-agent.exe (5 B)
[W] 2023/02/10 21:51:12 [L] <- [W] <- ssh-agent.exe (XXX B)
[L] 2023/02/10 20:30:05 [L] <- [W] (XXX B)
[L] 2023/02/10 20:30:05 ssh <- [L] (XXX B)
[L] 2023/02/10 20:30:05 ssh -> [L] (XXX B)
[L] 2023/02/10 20:30:05 [L] -> [W] (XXX B)
[W] 2023/02/10 21:51:12 [L] -> [W] -> ssh-agent.exe (XXX B)
[W] 2023/02/10 21:51:12 [L] <- [W] <- ssh-agent.exe (XXX B)
[L] 2023/02/10 20:30:05 [L] <- [W] (XXX B)
[L] 2023/02/10 20:30:05 ssh <- [L] (XXX B)
[L] 2023/02/10 20:30:05 ssh: closed

How wsl2-ssh-agent works

Linux ssh client connects to ssh-agent via a UNIX domain socket, while ssh-agent.exe service on Windows is listening on a named pipe. This command connects those two in the following mechanism.

graph TB
subgraph WSL2
  A(ssh) <-->|UNIX domain socket| B("wsl2-ssh-agent")
end
subgraph Windows
  B <-->|stdin/stdout| C("PowerShell.exe")
  C <-->|named pipe| D(ssh-agent.exe)
end
  • wsl2-ssh-agent listens on a UNIX domain socket (by default, $HOME/.ssh/wsl2-ssh-agent.sock).
  • wsl2-ssh-agent invokes PowerShell.exe as a child process, which can communicate with ssh-agent.exe service via a named pipe.
  • wsl2-ssh-agent and PowerShell.exe communicates via stdin/stdout thanks to WSL2 interop.

Note

Usually, ssh and ssh-agent should be the same version. However, OpenSSH on Ubuntu 22.04 is 8.9, while Windows bundles OpenSSH 8.6 (on my machine, as of this writing).

OpenSSH has extended the ssh-agent protocol since 8.9. However, ssh-agent.exe does not understand the extended message and will not communicate properly. (Japanese article)

To address this issue, wsl2-ssh-agent does not pass the extended message to ssh-agent.exe. Instead, it swallows the message and reply a dummy SSH_AGENT_SUCCESS message to ssh client. Note that this may reduce the security strength. Please use this tool at your own risk.