This guide walks you through setting up an SSH certificate authority (CA) to sign host and client keys. With a CA, you can centrally manage SSH access: clients trust any host key signed by your CA, and servers trust any client key signed by it. You’ll enter a few commands on a secure machine to generate the CA keys, then sign host and client public keys, and configure your servers and clients to trust the CA.
What You’ll Need
- A secure machine (ideally offline or air-gapped) to hold the CA private keys.
- OpenSSH installed (version 5.6 or newer for certificate support). Most Linux, macOS, and Windows 10+ systems have it.
- Access to the public keys of your hosts (e.g.,
/etc/ssh/ssh_host_rsa_key.pub) and clients (e.g.,~/.ssh/id_ed25519.pub). - Root or sudo access on the servers and clients you configure.
Step-by-Step
- Create the CA key pair. On your secure machine, run:
ssh-keygen -t ed25519 -f ca_host -C "Host CA" ssh-keygen -t ed25519 -f ca_client -C "Client CA"
This creates two key pairs:
ca_host(for signing host keys) andca_client(for signing client keys). Keep the private keys safe; anyone with them can impersonate your hosts or grant access. - Sign host keys. For each host, copy its public key to the CA machine and sign it:
ssh-keygen -s ca_host -I host1 -n host1.example.com -V +52w /path/to/host1_key.pub
Replace
host1with a unique identity,host1.example.comwith the host’s DNS name or IP, and adjust the validity period (-V +52w= 52 weeks). This produces a signed certificate file (e.g.,host1_key-cert.pub). - Sign client keys. Similarly, for each user’s public key, sign it with the client CA:
ssh-keygen -s ca_client -I user1 -n user1,username -V +52w /path/to/user1.pub
The
-noption specifies the principals (usernames) the certificate is valid for. You can list multiple comma-separated principals. - Install host certificates. On each host, copy the signed certificate to
/etc/ssh/and updatesshd_config:cp host1_key-cert.pub /etc/ssh/ echo "HostCertificate /etc/ssh/host1_key-cert.pub" >> /etc/ssh/sshd_config
Restart sshd (
systemctl restart sshdor equivalent). - Configure clients to trust the host CA. On each client machine, add the host CA public key to
~/.ssh/known_hosts:echo "@cert-authority * $(cat ca_host.pub)" >> ~/.ssh/known_hosts
Now the client will accept any host key signed by your CA, eliminating host key verification prompts.
- Install client certificates. Copy the signed client certificate to the user’s
~/.ssh/directory. The certificate file must have the same base name as the private key (e.g.,id_ed25519-cert.pubnext toid_ed25519). SSH will automatically use it when connecting. - Configure servers to trust the client CA. On each server, add the client CA public key to
~/.ssh/authorized_keys(or better, to a dedicated file and reference it viaAuthorizedKeysFile):echo "cert-authority $(cat ca_client.pub)" >> ~/.ssh/authorized_keys
Now any client presenting a certificate signed by your CA will be accepted, without needing individual keys in
authorized_keys. - Test the setup. From a client with a signed certificate, connect to a host that trusts the CA. You should not see any host key warning, and you should be logged in without entering a password (if your key has no passphrase). If it fails, check the logs on the server (
/var/log/auth.logorjournalctl -u sshd).
Common Mistakes
- Using the same CA for hosts and clients. While you can, it’s safer to separate them so you can revoke one without affecting the other.
- Signing with the wrong key. Make sure you sign host keys with the host CA and client keys with the client CA.
- Forgetting the
-nprincipals. For client certs, if you omit-n, the certificate is valid for any username, which is a security risk. Always specify allowed usernames. - Not setting a validity period. Without
-V, certificates are valid indefinitely. Set a reasonable expiration to limit risk if a key is compromised. - Putting the CA private key on a server. The CA private keys should be kept offline or on a highly secure machine. If compromised, an attacker can sign anything.
Tips
- Use Ed25519 keys for speed and security; they are well-supported in modern OpenSSH.
- Set a long validity for host certificates (e.g., 1 year) and shorter for client certificates (e.g., 30 days) to force periodic re-issue.
- Use a certificate revocation list (CRL) if you need to revoke access. Generate with
ssh-keygen -k -u -f crl_file ca_client.puband specifyRevokedKeys /path/to/crlinsshd_config. - Automate signing with a script or a small service, but keep the CA key protected.
- Document your CA setup and store the CA public keys in a well-known location so users can trust them.
Troubleshooting
- Host key verification failed. The client doesn’t trust the host CA. Check that
@cert-authorityline is inknown_hostsand that the CA public key matches the one used to sign the host certificate. - Permission denied (publickey). The server rejected the client certificate. Verify that the client certificate is valid (not expired, correct principals) and that the server’s
authorized_keyscontains thecert-authorityline for the correct CA. - Certificate is not valid yet. Check the system clocks on both client and server. Time skew can cause certificates to be considered invalid.
- sshd doesn’t start. Check
sshd_configsyntax withsshd -t. Ensure theHostCertificatepath is correct and readable by sshd. - Certificate file not found. Ensure the certificate file is named exactly as the key file plus
-cert.puband is in the expected directory. - Using a non-standard port or user. If you connect with
-por-l, the certificate still works, but the hostname in the certificate must match what you type (or you can use@cert-authoritywith a wildcard).
Frequently Asked Questions
- Can I use the same CA for both hosts and clients? Yes, but it’s not recommended. If the CA key is compromised, both host and client trust are lost. Separate CAs limit the blast radius.
- How do I revoke a certificate? Use a CRL. Generate it with
ssh-keygen -k -u -f crl_file ca_client.puband addRevokedKeys /path/to/crltosshd_config. For host certs, clients can useRevokedHostKeysinssh_config. - What is the validity period syntax?
-Vaccepts formats like+52w(52 weeks),+1d,20250101, or a range like-1d:+52w. Seeman ssh-keygenfor details. - Do client certificates replace passwords and keys? Yes, if you configure servers to only accept certificates. You can still use regular keys as fallback, but certificates offer centralized control.
- Can I sign a key that already has a passphrase? Yes, the passphrase protects the private key; the certificate is based on the public key. The user will still need to enter the passphrase to use the private key.
- Is this compatible with Windows OpenSSH? Yes, modern Windows OpenSSH supports certificates. The steps are the same, though file paths differ (e.g.,
%USERPROFILE%\.ssh\known_hosts).
Related
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Hide PHP Version HTTP Header: How To
- CentOS Stream for Developers: A Practical Guide
- Scroll Horizontally with Mouse Wheel by Holding Shift5.00 min/km
- How to Replace a Game Controller Battery Safely
- Man-Sized 3D Printer? Why You Probably Don’t Need One100.0 cm³/h
- iPadOS 16 Supported Devices: Full List