Using a YubiKey in web browsers works great.
Unfortunately, it is not so great when attempting to do so with SSH or within WSL2.
SSH
OpenSSH 8.2 and above supports fido2, which makes the process of using a Fido2 authenticator for SSH much simpler.
However, the version of OpenSSH that ships with Windows 10 does not support fido2 at time of writing. This is something that is being actively worked on, although it will probably be several months before this is a fixed.
Ironically, the easiest workaround for this is to use the version of ssh that comes with Git For Windows.
-
Install Git For Windows. These instructions assume that its in the default location of
C:\Program Files\Git, adjust as needed. -
The version of ssh that comes with Git For Windows does support fido2. However, it isn’t able to talk to the YubiKey or other compatible devices on Windows.
This is where the openssh-sk-winhello middleware comes in. It allows ssh to connect with these authenticators via the Windows Hello API.
Download the appropriate release of
winhello.dlldepending on the version of ssh in Git for Windows (v2.0 for my case). -
Copy
winhello.dlltoC:\Program Files\Git\usr\lib\ssh -
Add the following lines to
~/.ssh/config(this will map back toc:\users\<username>\.ssh\configon windows):Host * SecurityKeyProvider winhello.dll -
Configure Bash to have ssh-keygen and ssh-agent use
winhello.dll. Add this line to~/.bashrc(which will be in your user folder on windows):# this must be an absolute path, relative paths won't work export SSH_SK_PROVIDER=/usr/lib/ssh/winhello.dll/usr/libfrom within git bash maps back toC:\Program Files\Git\usr\libon windows. -
Launch git bash by typing “git bash” in the start menu to get to the shortcut.
-
Generate a SSH keypair resident on the YubiKey:
ssh-keygen -t ed25519-sk -O resident -C 'YubiKey 5C NFC' -f ~/.ssh/id_ed25519_skIf everything is set up correctly, you should be prompted to enter the pin for the YubiKey and to touch the device.
-
There should be 2 new files in your ssh folder. Copy the public key to a server you want to access. The private key is a stub that refers to the authenticator. From within git bash, try accessing a server via ssh with this new key.
Alternative Solutions
- windows-fido-bridge is another OpenSSH middleware that has similar functionality as winhelper. However, it requires ssh 8.3 and above, which doesn’t come with Ubuntu 20.04.
WSL2
WSL2 has experimental support for USB devices, although it doesn’t work with Fido2 devices yet.
To work around this issue, openssh-sk-winhello can be set to accessed from WSL2 via ssh-sk-helper, which acts as a bridge from WSL2 to the ssh tools set up above in git bash.
Git bash comes with ssh-sk-helper already, so that doesn’t need to be installed separately.
-
In WSL2, add the following to
~/.ssh/config(note the windows-style path):Host * SecurityKeyProvider "c:/Program Files/Git/usr/lib/ssh/winhello.dll" -
Add the following environment variables to configure ssh in WSL2 to use ssh-sk-helper and winhello:
# see https://github.com/tavrez/openssh-sk-winhello/blob/master/WSL.md export SSH_SK_HELPER="/mnt/c/Program Files/Git/usr/lib/ssh/ssh-sk-helper.exe" export SSH_SK_PROVIDER="c:/Program Files/Git/usr/lib/ssh/winhello.dll" -
Copy the following .dll files from
C:\Program Files\Git\usr\bintoC:\Program Files\Git\usr\lib\sshso that ssh-sk-helper has the DLLs it needs to run when invoked from WSL2:- msys-2.0.dll
- msys-cbor-0.8.dll
- msys-crypto-1.1.dll
- msys-fido2-1.dll
- msys-gcc_s-seh-1.dll
- msys-z.dll
-
If everything is set up correctly, you should be prompted to enter a pin and touch the device when generating an ssh keypair via the YubiKey.