How to Harden SSH with Certificate-Based Authentication
SSH certificate-based authentication is a more scalable and secure alternative to traditional public key authentication. Instead of distributing individual public keys to every server, a trusted Certificate Authority (CA) signs user and host keys, and servers trust any key signed by that CA. This approach dramatically simplifies key management on your Breeze instances.
How SSH Certificates Work
In traditional SSH key authentication, each user's public key must be added to ~/.ssh/authorized_keys on every server. With certificates:
- A CA signs the user's public key, creating a certificate
- Servers are configured to trust the CA, not individual keys
- Certificates can have expiration times, restricting access windows
- Certificates can restrict which users and hosts they are valid for
Setting Up the Certificate Authority
Create a dedicated CA key pair on a secure management machine (not on the Breeze instances themselves):
# Generate the User CA key
ssh-keygen -t ed25519 -f /etc/ssh/user_ca -C "User CA Key"
# Generate the Host CA key
ssh-keygen -t ed25519 -f /etc/ssh/host_ca -C "Host CA Key"
# Protect the CA private keys
chmod 600 /etc/ssh/user_ca /etc/ssh/host_ca
Signing Host Keys
Sign each Breeze instance's host key so clients can verify server identity without TOFU (trust on first use):
# Copy the host public key from the Breeze instance
scp root@breeze-ip:/etc/ssh/ssh_host_ed25519_key.pub ./host_key.pub
# Sign the host key
ssh-keygen -s /etc/ssh/host_ca -I "breeze-hostname" -h -n "breeze-ip,breeze-hostname" -V +52w host_key.pub
# Copy the signed certificate back
scp host_key.pub-cert.pub root@breeze-ip:/etc/ssh/ssh_host_ed25519_key-cert.pub
On the Breeze instance, add to /etc/ssh/sshd_config:
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
Configuring the Server to Trust User Certificates
Copy the User CA public key to each Breeze instance and configure sshd:
# Copy User CA public key to the server
scp /etc/ssh/user_ca.pub root@breeze-ip:/etc/ssh/user_ca.pub
# Add to sshd_config
echo "TrustedUserCAKeys /etc/ssh/user_ca.pub" | sudo tee -a /etc/ssh/sshd_config
# Restart sshd
sudo systemctl restart sshd
Signing User Keys
Sign a user's public key with the User CA:
# Sign user key valid for 8 hours, for user "deploy"
ssh-keygen -s /etc/ssh/user_ca -I "deploy@company" -n deploy -V +8h /path/to/user_id_ed25519.pub
The -n flag specifies which Linux usernames the certificate is valid for. The -V flag sets the validity period.
Client-Side Configuration
On the client, configure SSH to trust the Host CA so server identity is verified automatically:
# Add to ~/.ssh/known_hosts
@cert-authority *.yourdomain.com ssh-ed25519 AAAA...host_ca_public_key...
The user also needs the signed certificate alongside their key:
# The certificate file must be named with -cert.pub suffix
ls ~/.ssh/id_ed25519 ~/.ssh/id_ed25519-cert.pub
Restricting Certificate Capabilities
Certificates can include restrictions to limit what the authenticated user can do:
# Sign with no port forwarding and forced command
ssh-keygen -s /etc/ssh/user_ca -I "backup-agent" -n backup -V +24h \
-O no-port-forwarding \
-O no-x11-forwarding \
-O no-agent-forwarding \
-O force-command="/usr/local/bin/backup-script" \
backup_id_ed25519.pub
Revoking Certificates
Create a Key Revocation List (KRL) to invalidate compromised certificates:
# Create a KRL
ssh-keygen -k -f /etc/ssh/revoked_keys -s /etc/ssh/user_ca compromised_cert.pub
# Configure sshd to check the KRL
echo "RevokedKeys /etc/ssh/revoked_keys" | sudo tee -a /etc/ssh/sshd_config
sudo systemctl restart sshd
Best Practices
- Use short-lived certificates — issue certificates valid for hours, not months
- Protect CA keys offline — store the CA private keys on an air-gapped machine or HSM
- Automate signing — use a signing service to issue certificates on demand after authentication
- Audit certificate usage — monitor sshd logs for certificate-based logins
- Disable password authentication — once certificates are in place, set
PasswordAuthentication no
Certificate-based SSH authentication provides centralized trust management and short-lived credentials, making it far easier to manage access at scale across your Breeze fleet.