Yubikey for SSH on windows with WSL2
Recently I had to re-setup my laptop for some dev work, and unfortinatly most guides appear to be out of date and/or dont cover some issues I encountered along the way.
Note this will not cover generating the keys or saving them to the yubikey.
Windows setup
Step 1 Download and install GPG4Win, for this guide you will need version 4.1.0 or higher.
Step 2 Enable SSH support by editing the gpg-agent.conf file located in the gnupg directory %APPDATA%.gnupg\ on Windows, where the typical path is C:\Users<username>\AppData\Roaming. Add the following lines to it:
enable-ssh-support
To Enable support for PuTTY
enable-putty-support
To Enable support for the native Microsoft OpenSSH binaries (requires gpg 2.4.0 / Gpg4win 4.1.0 or higher)
enable-win32-openssh-support
use-standard-socket
default-cache-ttl 600
max-cache-ttl 7200
Step 3 start (or restart) the gpg agent using the following commands
gpg-connect-agent killagent /bye
gpg-connect-agent /bye
Step 4 set the SSH_AUTH_SOCKET`` Environment variable to
\.\pipe\openssh-ssh-agent`, the following powershell can do this for you
[System.Environment]::SetEnvironmentVariable('SSH_AUTH_SOCKET','\\.\pipe\openssh-ssh-agent', 'User')
From here you should be able to see your key when your run ssh-add -L
in windows, and see the card status with gpg --card-status
WSL setup
Step 1 download the agent that will provide access in WSL
windows_destination="/mnt/c/Users/Public/Downloads/wsl2-ssh-pageant.exe"
linux_destination="$HOME/.ssh/wsl2-ssh-pageant.exe"
wget -O "$windows_destination" "https://github.com/BlackReloaded/wsl2-ssh-pageant/releases/latest/download/wsl2-ssh-pageant.exe"
# Set the executable bit.
chmod +x "$windows_destination"
# Symlink to linux for ease of use later
ln -s $windows_destination $linux_destination
NOTE: change the windows_destination in the first line to a location that you want the executable stored, this MUST be on your windows drive to run correctly.
Step 2 to enable SSH add the following to your ~/.bashrc
file
export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
if ! ss -a | grep -q "$SSH_AUTH_SOCK"; then
rm -f "$SSH_AUTH_SOCK"
wsl2_ssh_pageant_bin="$HOME/.ssh/wsl2-ssh-pageant.exe"
if test -x "$wsl2_ssh_pageant_bin"; then
(setsid nohup socat UNIX-LISTEN:"$SSH_AUTH_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin" >/dev/null 2>&1 &)
else
echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable."
fi
unset wsl2_ssh_pageant_bin
fi
Step 3 to enable GPG add the following to your ~/.bashrc
file
export GPG_AGENT_SOCK="$HOME/.gnupg/S.gpg-agent"
if ! ss -a | grep -q "$GPG_AGENT_SOCK"; then
rm -rf "$GPG_AGENT_SOCK"
wsl2_ssh_pageant_bin="$HOME/.ssh/wsl2-ssh-pageant.exe"
if test -x "$wsl2_ssh_pageant_bin"; then
(setsid nohup socat UNIX-LISTEN:"$GPG_AGENT_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin --gpg S.gpg-agent" >/dev/null 2>&1 &)
else
echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable."
fi
unset wsl2_ssh_pageant_bin
fi
After reloading your shell session in wsl both ssh-add -L
and gpg --card-status
should now work and confirm everything is configured correctly.
Items to note
If you have systemd enabled in your WSL distro it will automaticly start the linux GPG agent and prevent gpg --card-status
from working, however ssh will still work. I have not yet found a work around for this.