What are SSH certificates and why should I care?
Like many other modern network solutions, SSH uses asymmetric cryptography to authenticate both users and servers. The actual protocols involved here are quite complex but ultimately, what they rely on is that if a digital signature can be successfully decoded using an entity's public key, it must have been generated using that entity's private key - thus proving the signature has indeed come from that entity (or someone who has compromised that entity and stolen their private keys, which however is beyond the scope of the current discussion).
Unfortunately, there are certain operational considerations associated with the fact SSH keys are just that - keys used in cryptographic operations. Consider the following:
- In order to validate the server's signature you must have its public key - but how can you be sure the key you receive when you connect to a server for the first time really belongs to that server?
- In case of user authentication the problem of trust is sidestepped by the relevant public keys having to be explicitly added to the user's authorized_keys file - but how do you add your public key there if the target server only allows key authentication?
- Should all the keys in your authorized_keys still be there? Could it be that some entries were only "temporarily" copied from another cluster and subsequently forgotten, or that one of them got compromised years ago but you had by then lost track of where you had deployed it?
- What about multi-factor authentication? Private SSH keys can be protected from unauthorised access by a passphrase but it is entirely up to the user to have one (or not); the server has no way of knowing.
The list goes on and on.
SSH certificates are the SSH equivalent of X.509 certificates, i.e. something you use every time you connect to a Web site using HTTPS. In short, they augment the formerly bare public key with metadata such as who the holder ("principal" in the SSH parlance) of the key is, when it is due to expire, and so on. Same as with X.509, the authenticity of said metadata is assured by it having been signed by the private key of a Certificate Authority (CA). That way:
- Instead of having to explicitly trust multiple SSH host keys, you just trust the public key of the CA. Moreover, that trust can be explicitly limited to a set of domain names rather than to all SSH host certificates you may encounter;
- There is no longer any need for having your user key in authorized_keys - if the target server trusts the signatures made by the given CA, all you need is your user name embedded in certificate metadata upon acquiring it;
- Finite (and usually quite short) lifetime of certificates makes it much harder for obsolete or compromised keys to pass unnoticed;
- Multi-factor authentication can now be enforced by the CA.
SSH certificates at Maths
We have got our own, internal SSH CA which can issue both host and user certificates. For the latter, the CA utilises the standard University authentication system to verify one's identity.
User certificates are presently issued with relatively long lifetime of one month. As time passes we intend to gradually scale that time down to the current best-practice lifetime of no more than 1 week.
Getting an user certificate
Let's say you have just been granted an account on the Maths HPC cluster "Swirles" (which allows neither password nor host-based authentication with SSH), and either want to access it for the first time or have had your old user certificate expire.
Some basic assumptions:
- you have active University and Maths accounts
- are on a machine connected to either the Maths wired network (it can, but does not have to be, an IT-managed Maths desktop or server) or the Maths VPN;
- you haven't got an SSH key pair yet (if you have one and want to use it, simply skip the first step and use a different file name than "swirles" in further commands)
- replace the placeholders in the following commands as follows
- [crsid] - your CRSid
- [certname] - something that will help you recognise your certificate in your records if need be. We recommend including your CRSid, followed by either a short description (e.g. something like "ab123+laptop"; this is the naming convention used by the UIS network tokens) or the current date (e.g. "ab123-20260401")
If you are on a managed Maths machine, please skip the steps highlighted in bold.
Linux / macOS / Cygwin
- ssh-keygen -t ed25519 -f "${HOME}"/.ssh/swirles
- rsync -av "${HOME}"/.ssh/swirles.pub [crsid]@ssh.maths.cam.ac.uk:.ssh/
- SSH as yourself to ssh.maths.cam.ac.uk, then
- step ca bootstrap --ca-url==https://ssh-ca.maths.cam.ac.uk/ --fingerprint=f08ce0b552af6437c78f2368319381c504ad60c36638604850318975818b86f1
- this only needs to be used once per user (or specifically once per home directory), if this has already been run skip this step
- step ssh certificate --console --provisioner=Blue --sign [certname] "${HOME}"/.ssh/swirles.pub
- on a managed Maths machine you can omit --console from the above - if will make the following step slightly simpler
- Follow on-screen instructions
- Disconnect
- step ca bootstrap --ca-url==https://ssh-ca.maths.cam.ac.uk/ --fingerprint=f08ce0b552af6437c78f2368319381c504ad60c36638604850318975818b86f1
- rsync -av [crsid]@ssh.maths.cam.ac.uk:.ssh/swirles-cert.pub "${HOME}"/.ssh/
- ssh-add "${HOME}"/.ssh/swirles
- this should say something along the lines of "Certificate added"
At this point you should be able to SSH to Swirles.
Nb. Use ssh-keygen -L -f "${HOME}"/.ssh/swirles-cert.pub to check the expiry date of your certificate, or to see what other metadata it consists of.
Windows (using PuTTY)
Detailed instructions to follow. Meanwhile, here are the main differences from the above:
Key generation
- use puttygen rather than ssh-keygen
- if you are on a very recent version of PuTTY, instead of selecting key type "ed25519" select key type "EdDSA" and make sure the option "Curve to use" below shows "ed25519"
- you will need to save the public key in OpenSSH key format in order for "step" to be able to process it. The easiest way of doing so is to copy the contents of the box "public key for pasting into OpenSSH authorized_keys file" and save them as a plain-text file using e.g. Notepad
File transfers
- instead of rsync, you may use a GUI SCP/SFTP client such as WinSCP or FileZilla
Importing the certificate
- use puttygen
- first, use the menu option is Key -> Add certificate to key to import the certificate downloaded from ssh.maths
- then, use "Save private key" (yes, private) to save everything in PuTTY-native PPK format
- this also how you can check certificate valiidity etc. - with the certificate added to the key, just click the button "Certificate info"
Using the certificate
- no changes to the normal PuTTY work flow here: if you use Pageant add the newly created PPK key to it (it will show as "ed25519-cert" rather than just "ed25519"), if you do not just point PuTTY directly at the new PPK file
Using Maths host certificates
Managed Maths systems should automatically recognise the signatures made by our SSH CA.
Should you want to accept Maths SSH host certificates elsewhere, paste the following as a single line into your $HOME/.ssh/known_hosts (PuTTY instructions TBA):
@cert-authority *.damtp.cam.ac.uk,*.dpmms.cam.ac.uk,*.statslab.cam.ac.uk,*.maths.cam.ac.uk ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBvEAtmCJq1uRFRh6RC5SS2kr9JOAVEdtkfAuQfqmGTFGcNzm/q6GjCHKnUXZOyrohY+SP7y2V7VrajX01KDxzk=
(yes, this is an ECDSA key for now - our CA software has only recently gained support for ed25519 CA keys)
For extra security, look for "@cert-authority" in /etc/ssh/ssh_known_hosts on a managed Maths system (it will likely be at the very end) and confirm that the key included there (i.e. the random-looking string after "ecdsa-sha2-nistp256") is identical to the one shown above.