Setting up Yubikey for ssh on Windows and WSL

When I became the proud owner of a Yubikey 5 nfc device and found out that it can be used to log in via ssh, I came across a lot of articles about setting up such a bundle on unix systems … And with a complete lack of adequate material about Windows.
Having understood the topic, collecting information from many sources and checking the performance of the bundle on personal experience, I am writing this article for those who decide to repeat my path.

I assume that by reading my guide, you have already created gpg keys in the configuration you need and written them to the Yubikey. There is a lot of information on how to do this, and the instructions are the same for Linux and Windows.
Also, I assume that you already have the latest version of GnuPG installed on your system (at the time of writing, version 2.40), and you know how to deal with it basicly.

You can read about creating keys and writing them to Yubikey here.

You can download GnuPg for Windows here (At least I used gpg4win).

After completing all the steps below, you will get:

  • Ability to use Yubikey along with OpenSSH on Windows;
  • Ability to use Yubikey along with ssh inside Wsl.

Before proceeding with the setup, make sure that:

  • You have Windows 10 version 1803 or later installed;
  • You have gpg4win or another version of GnuPg installed;
  • Command gpg --card-status correctly displays information about your Yubikey and the keys written on it;
  • The corresponding public keys are stored in gpg on the computer and displayed on command gpg --list-keys.

First of all, we need to change the GnuPg configuration so that GnuPg uses gpg-agent and also enable OpenSsh support in the agent itself.

First, let’s figure out where GnuPg will look for configuration files. To do this, enter the following on the command line:

gpgconf --list-dirs homedir
In response, we will receive the path where all gpg data and settings are stored on your system.
Next, you need to open the folder at the specified path and create two files in the folder: gpg.conf and gpg-agent.conf.

Then, in the gpg.conf file, we must write the following:

use-agent
This will tell gpg to use the gpg-agent.

And in the gpg-agent.conf file we write this:

enable-putty-support
enable-ssh-support

If you have Windows OpenSsh version 9.0 or later installed on your system, you can add the following on the third line:

enable-win32-openssh-support
Why this is necessary, I will explain a little later.

Now, by changing the gpg configuration, we can start gpg-agent with this command:

gpg-connect-agent /bye
And stop the running agent using the command

gpg-connect-agent killagent /bye

After making sure that the agent starts without errors, we need to create another file in the gnupg directory.
The file should be called sshcontrol and keygrip your authentication key (i.e. the key with capability a) into it.

To get the keygrip ‘s of all your keys, use the command

gpg --list-keys --with-keygrip

The output of the command will look something like this:

pub   rsa4096 2022-07-18 [SC]
      58DE66838D1CFAD22A5283F3AEFB45ACA247412F
      Keygrip = B53F9C92114AB637817A4EE28242654636D718A2
uid           [ultimate] Kirill Belousov <belousov.k.m@yandex.ru>
uid           [ultimate] Kirill Belousov <bkm.grotschool@yandex.ru>
uid           [ultimate] Kirill Belousov <funnytastymeat@gmail.com>
sub   rsa4096 2022-07-18 [E]
      Keygrip = B68CC0A9905D5737547DDC8AEA532259F2679107
sub   rsa4096 2022-07-18 [A]
      Keygrip = B21B4285DC89262A7EF194E68C73AE76C793D591

Notice the last two lines. Letter [a] in square brackets means that the subkey is intended specifically for authentication, and the line keygrip=... – and there is the required keygrip.
You need to copy everything that is written after keygrip= and paste in the sshcontrol.
Please note that there must not be empty lines before and after the inserted line, and there must not be spaces at the beginning and end of the line itself.

After saving the sshcontrol file, restart gpg-agent using the above commands.

After starting gpg-agent, a socket will appear in the system, with the help of which ssh can connect to gpg and request ssh keys … On linux.
Ssh on Windows cannot work with such sockets. That is why we need an external utility called wsl-ssh-pageant.

You can download the utility here.
Two versions of the program are available for download: a command line version (launched with a command line window that will hang open while the program is running), and a gui version that runs in the background, does not “glow” the command line window and can only be stopped through the task manager or using the icon in the system tray.
For use with the task scheduler (for automatic launch), the first option is more suitable, and for manual launch by clicking on the shortcut, the second one. But which version to use is entirely your choice, they are identical in functionality.

After downloading the utility and saving it in a convenient place, run it with the following parameters:

--wsl C:\path\to\wsl\socket.sock --winssh pipe-name-for-windows-ssh --systray --force

Parameter --wsl <path> allows you to specify the path where the socket file for wsl will be created. If you don’t need Wsl support, you can omit this parameter.

--winssh <pipe-name> allows you to specify a name for a named pipe that OpenSsh on Windows will use to try to connect to the agent.

--systray turns on the display of the icon in the system tray,
a --force restarts the utility and recreates all entities if the utility is already running (useful for quick restart by clicking on a shortcut).

I usually start the gui version of the program with a shortcut with the following content:

C:\wsl-ssh-pageant\wsl-ssh-pageant-amd64-gui.exe --wsl C:\wsl-ssh-pageant\ssh-agent.sock --winssh ssh-pageant --systray --force

After running the utility and making sure that it started without errors (by the tray icon or by the output of the command line), let’s move on to the last step.

The final touch, after which everything should work, will be setting an environment variable with which Windows OpenSsh will look for a connection to gpg through the utility configured above.

To add the necessary environment variable, run the command on the command line

setx SSH_AUTH_SOCK \\.\pipe\<name>
Instead of <name> substitute what you specified in the parameter --winssh when running wsl-ssh-pageant.

If you need ssh authentication with Yubikey in Wsl, you must create the SSH_AUTH_SOCK environment variable in Wsl and set its value to the path to the socket file created by wsl-ssh-pageant.
In my case, the command looks like this:

export SSH_AUTH_SOCK=/mnt/c/wsl-ssh-pageant/ssh-agent.sock

Note: despite the fact that all instructions describe exactly this algorithm for Wsl, it did not work on my system. There may be additional steps that I don’t know about.

For those with Windows OpenSsh version 9.0

When configuring gpg, I mentioned the “not for everyone” option.
If you have gpg version 2.40 or later and Windows Openssh version 9.0 or later, you can bypass wsl-ssh-pageant and use gpg-agent and ssh directly.

If, when filling out the gpg-agent.conf file, you entered the option enable-win32-openssh-supportreturn to the step with setting the environment variable and set the value for the variable to \\.\pipe\openssh-ssh-agent.

Attention! Despite the fact that the versions of all the components matched the conditions for me, this method did not work on my system, and I had to fall back to using wsl-ssh-pageant.
If you encounter the same problem and find a solution, please share your experience in the comments. Be sure to include the versions of all components used and the version of your system.

To make sure that all components see each other and the configuration is done correctly, run two commands

gpg --export-ssh-key <id_публичного_ключа>
This command will output to the console the public ssh key corresponding to the authentication subkey.

Then, after making sure gpg-agent and wsl-ssh-pageant are running, run the command

ssh-add -L
This command will list all ssh keys that Windows OpenSsh was able to find on your system.
If the displayed keys show the same key as the previous command gpg --export-ssh-keythen you have configured everything correctly and now you can log in via ssh using your Yubikey.

I hope that the article was useful for you, and you succeeded.

If you have any additions, recommendations and tips, feel free to leave them in the comments. I think other readers will be grateful to you.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *