DEV Community

Cover image for The ultimate guide to Yubikey on WSL2 [Part 2]
Jaroslav Živný
Jaroslav Živný

Posted on • Updated on • Originally published at jardazivny.Medium

The ultimate guide to Yubikey on WSL2 [Part 2]

In the Previous part we configured OpenGPG with Yubikey. In case you have it done, we can continue on how to access your YubiKey in WSL2.

Disclaimer: This tutorial is written for WSL2 with Ubuntu. It may differ distro from distro.


Access your YubiKey in WSL2

Prerequisites

Install socat and wsl2-ssh-pageant in WSL:

# WSL2
$ sudo apt install socat scdaemon
$ mkdir ~/.ssh
$ wget https://github.com/BlackReloaded/wsl2-ssh-pageant/releases/download/v1.4.0/wsl2-ssh-pageant.exe -O ~/.ssh/wsl2-ssh-pageant.exe
$ chmod +x ~/.ssh/wsl2-ssh-pageant.exe
Enter fullscreen mode Exit fullscreen mode

Sync sockets

This part is inspired by this tutorial.

Edit your ~/.bashrc or ~/.zshrc - depends on your shell (e.g. via nano or vim) and add following content:

config_path="C\:/Users/<YOUR_USER>/AppData/Local/gnupg"
wsl2_ssh_pageant_bin="$HOME/.ssh/wsl2-ssh-pageant.exe"
# SSH Socket
# Removing Linux SSH socket and replacing it by link to wsl2-ssh-pageant socket
export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
if ! ss -a | grep -q "$SSH_AUTH_SOCK"; then
  rm -f "$SSH_AUTH_SOCK"
  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
fi
# GPG Socket
# Removing Linux GPG Agent socket and replacing it by link to wsl2-ssh-pageant GPG socket
export GPG_AGENT_SOCK="$HOME/.gnupg/S.gpg-agent"
if ! ss -a | grep -q "$GPG_AGENT_SOCK"; then
  rm -rf "$GPG_AGENT_SOCK"
  if test -x "$wsl2_ssh_pageant_bin"; then
    (setsid nohup socat UNIX-LISTEN:"$GPG_AGENT_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin --gpgConfigBasepath ${config_path} --gpg S.gpg-agent" >/dev/null 2>&1 &)
  else
    echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable."
  fi
fi
Enter fullscreen mode Exit fullscreen mode

Restart WSL by running

# CMD
wsl.exe --shutdown
Enter fullscreen mode Exit fullscreen mode

When you open Ubuntu Terminal now and run gpg --card-status you should be able to see something like this:

gpg --card-status

Import GPG key to WSL2

If you check GPG keys availible in WSL2 via gpg --list-keys or gpg --list-secret-keys you get empty results. We have to first import them. It’s quite easy just run:

# WSL2
$ gpg --card-edit
Enter fullscreen mode Exit fullscreen mode

