ssh with Certificates and Hardware Token
This Q might be quite old but hardware auth is getting more common nowadays. The following should work with different hardware keys, as long as the private key is provided by an ssh-agent
or a substitute like gpg-agent
.
TL;DR
Just provide your public key file in the -i
parameter of the ssh
command:
ssh -o CertificateFile=yubikey-cert.pub -i yubikey.pub [email protected]
Step by step
This guide has been tested with ssh version:
OpenSSH_7.9p1 Raspbian-10+deb10u2+rpt1, OpenSSL 1.1.1n 15 Mar 2022
It is assumed that the private key has been created on the hardware token. There's absolutely no way to retrieve the private key from the token and store it in a file. The key is accessible only by a software driver that emulates an ssh-agent
and provides the usual SSH_AUTH_SOCK
environment variable. For using the key this driver communicates with the hardware token and any use of the key happens on the token's microcontroller.
Get the Public Key
The public key of the token's private key is needed. The key's hash can be seen by:
ssh-add -l
Output:
4096 SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx cardno:000000000000 (RSA)
The public key can be retrieved and stored in a file:
ssh-add -L > yubikey.pub
Output:
cat yubikey.pub
ssh-rsa AAA.........XXX== cardno:000000000000
Sign the Public Key
Now the public key can be signed with the Certificate Authorities private key, to create a certificate:
ssh-keygen -s ca.key -I "keyID" -n user -z 4711 yubikey.pub
This generates the certificate file yubikey-cert.pub
. Of course the proper keyID and serial (-z
parameter) should be provided.
Use the Certificate
The certificate can now be used directly in the ssh
command. Without relying on the implicit mechanism, key and cert can be passed to ssh
on the command line. The private key must of course be available in the ssh-agent
.
ssh -o CertificateFile=yubikey-cert.pub -i yubikey.pub [email protected]
For troubleshooting the -v
switch of ssh can be used to get more details about which key and cert is used:
ssh -v -o CertificateFile=yubikey-cert.pub -i yubikey.pub [email protected]
Output (truncated for brevity):
...
debug1: Will attempt key: yubikey-cert.pub RSA-CERT SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx explicit
debug1: Will attempt key: yubikey.pub RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx explicit agent
debug1: Will attempt key: ...
...
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering public key: yubikey-cert.pub RSA-CERT SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx explicit
debug1: Server accepts key: yubikey-cert.pub RSA-CERT SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx explicit
debug1: Authentication succeeded (publickey).
...
A full tutorial of ssh certificates is out of scope of this answer. More information can be found e.g. at the OpenhSSH Cookbook.