on
Yubikey, gpg, ssh and WSL2
Update on 07-07-2020
Thanks to the work of Anders Ingemann, the setup process has been simplified.
Using a smartcard to hold your GPG key can be great. Personnaly, I use a Yubikey. Although, by default, you cannot use any device from WSL2, including your smartcard.
To circumvent this issue, I came across several articles treating this topic. Here is what worked for me and a summarized how-to.
We will consider you have your yubikey with gpg keys setup on it, we also consider you use Gpg4Win.
Pre-requisites
npiperelay
As explained in justyn blog article, we will use npiperelay to use gpg4win gpg-agent from WSL2 environment.
- First, download NZSmartie’s version of npiperelay. Place it in
%appdata%\npiperelay\npiperelay.exe
.
Enable windows gpg ssh support and prepare pageant
If you use the GPG keys in your smartcard to authenticate through SSH, you will have to make changes too. Several approaches exists, this one uses https://github.com/benpye/wsl-ssh-pageant and npiperelay (as seen previously) to use windows GnuPG’s ssh pageant.
First, enable SSH support by:
- Locating your gpg-agent.conf (probably in %userprofile%\AppData\Roaming\gnupg\gpg-agent.conf, you may have to create it)
- Add this line
enable-putty-support
Then, visit wsl-ssh-pageant, download the latest version to:
-
Visit release, download the latest version in
%appdata%\wsl-ssh-pageant\wsl-ssh-pageant-amd64-gui.exe
The name of this file is dependant of your architecture and support of GUI. Adapt accordingly if you choose something different than
amd64-gui
variant
Setup the daemon in the WSL2’s side
Thanks to Anders Ingemann’s work, you’ll have a scipt in charge of launching the required tools as a daemon.
Tested on Ubuntu 20.04 with
socat
utility installed. You’ll need to adapt the script yourself for older version. Also, you will want to double check on the provided paths
Visit Anders Ingemann’s gist for the most up to date version:
#!/usr/bin/env bash
# Inspired by https://blog.nimamoh.net/yubi-key-gpg-wsl2/
# Guide:
# Install GPG on windows & Unix
# Add "enable-putty-support" to gpg-agent.conf
# Download wsl-ssh-pageant and npiperelay and place the executables in "C:\Users\[USER]\AppData\Roaming\" under wsl-ssh-pageant & npiperelay
# https://github.com/benpye/wsl-ssh-pageant/releases/tag/20190513.14
# https://github.com/NZSmartie/npiperelay/releases/tag/v0.1
# Adjust relay() below if you alter those paths
# Place this script in WSL at ~/.local/bin/gpg-agent-relay
# Start it on login by calling it from your .bashrc: "$HOME/.local/bin/gpg-agent-relay start"
GNUPGHOME="$HOME/.gnupg"
PIDFILE="$GNUPGHOME/gpg-agent-relay.pid"
die() {
# shellcheck disable=SC2059
printf "$1\n" >&2
exit 1
}
main() {
checkdeps
case $1 in
start)
if ! start-stop-daemon --pidfile "$PIDFILE" --background --notify-await --notify-timeout 5 --make-pidfile --exec "$0" --start -- foreground; then
die 'Failed to start. Run `gpg-agent-relay foreground` to see output.'
fi
;;
stop)
start-stop-daemon --pidfile "$PIDFILE" --remove-pidfile --stop ;;
status)
start-stop-daemon --pidfile "$PIDFILE" --status
local result=$?
case $result in
0) printf "gpg-agent-relay is running\n" ;;
1 | 3) printf "gpg-agent-relay is not running\n" ;;
4) printf "unable to determine status\n" ;;
esac
return $result
;;
foreground)
relay ;;
*)
die "Usage:\n gpg-agent-relay start\n gpg-agent-relay stop\n gpg-agent-relay status\n gpg-agent-relay foreground" ;;
esac
}
relay() {
set -e
local winuser
winuser=$(/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe '$env:UserName')
winuser=${winuser//$'\r'}
local winhome="/mnt/c/Users/$winuser"
local wingnupghome="C:/Users/$winuser/AppData/Roaming/gnupg"
local npiperelay="$winhome/AppData/Roaming/npiperelay/npiperelay.exe"
local wslsshpageant="$winhome/AppData/Roaming/wsl-ssh-pageant/wsl-ssh-pageant-amd64-gui.exe"
local gpgconnectagent="/mnt/c/Program Files (x86)/GnuPG/bin/gpg-connect-agent.exe"
local gpgagentsocket="$GNUPGHOME/S.gpg-agent"
local sshagentsocket="$GNUPGHOME/S.gpg-agent.ssh"
killsocket "$gpgagentsocket"
killsocket "$sshagentsocket"
"$gpgconnectagent" /bye
"$wslsshpageant" --systray --winssh ssh-pageant 2>/dev/null &
WSPPID=$!
socat UNIX-LISTEN:"$gpgagentsocket,unlink-close,fork,umask=177" EXEC:"$npiperelay -ep -ei -s -a '${wingnupghome}/S.gpg-agent'",nofork &
GNUPID=$!
# shellcheck disable=SC2064
trap "kill -TERM $GNUPID" EXIT
socat UNIX-LISTEN:"$sshagentsocket,unlink-close,fork,umask=177" EXEC:"$npiperelay /\/\./\pipe/\ssh-pageant" &
SSHPID=$!
set +e
# shellcheck disable=SC2064
trap "kill -TERM $GNUPID; kill -TERM $SSHPID" EXIT
systemd-notify --ready 2>/dev/null
wait $GNUPID $SSHPID
trap - EXIT
}
killsocket() {
local socketpath=$1
if [[ -e $socketpath ]]; then
local socketpid
if socketpid=$(lsof +E -taU -- "$socketpath"); then
timeout .5s tail --pid=$socketpid -f /dev/null &
local timeoutpid=$!
kill "$socketpid"
if ! wait $timeoutpid; then
die "Timed out waiting for pid $socketpid listening at $socketpath"
fi
else
rm "$socketpath"
fi
fi
}
checkdeps() {
local deps=(socat start-stop-daemon lsof timeout)
local dep
local out
for dep in "${deps[@]}"; do
if ! out=$(type "$dep" 2>&1); then
printf -- "Dependency %s not found:\n%s\n" "$dep" "$out"
return 1
fi
done
}
main "$@"
Then, update your .bashrc
to start the script, considering your script location to ~/.local/bin/gpg-relay-agent
:
$HOME/.local/bin/gpg-agent-relay start
export SSH_AUTH_SOCK=$HOME/.gnupg/S.gpg-agent.ssh
Now, on computer boot, from WSL2, you should be able to see the SSH keys of you yubikey when you type
ssh-add -L
Troubleshooting
- Check relay is running with:
~/.local/bin/gpg-agent-relay status
- Check error of relay script launching it foreground:
~/.local/bin/gpg-agent-relay foreground
- Double check the path you put
npiperelay
andwsl-ssh-pageant
on windows, make sure it corresponds to the ones specified in gpg-agent-relay - Don’t forget to update
gpg-agent.conf
(you may have to restart gpg4win)
Resources
- Using a Yubikey for GPG in WSL (Windows Subsystem for Linux) on Windows 10
- andsens’s gists · GitHub
- Script taken from https://blog.nimamoh.net/yubi-key-gpg-wsl2/ and improved · …
GitHub - vuori/weasel-pageant: Deprecated: An ssh-agent compatible helper for…- How to use GPG with YubiKey (bonus: WSL) — The Coding Nest
- GitHub - benpye/wsl-ssh-pageant: A Pageant -> TCP bridge for use with WSL, al…
- benpye/wsl-ssh-pageant#33 Support for WSL2
- GitHub - jstarks/npiperelay: npiperelay allows you to access Windows named pi…
- Yubico SSH authentication on windows
Knowing so, if you think you found an error or inexact content, you are more than welcome to notify it through comment below ⏬.
Also, if you found the content useful and it helped you, consider leaving a comment too or, better, give me fuel buying me a coffee with the link on the top of the website. 🙏