How to set up OpenSSH to use x509 PKI for authentication?

OpenSSH does not officially support x.509 certificate based authentication:

The developers have maintained a stance that the complexity of X.509 certificates introduces an unacceptable attack surface for sshd. Instead, they have [recently] implemented an alternative certificate format which is much simpler to parse and thus introduces less risk.

...

OpenSSH just uses the low-level cryptographic algorithms from OpenSSL.

However Roumen Petrov publishes OpenSSH builds that do include X.509 support, and you could try with those.

X.509 certificates can [be] used as "user identity" and/or "host key" in SSH "Public Key" and "Host-Based" authentications.

Roumen Petrov's builds can be downloaded via this page.

Here's a Debian how-to for SSH with authentication key instead of password that might also prove useful in setting up your OpenSSH to accept x509 PKI for user authentication.


Native certificate-based authentication is available in unmodified upstream OpenSSH. It is not, however, based on x.509.

First, generate your CA:

ssh-keygen -f ssh-ca

Next, install your CA key in .authorized_keys with a cert-authority prefix:

echo "cert-authority $(<ssh-ca.pub)" >>.ssh/authorized_keys

From that point, whenever a key is generated by a user:

ssh-keygen -f real-key

...the public portion can be signed by your SSH CA, whereafter it will be trusted by the server without that key itself being added to authorized_keys:

ssh-keygen -s ssh-ca -I identifier_for_your_real_key_goes_here real-key.pub

With OpenSSH it's not possible. As said by @TildalWave you need to use the fork from Roumen Petrov PKIXSSH.

Once you have your X509 certificate you don't need to add the public key on the authorized_keys file.

You need to configure two things in the server side:

  • Add the certificate for the CA in the directory set by CACertificatePath directive in sshd_config file (normally /etc/ssh/ca/crt, I think) with a link for the hash of the certificate.

    For creating the link use openssl. Supposing the CA certificate has been copied under /ect/ssh/ca/crt/ca.crt the commands will be:

cd /etc/ssh/ca/crt/
ln -s ca.crt `openssl x509 -in ca.crt -noout -hash`.0
  • Add the "subject" information of x509 certificate to the authorized_keys file of the user (in destination server)

    Suppose the private key and the X509 certificate of the user is in ssh/id_rsa to get the subject run in the client:

openssl x509 -noout -subject -in .ssh/id_rsa

And them on the server, add this line with the prefix x509v3-sign-rsa subject= to the authorized_keys.

This line will have a content similar to this one:

x509v3-sign-rsa subject= /C=ES/ST=Pontevedra/L=Vigo/CN=testssh/[email protected]

As we can see, the authentication is really made trusting the CA for any valid x509 certificate from the user. We could generate a new certificate and it will be accepted with no intervention on server side.


After struggling for a few days I have written a post explaining the full process on a blog I have just deployed. You can read it at "OpenSSH with X509 certificates HOW TO".