The documentation for OpenSSH certificates (introduced in OpenSSH 5.4) are, shall we say, a bit lacking. So I'm writing down the essentials of what they are and how to use them.
What they are NOT
They're not SSH PubkeyAuthentication
In other words if your .pub file doesn't end in -cert.pub and you haven't used ssh-keygen -s, then you aren't using certificates.
They're not SSLStill the same SSH protocol.
They're not PEM, x509 ASN.1 or any other insane formatThis means you cannot get your keys signed by Verisign or any other root CA. And you cannot use multiple levels of CA.
They're not easy to google forMost hits will be about normal pubkey authentication. Some will be about older patches to one SSH implementation or another that added some form of PKI, even x509 support. You'll probably have the most luck googling for "ssh-keygen -s" (with quotes).
What they do
Sign host keysIf an organization publishes their host-key signing CAs public key you can just get that and you'll never have to see the familiar:
The authenticity of host 'xxx' can't be established. RSA key fingerprint is xxx. Are you sure you want to continue connecting (yes/no)?
Sign user keysInstead of copying your public key into thousands of servers ~/.ssh/authorized_keys you just have the user CA public key there (or system wide) and with one change it's ready for all future users of the system.
Either or both of the aboveUser CA and host CA don't depend on each other. They don't have to have the same key.
Allow you to expire certsWhile keys don't expire, the certs can if you want.
Setting up host certificates
- On the machine that you'll be storing your CA on: Create host CA key (host_ca & host_ca.pub):
ssh-keygen -f host_ca
- Sign existing host public key:
ssh-keygen -s host_ca -I host_foo -h -n foo.bar.com -V +52w /etc/ssh/ssh_host_rsa_key.pubCopy /etc/ssh/ssh_host_rsa_key.pub from other servers and this command on those files too, and copy the resulting back to the server.
- Configure server(s) to present certificate (/etc/ssh/sshd_config):
HostCertificate /etc/ssh/ssh_host_rsa_key-cert.puband restart sshd.
- Put host CA in clients known_hosts, such as ~/.ssh/known_hosts
or a system-wide one. The line should look something like this:
@cert-authority *.bar.com ssh-rsa AAAAB3[...]== Comment
- Remove clients entry (including aliases such as its IP address) for the host itself in ~/.ssh/known_hosts (if any)
- Logging in to the correct name should now work and you should
not be asked about the host key:
- Logging in to the IP address of the machine should present the message: "Certificate invalid: name is not a listed principal"
Do NOT forget the -n switch when creating host certificates. Otherwise anyone who cracks one machine will be able to impersonate any other machine in the domain to users who trust this CA.
You may need to add something like this to your client config (~/.ssh/config):
It worked for me without it, but some have needed it.Host * HostKeyAlgorithms [email protected],ssh-dss
Setting up user certificates
- On the machine you'll be storing your CA on: Create user CA key (user_ca & user_ca.pub):
ssh-keygen -f user_ca
- For every server that the certificates should work on:
- Copy user_ca.pub from the CA machine to /etc/ssh/ on the server.
- Add user_ca.pub to servers /etc/ssh/sshd_config:
- For each user: Sign existing user pubkey key:
ssh-keygen -s user_ca -I user_thomas -n thomas,thomas2 -V +52w /path/to/id_rsa.pubGive the resulting *-cert.pub file back to the user.
- Log in as user thomas or thomas2 on the server, even though the server has never seen your key or cert before, only user_ca.pub.
- Never forget -n when creating host certs.
- If you put your user CA in ~/.ssh/authorized_keys instead of configuring the server you don't need -n for user certs. If you're doing system-wide (as described) it's mandatory.
- The certificate validity time is in UTC
- You can revoke keys and certs with RevokeKeys
- -I just specifies the key ID. It doesn't have to follow the pattern I used.
- Print certificate information with ssh-keygen -L:
$ ssh-keygen -L -f user-thomas-cert.pub user-thomas-cert.pub: Type: [email protected] user certificate Public key: RSA-CERT-V00 a4:b3:6d:e2:bd:4a:39:01:31:c9:05:43:db:78:f6:c9 Signing CA: RSA a5:e5:20:8e:ea:ea:15:7e:c3:31:60:2d:6b:93:a0:6b Key ID: "user_thomas" Valid: from 2011-07-07T15:37:00 to 2012-07-05T15:38:11 Principals: thomas thomas2 Critical Options: permit-agent-forwarding permit-port-forwarding permit-pty permit-user-rc permit-X11-forwarding
Update (2012-09-12)The certificate cert format seems to have changed between 5.5 and 6.0. *sigh*. New certs can't be used to connect to old servers. To see the cert version run:
"v01" means new version. If you have servers that can only handle version v00 certificates then you should generate version v00 certificates for users:$ ssh-keygen -L -f id_rsa-cert.pub | grep Type Type: [email protected] user certificate
$ ssh-keygen -t v00 -s user-ca -I [email protected] -n thomas -V +52w id_rsa.pub