This is a follow-up to my WSL2 hack enabling Systemd to run enabling all the awesome features such as service management and session management. The session management enables most graphical or GUI applications in the WSL2 Distro to function without issue when combined with an appropriate Windows-based X11 server such as X410, MobaXTerm or VCXSRV.
So, you're working away in your WSL2 distro and then you want to sign a GIT commit with your PGP key which is backed by a Hardware Security Module like a YubiKey. Or you want to SSH into a remote system using an SSH key that has a long and difficult to remember password. Both activities can be improved or enabled by using Windows-based "Agents". For PGP we can use GPG4Win's gpg-agent
and for SSH we can use the SSH agent that is shipped with Windows.
Installation
We only need to install GPG4Win, because Windows comes with the SSH Agent out of the box. So, to install GPG4Win we'll use winget. In a CMD or PowerShell window run:
winget.exe install gpg4win
Loading your keys
Next we load your Private SSH or PGP keys or HSM-backed Public PGP keys into the Windows agents. For SSH keys this is easy; simply copy the keys to C:\Users\<your-username>\.ssh\
.
For PGP keys, use the Start Menu to open Kleopatra. If you are using an HSM you only need the public key as a file or the fingerprint ID to lookup the public key on a key server. To import a file-based key select "File" and then "Import" (or press ctrl+I
), locate your key file in the browser, and click "Open". To lookup a public key on a key server with the key ID select "File" and then "Lookup on server" (or press ctrl+shift+I
). In the dialog that opens enter your key's fingerprint ID, click search, select the correct key from the list and finally click "Import".
Ensuring the agents start automatically
For SSH Agent this is easy to do with PowerShell. Open the run dialog by pressing win+r
and type powershell into the text box and finally pressing ctrl+shift+enter
to start it in a privileged mode. Now we type the following into the PowerShell window and then you can close it because we're finished there:
Set-Service ssh-agent -StartupType automatic
Start-Service ssh-agent
To start the GPG agent open a new unprivileged PowerShell window and run:
& 'C:\Program Files (x86)\GnuPG\bin\gpg-connect-agent.exe' /bye
However, that only starts the agent once for your current session. To get it started every time you login you can open a privileged PowerShell like we did with the SSH agent above and run:
Register-ScheduledJob -Name GPGAgent -Trigger (New-JobTrigger -AtLogOn) -RunNow -ScriptBlock {
& "${env:ProgramFiles(x86)}/GnuPG/bin/gpg-connect-agent.exe" /bye
}
Tying the agents to WSL2
First you need your Distro to have the WSLUtilities installed. On Ubuntu these are already present. Follow the steps on the linked GitHub page for your Distro.
Next, we need socat
if it isn't already installed:
sudo apt update
sudo apt install -yyq socat
Now, place the following code into a file in your Distro at /etc/profile.d/wsl2-ssh-gpg-agents.sh
. This presumes that your Distro automatically parses files in /etc/profile.d
:
NPIPERELAY_URL="https://github.com/NZSmartie/npiperelay/releases/download/v0.1/npiperelay.exe"
if [ -n "$WSL_DISTRO_NAME" ]; then
APPDATA="$(wslvar appdata)"
APPDATA="${APPDATA//\\/\/}"
NPIPERELAY_WIN="$APPDATA/wsl2-ssh-gpg-npiperelay.exe"
NPIPERELAY="$(wslpath "$NPIPERELAY_WIN")"
if [ ! -f "$NPIPERELAY" ]; then
curl -L -q -o "$NPIPERELAY" "$NPIPERELAY_URL"
fi
#####
## Autorun for the gpg-relay bridge
##
SOCAT_PID_FILE=$HOME/.gnupg/socat-gpg.pid
SOCAT_PID_FILE2=$HOME/.gnupg/socat-gpg.pid.2
for GPG_SOCK in "$HOME/.gnupg/S.gpg-agent" "/run/user/$UID/gnupg/S.gpg-agent"; do
if ! ss -a | grep -q "$GPG_SOCK"; then
rm -f "$GPG_SOCK"
mkdir -p "$(dirname "$GPG_SOCK")"
setsid --fork socat UNIX-LISTEN:"$GPG_SOCK",fork EXEC:"$NPIPERELAY -ei -ep -s -a "'"'"$APPDATA"/gnupg/S.gpg-agent'"',nofork
fi
done
#####
## Autorun for the ssh-relay bridge
##
export SSH_AUTH_SOCK=$HOME/.ssh/agent.sock
if ! ss -a | grep -q "$SSH_AUTH_SOCK"; then
rm -f "$SSH_AUTH_SOCK"
setsid --fork socat UNIX-LISTEN:"$SSH_AUTH_SOCK",fork EXEC:"$NPIPERELAY -ei -s //./pipe/openssh-ssh-agent",nofork
fi
fi
Finishing up
You're done. Just restart your WSL2 session and you'll be able to use the GPG and SSH agents hosted on Windows from within the Linux environment. This also works for Yubikey-backed PGP keys!
I hope to return to this soon to automate the installation the way that Damion Gans did for the Systemd hack.
Top comments (0)