These are my notes (mostly for myself!) on getting SSH authentication through GPG under a variety of Windows 10 environments like native SSH (see c:windowssystem32openssh*
), Windows Subsystem for Linux (WSL) and minGW / GIT Bash. Why? So you have a single, GPG based identity on a secure, removable hardware key store like a OpenPGP card (e.g. Yubikey 5) and your SSH keys are based off that GPG identity. No naked RSA SSH keys floating around on disk.
This document does NOT cover generating the GPG keys or moving the GPG profile and keys to the Yubikey. If you want that, see this.
NOTE: Everywhere here, replace sid
with your username as appropriate e.g. c:Userssid
becomes c:Users<yourusername>
Overall idea
One of the most exciting security enhancements in Ubuntu 20.04 LTS (Focal Fossa) is the ability to use the Fast Identity Online (FIDO) or Universal 2nd Factor (U2F) devices with SSH. By using a second authentication factor via a device, users can add another layer of security to their infrastructure through a stronger and yet still easy to use mechanism for authentication. Ss iptv samsung tv install.
- Windows-fido-bridge This repository implements an OpenSSH security key middleware that allows you to use a FIDO/U2F security key (for example, a YubiKey) to SSH into a remote server from a machine running Windows 10 and Windows Subsystem for Linux.
- Ssh-keygen may be used to generate a FIDO token-backed SSH key, after which such keys may be used much like any other key type supported by OpenSSH, provided that the YubiKey is plugged in when the keys are used. YubiKeys require the user to explicitly authorize operations by touching or tapping them.
The core idea is to install and setup gpg
natively on Windows 10. We use gpg-agent to perform SSH authentication via the pageant protocol. So we’ll be building bridges (via sockets and named pipes) to make those cross-environment connections. The complexity comes from the fact that the ends of those bridges (sockets and named pipes) are incompatible, the openssh(=non-pageant) ssh authentication protocol is unreliable and there are multiple SSH installations in most cases.
Windows 10 setup
I actually already had gpg4win but it simply wouldn’t prompt me for the GPG PIN i.e. authentication failed no matter what I tried. After struggling for a day with this, I uninstalled it completely and started fresh. In addition to having your private key on the YubiKey, it is highly recommended you have an air-gapped or offline backup of your public and private keys.
- [Optional] Uninstall gpg4win and then delete the
c:Userssid.gnupg
andC:UserssidAppDataRoaminggnupg
folders. - Install gpg4win (download)
- Re-import your GPG public key and private key into GPG per this guide. The actual private key stays on the OpenPGP card, just a link to it is imported into GPG.
- Edit
%APPDATA%gnupggpg-agent.conf
to haveenable-putty-support
- Download WSL-SSH-Pageant and install it somewhere e.g.
C:toolswsl-ssh-pageant
- Start the bridge on the Windows side by
C:toolswsl-ssh-pageantwsl-ssh-pageant-amd64-gui.exe -systray -verbose -wsl C:toolswsl-ssh-pageantwsl-ssh-agent.sock
- Start Windows’ GPG agent by the following powershell command
& 'C:Program Files (x86)GnuPGbingpg-connect-agent.exe' /bye
Ssh With Yubikey
Automating it
To start the above bridge automatically at startup, do this:
- Open
C:UserssidAppDataRoamingMicrosoftWindowsStart MenuProgramsStartup
- Put one shortcut that runs
'C:Program Files (x86)GnuPGbingpg-connect-agent.exe' /bye
- Put another shortcut that runs
'C:toolswsl-ssh-pageantstart wsl-ssh-pageant.bat'
- create a file
C:toolswsl-ssh-pageantstart wsl-ssh-pageant.bat
which has the following. This ensures that a permanent terminal window isn’t kept dangling
If you don’t have the newer cross platform PowerShell (pwsh
) used in the above command, install it from here (preferred) or use the older powershell.exe
.
SSH auth in WSL
This routes WSL’s SSH authentication across to GPG’s SSH agent using the bridge we setup earlier
- Issue this command in a WSL terminal
export SSH_AUTH_SOCK=/mnt/c/tools/wsl-ssh-pageant/wsl-ssh-agent.sock
- test with something like
ssh sid@lab-linux13-ubuntu18
. You should see a GUI PIN prompt on the Windows 10 side
Automating it
Open a WSL terminal, edit ~/.profile
file to add
SSH auth in Windows 10
Windows 10 now ships with a native OpenSSH client that lives in c:windowssystem32openssh
. If you just want to open a command prompt or powershell window and ssh
away, this is for you.
- Run
$env:SSH_AUTH_SOCK='.pipewinssh-pageant'
in powershell - test with something like
ssh sid@lab-linux13-ubuntu18
. You should see a GUI PIN prompt on the Windows 10 side
Make GIT use SSH + GPG
Chances are you also want to be able to issue a git
command in a regular windows terminal for your work e.g. git fetch
. The issue is there are two SSHs even in the pure native Windows 10 side. One in c:windowssystem32openssh
and the other installed by GIT at C:Program FilesGitusrbin
– and GIT will use it’s version and not the version we just setup above.
To fix that, open a Windows Powershell terminal and type $env:GIT_SSH='C:Windowssystem32OpenSSHssh.exe'
and then test it works by issuing git fetch
from a suitable git repository (make sure the GIT repo has your corresponding SSH key registered). If all works, you should see the PIN prompt.
Automating it
- Windows 10 Start Button -> type
environment variables
-> Edit environment variables for your account -> User variables for sid -> New - Name =
SSH_AUTH_SOCK
and value =.pipewinssh-pageant
-> Ok - Repeat with Name =
GIT_SSH
and value =C:Windowssystem32OpenSSHssh.exe
-> Ok
SSH auth in Git-Bash (mingw)
When you install git for windows, you get a bash shell that’s based off “Minimalist GNU for Windows” – a minimalist development environment for Windows. GIT runs within that.
- Run
eval $(/usr/bin/ssh-pageant -r -a '/tmp/.ssh-pageant-$USERNAME')
- test with something like
ssh sid@lab-linux13-ubuntu18
. You should see a GUI PIN prompt on the Windows 10 side
If you’re using SourceTree, switch to putty
SSH authentication and
Automating it
Just add the following to your git-bash’s ~/.bashrc
or .profile
file
WSL setup for running GPG
If all you care is SSH on WSL using gpg-agent on Windows, then the SSH auth bridge setup above is all you need. You do not need this additional bridge. But if you want to use the gpg
binary within WSL (e.g. encrypting files), then you need another bridge to handle the gpg communications into the Windows world.
- Download
npiperelay
(link) with GPG support and unzip it to something likec:toolnpiperelaynpiperelay.exe
- install socat by
sudo apt install socat
- in WSL run (it’s all one line)
socat UNIX-LISTEN:'$HOME/.gnupg/S.gpg-agent,fork' EXEC:'/mnt/c/tools/npiperelay/npiperelay.exe -ei -ep -s -a 'C:/Users/sid/AppData/Roaming/gnupg/S.gpg-agent',nofork
- Test by running
gpg --card-status
in WSL, it should work
Automating it
Add the following to the end of your WSL’s ~/.profile
file
Ssh Fido2
Ending comments – Yubico and the state of the ecosystem
Overall, I’m rather disappointed with the quality of software and how they all (don’t) interoperate smoothly. I also contacted Yubico to see if they had any internal documentation since external documentation about this was sparse. Astonishingly their just sent back unrelated links to 3rd party blog posts. If git for Windows, OpenSSH, and GPG don’t work well out of the box, Yubico should be stepping up and providing guidance to smooth that journey since they’re selling security devices that are heavily dependent on that ecosystem.
Troubleshooting
Windows 10’s default OpenSSH authentication agent was disabled but it is unclear if this is a necessary requirement.
Ssh-keygen Fido
Greasy lake full story. Start button-> Services -> OpenSSH Authentication Agent -> Stop