BitRot | Using a SSH CA

Using a SSH CA

on

Facebook recently posted a lengthy description of how they use SSH certificates and a bastion host heavily integrated with LDAP to grant access to their operational systems. I started investigating the option to use SSH certificates about a year ago (while building a short script to rotate SSH keys automatically), but reading their account finally gave me the impetus to complete the effort, including writing a wrapper script that simplifies a lot of the configuration/operation of a SSH CA.

Source is here

Getting set up

Run ssh-ca setup, which will create a ca directory (defaults to ~/.ssh/ca, but you can set it via the SSHCA_ROOT environment variable).

ca_root
├── audit.log
├── ca.pub
├── certs
├── krl.source
├── krl
├── next_cert_id
├── next_krl_id
└── private
    ├── ca_key
    └── ca_key.pub

Trusting the CA for client keys

You’ll need to configure ssh to trust your CA. Run ssh-ca install myserver to set up the CA in the authorized_keys file, similar to ssh-copy-id. If you prefer to do this manually, you can run ssh-ca trustconfig.

Trusting the CA for host keys

To trust host keys, run ssh-ca install and it will add the relevant configuration line to your known_hosts file. If you prefer to do this manually, you can run ssh-ca trustconfig.

Normal operation

Signing client keys

ssh-ca sign ~/.ssh/id_rsa.pub signs your key, placing the signed certificate in ~/.ssh/id_rsa-cert.pub. Adjust your ~/.ssh/config to prefer certificates over keys and your certificate will be trusted by any server you’ve set up to be trusted by your CA.

Signing host keys

ssh-ca signhost myhost.example.com will run ssh-keyscan to pull in and sign all the keys offered by the host. You’ll need to copy the certificates back to the server and configure sshd_config to use them.

Key Revocation Lists

The problem with KRLs is that there is no easy way to combine two compiled KRLs, which means releasing a new KRL takes passing it along to all the CAs that are trusted by a specific server. As such, I strongly recommend using short validity periods for SSH certificates, and building automation to sign keys.

More worrying is that KRLs are only for servers, so there’s no way to revoke a compromised server certificate without replacing the CA.

If you really need to revoke a key, use ssh-ca revoke "serial: X" where X is the serial number of the certificate. This will build the KRL, which you can then distribute to all your servers.

Next steps

KRLs reintroduce the key distribution problem, so a better solution is to use an ACME-style proof of control to automatically issue certificates.