https://github.com/indygreg/yubikey-ssh-agent
An opinionated SSH agent for YubiKeys
https://github.com/indygreg/yubikey-ssh-agent
Last synced: about 1 year ago
JSON representation
An opinionated SSH agent for YubiKeys
- Host: GitHub
- URL: https://github.com/indygreg/yubikey-ssh-agent
- Owner: indygreg
- License: mpl-2.0
- Created: 2022-04-20T01:52:39.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2022-05-09T22:05:05.000Z (about 4 years ago)
- Last Synced: 2025-03-25T04:28:37.228Z (about 1 year ago)
- Language: Rust
- Size: 237 KB
- Stars: 16
- Watchers: 2
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# YubiKey SSH Agent
This project defines an SSH Agent specifically tailored for use with
YubiKeys.
The canonical home for this project is
https://github.com/indygreg/yubikey-ssh-agent.
## Usage
**The agent is only well tested on macOS. It may work on Linux, but that's
not the focus of development at the moment.**
Obtain a pre-built release from https://github.com/indygreg/yubikey-ssh-agent/releases
or compile your own via `cargo build`.
Extract the zip file and drag the `YubiKey SSH Agent` application
to your `Applications` folder in Finder.
Launch the application by double clicking or running
`open "/Applications/YubiKey SSH Agent.app"` from the terminal.
You should see a key/lock appear in your system tray at the top of
the screen.
Then, tell SSH how to use it:
$ export SSH_AUTH_SOCK="~/Library/Application Support/com.gregoryszorc.yubikey-ssh-agent/agent.sock"
**To make this change permanent**, you'll want something like this at the
top of your `~/.ssh/config`:
Host *
IdentityAgent "~/Library/Application Support/com.gregoryszorc.yubikey-ssh-agent/agent.sock"
Then perform an SSH operation needing the private key on your YubiKey:
$ ssh git@github.com
**The application does not yet persist across logouts or restarts.
You will need to launch the application whenever you log in.** This
will be fixed in a future release.
## Features
The `yubikey-ssh-agent` process provides a minimal SSH agent daemon
that interfaces directly with attached YubiKeys to service requests
for public key lookups and cryptographic signing operations.
The process provides a minimal GUI displaying current state and
provides a mechanism for inputting the PIN to unlock the YubiKey.
## Advantages Over Normal SSH Agent
This tool was born because out of the author's frustration with the user
experience when using YubiKeys with OpenSSH using the default OpenSSH
agent (`ssh-agent`) and `libykcs11`.
When you use the default OpenSSH SSH agent + `libykcs11`:
1. `ssh-agent` spawns a `ssh-pkcs11-helper` process.
2. `ssh-pkcs11-helper` loads `libykcs11.{so,dylib,dll}`.
3. When `ssh-agent` receives a message requesting interfacing with the
YubiKey, it calls into APIs in `libykcs11`, which speaks to the
YubiKey.
4. Results from `libykcs11` are relayed back to `ssh`.
A common problem is that `libykcs11` will lose contact with the YubiKey
or your cached PIN expires due to a timeout. What happens in these
scenarios is `ssh-agent` thinks that no YubiKey keys are available
and tells `ssh` there are no keys. `ssh` summarily tries to
authenticate without knowledge of the YubiKey keys. And this often
fails with a `Permission denied` message because the client didn't
actually present any public keys!
Or a variant of this is that `ssh-agent` advertises the YubiKey-hosted
key but when it attempts to use the key it fails because the YubiKey is
locked (a PIN is required). This also often materializes as a nebulous
and hard-to-debug `Permission denied` error.
**Unlike the default `ssh-agent` + `libykcs11` behavior, this agent
won't fail SSH client operations because the YubiKey is locked, the agent
lost a connection with the YubiKey, or the agent's cached PIN has expired.
Instead, this agent recognizes when a key is locked and prompts the user
to unlock it, before failing the SSH operation.**
This SSH agent makes the assumption that the YubiKey is the provider of
SSH keys. Therefore, when there is a request for available keys or a
signature request, it can be very vocal about raising an error (through
its own GUI) when user interaction is needed. For example, if SSH wants
to perform a cryptographic signature but the YubiKey is locked, this agent
will open a modal window requesting the YubiKey PIN and the SSH agent will
wait for you to unlock the YubiKey before failing the SSH attempt.
### Security Advantages
This agent doesn't support adding keys. This agent doesn't (yet) support
caching the YubiKey PIN or management key.
There are no secrets lingering in memory that can easily be extracted by
a user on the same machine. (If someone accesses the process at just the
right time they could acquire the PIN, however.)
The main threat model for this SSH agent is an unwanted client requesting
signing operations. This threat model exists for all SSH agent implementations.
For the ultra paranoid, you'll want to set a PIN protection policy on the
YubiKey to require a PIN or touch for every operation. Without such a policy,
multiple signing operations may be performed from a single unlock/touch
and anyone with access to the SSH agent could effectively use the private
key on the YubiKey.
## State of Project
This project is still very alpha. The graphical UI in particular is
very crude and in need of a lot of work.
Please file issues or just contribute pull requests to improve things.
Only macOS is well tested. Windows doesn't currently build due to
https://github.com/sekey/ssh-agent.rs not compiling on Windows (this
is a very fixable problem).
## Quirks
### macOS Default SSH Agent
macOS has an SSH agent built-in and will set `SSH_AGENT_SOCK` automatically
to a value like `SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.{random}/Listeners`.
[Stick with Security: YubiKey, SSH, GnuPG, macOS](https://evilmartians.com/chronicles/stick-with-security-yubikey-ssh-gnupg-macos)
has a good overview of the problem and how to work around it.
Essentially, the system built-in
`/System/Library/LaunchAgents/com.openssh.ssh-agent.plist` will launch
`ssh-agent` and set `SSH_AUTH_SOCK` to point to its socket.
You can't edit this file with system integrity protection enabled. So a
workaround is to create your own plists for use with launchd/launchctl
to spawn this agent and symlink over `SSH_AUTH_SOCK`.
Some day we'll likely streamline this procedure to enable people to easily
replace `SSH_AUTH_SOCK` so SSH clients never use the system default
agent.