- Batchfile 100%
| Docs | ||
| Scripts/Windows | ||
| LICENSE.md | ||
| README.md | ||
xo's YubiKey Config
This project is a collection of scripts that help set up a YubiKey to be used for SSH and GPG signing including the signing of git commits.
These scripts are for my personal use, but you may find them helpful as well.
Prerequisites
- One or more YubiKey 5 series keys to provision
- Firmware (,5.1) is unsupported
- Firmware [5.1, 5.2.3) uses
ecdsa-sk - Firmware [5.2.3,) uses
ed25519-sk
- YubiKey Manager (ykman)
- Gpg4win
- Git
- OpenSSH
Note: Versions above use the standard Maven version range syntax.
Usage
Must be run as Administrator (required for setting the FIDO2 PIN).
Begin an interactive process of setting up one or more YubiKeys:
.\Scripts\Windows\00-provision-keys.bat
Same as above with colorized output:
.\Scripts\Windows\00-provision-keys-colors.bat
Note: 00-provision-keys-colors will not use colors if a NO_COLOR variable is set.
Using Your Keys on a New Device
Firmware 5.2.3+ (ed25519-sk, resident keys): The key material lives on the YubiKey, not on disk. To use on a new machine:
- Install OpenSSH
- Plug in your YubiKey and run
ssh-keygen -Kin an administrator command prompt - this pulls the public key and a stub file down from the key into the working directory. Copy that to~/.sshor run the command from there. - Done. SSH will use the YubiKey automatically when it's plugged in.
Firmware [5.1, 5.2.3) (ecdsa-sk, non-resident): The private key stub is
written to disk during provisioning, so it won't be on a new machine
automatically. Copy ~/.ssh/yubikey-<serial> and
~/.ssh/yubikey-<serial>.pub to the new machine manually. The YubiKey still
handles the actual cryptography - the stub just tells SSH where to find it.
Tip: If you aren't sure if a resident key is on your Yubikey you can install ykman run
ykman fido credentials listto list the resident keys on your YubiKey.
SSH config
Add entries to ~/.ssh/config to tell SSH which keys to use. List one
IdentityFile per YubiKey - SSH will try each in order and use whichever
matches the key currently plugged in:
Host *
IdentityFile ~/.ssh/yubikey-11223344
IdentityFile ~/.ssh/yubikey-55667788
IdentityFile ~/.ssh/yubikey-99001122
IdentitiesOnly yes
AddKeysToAgent no
IdentityFile- path to the key stub written by the provisioning script. The filename isyubikey-<serial>where serial matches whatykman inforeports for that key.IdentitiesOnly yes- only try the listed keys, nothing else. Prevents SSH from offering unrelated keys and hittingMaxAuthTrieslimits.AddKeysToAgent no- the private key never leaves the hardware so there is nothing meaningful to add to the agent.
You can scope entries to specific hosts if needed:
Host github.com
IdentityFile ~/.ssh/yubikey-11223344
IdentityFile ~/.ssh/yubikey-55667788
IdentitiesOnly yes
AddKeysToAgent no
For GPG signing on a new machine:
- Import your public key from the backup directory:
gpg --import gpg-signing-key.asc - Plug in the YubiKey and run
gpg --card-status- GPG will detect the card and link it to the imported key automatically - Set trust:
gpg --edit-key <fingerprint>->trust->5
The backup directory from provisioning is your recovery point if you ever lose all your YubiKeys - that's the only place private key material exists off-hardware.
Troubleshooting
Git signing fails after switching YubiKeys
The issue: GPG records the serial number of the last card used. When you insert a different YubiKey, GPG can't match it to the key stub.
The fix: Run gpg --card-status to re-sync GPG to whichever card is
currently inserted, then retry the commit.
gpg failed to sign the data when comitting
The issue: Git and gpg are not hooked up together properly.
First make sure you can sign using your key. If this doesn't work you need to fix that before you can get gpg hooked up to Git properly:
echo "test" | gpg --clear-sign
This command should require you to enter your PIN and touch your Yubikey. If it
doesn't you'll need to check if your key was imported properly
(gpg --import gpg-signing-key.asc) before you continue.
Next you'll want to configure git. This guide by GitHub is a good reference.
That might be enough to get them hooked up for you, but if you're running into
issues still check that git's version of gpg is the one you're using to run gpg
commands. Basically you want the top result when running where gpg to match
the value of your git config's gpg.program. An example would be something
like:
$ where gpg
C:\Program Files\GnuPG\bin\gpg.exe
C:\msys64\usr\bin\gpg.exe
$ git config --global gpg.program "C:\Program Files\GnuPG\bin\gpg.exe"`
Note: $ in the example above annotates a command to be run. Other lines are the output of the command being run.
OpenPGP PIN rejected on a freshly reset key
The issue: The factory defaults are user PIN 123456 and admin PIN
12345678. If the key was partially set up before, those may have changed.
The fix: Use ykman openpgp reset to restore these defaults before running
the provisioning scripts.
I can't use these keys to SSH into Windows
The issue: Windows' OpenSSH server has poor support for authentication methods other than password based auth.
The fix: Unknown. I just skip FIDO2 authentication when accessing Windows via SSH. I either remote in or use password-based authentication.
Future Improvements:
These scripts are meeting my needs at the moment, so although improvements are not a priority these ideas would be considered if requested:
- Support for bash on Unix-based systems.
- Improved error handling (although there are some already)
- Improved self-test steps (although there are some already)
- Offering the user a clean/reliable setup by...
- Resetting their YubiKey to factory settings.
- Setting up their .ssh/config file for them.
- Improving key comments to help the user with debugging.
- Programmatically write out helper scripts to...
- Verify SSH credentials for some domain (ie: ssh -T )
- Sign and verify the signature of an arbitrary set of input bytes or a file.
Unplanned:
The following changes will not be implemented / are not in the spirit of this project:
- A port to PowerShell, Python, etc...
- Tight integration with GitHub or other specific Git services.
- Support for other brands of hardware keys.
- Providing a license permitting commercial use.
- Support setting different PINs per-card.
- You can just re-start the provisioning process to do that if you want.