This will open gpg command interface. Just type in fetch. It’ll get you public keys from keys.openpgp.org (we uploaded them there in the previous part

In case you haven’t uploaded the public keys to keys.openpgp.org (as shown in the part 1 of this tutorial). You can import it via asc file (exported in part 1) via:

gpg --import PATH_TO_ASC_FILE

Exit the gpg command interface via quit

If you now run gpg --list-keys you finally get your keys.

gpg --list-keys

Great success!

Now we are missing one small step. As you can see. The trustworthiness of our certificate is unknown (information next to the name). We can change it via running:

# WSL2
$ gpg --edit-key YOUR_KEY_ID # In my case 1E9...
Enter fullscreen mode Exit fullscreen mode

This opens gpg console insterface. Write:

# WSL2
trust # Change trust level
5     # Set trust level to ultimate
save  # Save the changes
Enter fullscreen mode Exit fullscreen mode

If you list keys via gpg --list-keys now. You should be able to see [ultimate] next to your name.

Additional Tips

Yubikey stopped working on WSL

  1. Unplug Yubikey
  2. Shutdown wsl wsl --shutdown
  3. Shutdown Kleopatra in Task manager
  4. Shutdown wsl2-ssh-pageant in Task manager
  5. Start Kleopatra
  6. Start wsl - open a new window
  7. Plug in the Yubikey

Getting "error: Couldn't load public key XXX No such file or directory?"

Unset gpg.format via 

git config - global - unset gpg.format
Enter fullscreen mode Exit fullscreen mode

We’ll continue in the part 3.

Top comments (7)

Collapse
 
byteduty profile image
Colin Docherty • Edited

Any suggestion on debugging if gpg-agent keeps starting on Ubuntu wsl, when I do gpg --card-status ?
I've followed the guide multiple times, and I repeated it also in the Debian wsl.
I can successfully use "ssh-add -L" and I can access my Yubikey stored ssh key no problem.
However, when I do gpg --card-status I get a delay, then:

$ gpg --card-status
gpg: can't connect to the agent: End of file
gpg: OpenPGP card not available: No agent running

pstree then shows gpg-agent running, even though it wasn't previously.

This is the state of processes before I run gpg --card-status:

colin 25 0.0 0.0 6968 1832 ? Ss 11:50 0:00 socat UNIX-LISTEN:/home/colin/.ssh/agent.sock,fork EXEC:/home/colin/.ssh/wsl2-ssh-pageant.exe
colin 29 0.0 0.0 6968 1776 ? Ss 11:50 0:00 socat UNIX-LISTEN:/home/colin/.gnupg/S.gpg-agent,fork EXEC:/home/colin/.ssh/wsl2-ssh-pageant.exe --gpg S.gpg-agent

This is the state of process after I run gpg --card-status

$ gpg --card-status
gpg: can't connect to the agent: End of file
gpg: OpenPGP card not available: No agent running
colin@letham:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2424 1032 ? Sl 11:50 0:00 /init
root 7 0.0 0.0 1752 68 ? Ss 11:50 0:00 /init
root 8 0.0 0.0 1752 76 ? S 11:50 0:00 /init
colin 9 0.0 0.0 10040 5048 pts/0 Ss 11:50 0:00 -bash
colin 25 0.0 0.0 6968 1832 ? Ss 11:50 0:00 socat UNIX-LISTEN:/home/colin/.ssh/agent.sock,fork EXEC
colin 29 0.0 0.0 6968 3380 ? Ss 11:50 0:00 socat UNIX-LISTEN:/home/colin/.gnupg/S.gpg-agent,fork E
colin 583 0.0 0.0 82952 972 ? Ss 11:52 0:00 gpg-agent --homedir /home/colin/.gnupg --use-standard-s
colin 597 0.0 0.0 10620 3308 pts/0 R+ 11:52 0:00 ps aux

gpg --card-status is running fine in the Windows terminal.

I'm running wsl2, on Windows 11, on a new Surface Pro 8. I've also managed to previously get this running on my HP Running Windows 11 a few weeks ago, although this was probably using instructions elsewhere.

Collapse
 
ryanjaeb profile image
Ryan Jaeb

You may be running into this. With newer versions of gnupg4win the windows socket file (S.gpg-agent) ends up in ...\AppData\Local\..., but wsl2-ssh-pageant is expecting ...\AppData\Roaming\....

Collapse
 
phillipmcmahon profile image
Phillip

I am also seeing this same error on a new install of Windows 10. On that side of things all is working fine, gpg and ssh all recognise my yubikey and I am prompted for my PIN etc.

Prior to my rebuild, I had this working on my WSL Ubuntu instance but now getting this error. socat, scdaemon, ss, etc. all installed. ssh works and I am prompted for my PIN, just no joy at all with gpg.

"gpg: selecting card failed: No such device
gpg: OpenPGP card not available: No such device"

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 1052 668 ? Sl 11:00 0:00 /init
root 8 0.0 0.0 900 84 ? Ss 11:00 0:00 /init
root 9 0.0 0.0 900 84 ? S 11:00 0:00 /init
phillip+ 10 0.0 0.0 10036 5004 pts/0 Ss 11:00 0:00 -bash
phillip+ 26 0.0 0.0 6968 1744 ? Ss 11:00 0:00 socat UNIX-LISTEN:/home/phillipmcmahon/.ssh/agent.sock,fork EXEC:/home/phillipmcmahon/.ssh/wsl2-ssh-pageant.exe
phillip+ 30 0.0 0.0 6968 3192 ? Ss 11:00 0:00 socat UNIX-LISTEN:/home/phillipmcmahon/.gnupg/S.gpg-agent,fork EXEC:/home/phillipmcmahon/.ssh/wsl2-ssh-pageant.exe --gpg S.gpg-agent
phillip+ 485 0.0 0.0 82952 2640 ? Ss 11:00 0:00 gpg-agent --homedir /home/phillipmcmahon/.gnupg --use-standard-socket --daemon
phillip+ 574 0.0 0.0 93772 3472 ? SLl 11:07 0:00 scdaemon --multi-server
phillip+ 578 0.0 0.0 10620 3192 pts/0 R+ 11:08 0:00 ps aux
phillip+ 579 0.0 0.0 10036 1700 pts/0 D+ 11:08 0:00 -bash

Collapse
 
genebean profile image
Gene Liverman

I am on Windows 11 and ssh works fine in WSL2 but I can't seem to get the gpg side to work. I have gpg4win installed via chocolatey. I am using this:

# Utilize Yubikey and SSH from Windows
wsl2_ssh_pageant_bin="$HOME/.ssh/wsl2-ssh-pageant.exe"
if [[ ! -f "${wsl2_ssh_pageant_bin}" ]]; then
  windows_destination="/mnt/c/Users/Public/Downloads/wsl2-ssh-pageant.exe"
  if [[ ! -f "${windows_destination}" ]]; then
    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"
  fi
  # Symlink to linux for ease of use later
  ln -s $windows_destination $wsl2_ssh_pageant_bin
fi

export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"
if ! ss -a | grep -q "$SSH_AUTH_SOCK"; then
  rm -f "$SSH_AUTH_SOCK"
  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
fi

export GPG_AGENT_SOCK="$HOME/.gnupg/S.gpg-agent"
if ! ss -a | grep -q "$GPG_AGENT_SOCK"; then
  rm -rf "$GPG_AGENT_SOCK"
  windows_username=$(cmd.exe /c echo %USERNAME% 2>/dev/null | tr -d '\r')
  # When gpg4win is installed with scoop or chocolatey, the pipe is in the local directory
  if [ -d "/mnt/c/Users/$windows_username/AppData/Local/gnupg" ]; then
    config_path="C:/Users/$windows_username/AppData/Local/gnupg"
  else
    config_path="C:/Users/$windows_username/AppData/Roaming/gnupg"
  fi

  if test -x "$wsl2_ssh_pageant_bin"; then
    (setsid nohup socat UNIX-LISTEN:"$GPG_AGENT_SOCK,fork" EXEC:"$wsl2_ssh_pageant_bin -verbose --gpgConfigBasepath ${config_path} --gpg S.gpg-agent" >/dev/null 2>&1 &)
  else
    echo >&2 "WARNING: $wsl2_ssh_pageant_bin is not executable."
  fi
  unset windows_username config_path
fi

unset wsl2_ssh_pageant_bin
Enter fullscreen mode Exit fullscreen mode

I am pretty sure I have every package anyone in any debugging thread has mentioned:

$ apt list --installed |grep 'gpg\|scdaemon\|iproute2'

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

gpg-agent/jammy-updates,jammy-security,now 2.2.27-3ubuntu2.1 amd64 [installed,automatic]
gpg-wks-client/jammy-updates,jammy-security,now 2.2.27-3ubuntu2.1 amd64 [installed,automatic]
gpg-wks-server/jammy-updates,jammy-security,now 2.2.27-3ubuntu2.1 amd64 [installed,automatic]
gpg/jammy-updates,jammy-security,now 2.2.27-3ubuntu2.1 amd64 [installed,automatic]
gpgconf/jammy-updates,jammy-security,now 2.2.27-3ubuntu2.1 amd64 [installed,automatic]
gpgsm/jammy-updates,jammy-security,now 2.2.27-3ubuntu2.1 amd64 [installed,automatic]
gpgv/jammy-updates,jammy-security,now 2.2.27-3ubuntu2.1 amd64 [installed,automatic]
iproute2/jammy,now 5.15.0-1ubuntu2 amd64 [installed]
libgpg-error0/jammy,now 1.43-3 amd64 [installed,automatic]
libgpgme11/jammy,now 1.16.0-1.2ubuntu4 amd64 [installed,automatic]
scdaemon/jammy-updates,jammy-security,now 2.2.27-3ubuntu2.1 amd64 [installed]
Enter fullscreen mode Exit fullscreen mode

Here's info on my install of WSL also:

PS C:\ > wsl --version
WSL version: 0.70.0.0
Kernel version: 5.15.68.1
WSLg version: 1.0.45
MSRDC version: 1.2.3575
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22000.1098
Enter fullscreen mode Exit fullscreen mode

Anyone have any idea why this isn't working?

Collapse
 
luizvessosa profile image
Luiz Vessosa

Together with:
sudo apt install socat
this should be installed otherwise will not work:
sudo apt-get install scdaemon

Collapse
 
dzerycz profile image
Jaroslav Živný

Thanks for your feedback. scdaemon is usually installed with GnuPG in Windows

Collapse
 
jmz0 profile image
James Crace

Thanks for this awesome guide!