SSH Certificate Authorities (CAs)¶
As described on our blog, SSH CAs are a way of building SSH authentication on top of a signing SSH keys. This document expands on how SSH CAs work, the different modes of operation, possible improvements, and other interesting things that can be done with CAs.
How an SSH CA Works¶
An SSH CA key is just a normal SSH key. This bot generates keys via:
ssh-keygen -t ed25519 -f ca-key -m PEM
A signature on a SSH key is a certificate that contains some additional information. A certificate contains:
- The public key of the signed key
- A key ID that can be used to identify who the key was issued to
- A serial number that can be used manage revocation lists
- A validity period where the key is considered valid only within that period of time
- A list of principals
A list of principals on a certificate is simply strings that are shared for access control. The field is often used to encode roles a user has or groups that they are in, anything that helps the server decide whether or not to allow access (and how much access to grant). We use this field to include a list of keybase teams that the user is in. And the servers are configured to expect the same values (more below). As an example, here is the information encoded in a certificate created by this bot:
$ ssh-keygen -L -f ~/.ssh/keybase-signed-key---cert.pub
/home/david/.ssh/keybase-signed-key---cert.pub:
Type: ssh-ed25519-cert-v01@openssh.com user certificate
Public key: ED25519-CERT SHA256:wdzTWhCrVeJrxRIC1KU5nJr8FbxxCUJt1IVeG7HYjmc
Signing CA: ED25519 SHA256:OEhTm77qM7ZDwb5oltxt78FIpKraXCzxoaboi/KpNbM
Key ID: "08a093ec-cb4e-4bc2-9800-825095418397:981b88e2-a214-4075-af77-72da9600f34f"
Serial: 0
Valid: from 2019-07-31T11:21:00 to 2019-07-31T12:22:50
Principals:
sshcademo.staging
sshcademo.prod
sshcademo.root_everywhere
sshcademo.bot_access
Critical Options: (none)
Extensions:
permit-X11-forwarding
permit-agent-forwarding
permit-port-forwarding
permit-pty
permit-user-rc
This certificate which was created by the CA bot is the bot’s cryptographic assertion that I am in the specified teams.
If I then attempt to SSH into a server with this certificate, it is the responsibility of the server to decide whether
or not to allow the connection. This is done via adding two lines to /etc/ssh/sshd_config
:
TrustedUserCAKeys /etc/ssh/ca.pub
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%u
The first line specifies that /etc/ssh/ca.pub
contains the CA public key (as generated by ssh-keygen above). The
second line is how we define a mapping between the principals (for this bot: the Keybase teamnames) and the SSH users
they are granted access to. For example, if we wanted this server to allow people with the principal sshcademo.root_everywhere
to use the root user and people with the principal sshcademo.staging
to use the “developer” user, we would create two files.
First, /etc/ssh/auth_principals/root
with contents sshcademo.root_everywhere
and second /etc/ssh/auth_principals/keybase
with contents sshcademo.staging
.
When the SSH server accepts the connection, it will log the key ID and the serial number which can be combined with the CA bot’s audit logs in order to track a connection to a specific keybase user.
Accepted publickey for developer from 65.202.161.38 port 56914 ssh2: ED25519-CERT ID e662bf1e-0855-41e9-8951-87bf8c0b3614:f650a363-cd34-4ab0-b6bf-52faa120364d (serial 0) CA ED25519 SHA256:OEhTm77qM7ZDwb5oltxt78FIpKraXCzxoaboi/KpNbM
For more information on SSH CAs, here are a few more useful sources:
- https://code.fb.com/security/scalable-and-secure-access-with-ssh/
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/sec-using_openssh_certificate_authentication
- https://medium.com/uber-security-privacy/introducing-the-uber-ssh-certificate-authority-4f840839c5cc
Future Improvements¶
Below are a few ideas for future improvements to this project. PRs welcome!
Key Encryption¶
Currently the CA key is stored on the filesystem unencrypted by the CA bot. As long as the CA bot is run on a well isolated machine, this is not seen as a significant security weakness. Nonetheless, this could be improved upon by adding options that allow for encrypting the CA key.
Revocation¶
With an SSH CA it is possible to revoke signed SSH keys via revocation lists. A revocation list is a file on the server that contains a list of revoked keys. It is likely impractical to manually manage a revocation list, so this could be done via a cron job that periodically updates the revocation list. One of the main difficulties of designing this feature as part of the SSH CA bot is that a design goal of this bot was to not require running Keybase on every server. Thus, this revocation list would need to be somehow updated independent of Keybase.
Host Key Signing¶
SSH CAs can be used to sign SSH host keys. This would remove the below message and strengthen SSH by switching it away from a TOFU model.
$ ssh root@daviddworken.com
The authenticity of host 'daviddworken.com (2604:a880:400:d0::38c4:2001)' can't be established.
ECDSA key fingerprint is SHA256:MmB6/g0vDrMkanuRc46n6JCDYPaPKHYsbDpLhQ3y1Yg.
Are you sure you want to continue connecting (yes/no)?
This feature has not been included because signing host keys is significantly different from signing user keys. Despite this, it could still be a useful feature to build on top of Keybase.