HackBlue

Tools · Cryptography and passwords in practice · 08 / 20

SSH certificates with ssh-keygen: a lab certificate authority for users and hosts

Replace scattered authorized_keys files with short-lived SSH user certificates signed by a CA, restrict principals and validity, and configure servers to trust the CA.

11 min read · practice only with authorization

Why certificates

With plain SSH keys, every server keeps an authorized_keys list, and removing someone means editing every server. With SSH certificates, servers trust one certificate authority key. Users present a short-lived certificate signed by the CA that lists their allowed principals (usernames). Expiry handles most revocation, and host certificates remove trust-on-first-use prompts for clients.

Create the CA and sign a user key

The CA is just an SSH key pair kept carefully. ssh-keygen -s signs a public key, -I sets an identity string for logs, -n sets principals, and -V sets validity.

Snippet
ssh-keygen -t ed25519 -f user_ca -C 'lab user CA'
ssh-keygen -t ed25519 -f ~/.ssh/id_lab -C 'alice laptop'
ssh-keygen -s user_ca -I alice@lab -n alice,deploy -V +8h ~/.ssh/id_lab.pub
ssh-keygen -L -f ~/.ssh/id_lab-cert.pub

Lab: configure a server to trust the CA

On a lab server, copy user_ca.pub to /etc/ssh/user_ca.pub and add TrustedUserCAKeys to sshd_config, then restart sshd. Log in as alice with the certificate. Then sign a certificate valid for one minute, wait, and confirm login fails after expiry. Check the server’s auth log for the certificate ID and serial.

Snippet
# /etc/ssh/sshd_config
TrustedUserCAKeys /etc/ssh/user_ca.pub

sudo systemctl restart ssh
ssh -i ~/.ssh/id_lab alice@lab-server
ssh-keygen -s user_ca -I short@lab -n alice -V +1m ~/.ssh/id_lab.pub
sudo journalctl -u ssh | grep -i 'cert' | tail

Operating a CA

Protect the CA private key like a domain admin credential: store it offline or in a hardware key or KMS, or use a CA service such as step-ca, Vault’s SSH secrets engine, or a cloud provider’s managed offering. Keep validity short (hours) for users. Use RevokedKeys in sshd_config for emergencies. Sign host keys too and distribute @cert-authority lines in known_hosts.

Diagram

authorized_keys versus SSH certificates

Centralize trust, shorten lifetimes.

authorized_keys everywhere

Trust. Per key, per server

Removal. Edit every server

Lifetime. Forever until removed

SSH user certificates

Trust. One CA key per server

Removal. Let it expire; RevokedKeys for emergencies

Lifetime. Hours, set with -V

Check yourself

1. Which sshd_config option makes a server accept user certificates from a CA?

2. Which ssh-keygen option sets the usernames a certificate is valid for?

3. What is the main revocation strategy for SSH user certificates?