Skip to content

SSH Authentication with a CA

cover

This article describes how to use a SSH CA to authenticate to SSH servers. This is particularly useful when you have a lot of servers to manage and you want to avoid the hassle of managing a lot of SSH keys.

The basic idea is to have a CA (Certificate Authority) that will sign the public keys of the users. Then, the users will be able to authenticate to the servers using their signed public key. This way, you don't have to manage the public keys of the users on the servers, you only have to manage the public keys of the CA. You can also limit the validity of the signed public keys to a certain amount of time or to a certain set of servers and users.

Prerequisites

This article assumes that you have a basic knowledge of SSH and that you have a SSH server running on a Linux machine.

The theory

What is a SSH CA ?

A SSH CA is simply an basic SSH key pair (public and private) that is used to sign other SSH public keys. The public key of the CA is then distributed to the servers and the private key is kept secret.

How does it work ?

When a user wants to authenticate to a server, the server will ask the user to provide a public key. The user will then provide a public key that has been signed by the CA. The server will then check the signature of the public key using the public key of the CA. If the signature is valid, the user will be authenticated.

The practice

Generate the CA key pair

The first step is to generate the CA key pair. To do so, you can use the ssh-keygen command:

ssh-keygen \
  -t rsa \
  -b 4096 \
  -f my_ssh_ca
Parameter Description
-t The algorithm to use to generate the key pair.
-b The size (in bits) of the key pair.
-f The output file name (without the extensions).

This will generate two files: my_ssh_ca and my_ssh_ca.pub. The first one is the private key of the CA and the second one is the public key of the CA.

Generate a personal SSH key pair (optional)

This step assumes that you already have a personal SSH key pair. If you don't, you can generate one using the ssh-keygen command:

ssh-keygen \
  -t ed25519 \
  -b 256 \
  -f my_ssh_key
Parameter Description
-t The algorithm to use to generate the key pair.
-b The size (in bits) of the key pair.
-f The output file name (without the extensions).

Distribute the CA public key

Configure the SSH server

First, you need to configure the SSH server to accept the SSH CA public key. To do so, you need to authenticate to the server and become root. Then, you need to edit the /etc/ssh/sshd_config file and add the following line at the end of the file:

Match Address 192.168.42.*
  TrustedUserCAKeys /etc/ssh/ssh_user_ca
  AuthorizedPrincipalsFile /etc/ssh/authorized_principals/%u
  RevokedKeys /etc/ssh/revoked_keys
Parameter Description
Match Address 192.168.42.* This line is used to apply the following configuration only to the clients that match the given address. In this case, we only want to apply the following configuration to the clients that match the 192.168.42.* address.
TrustedUserCAKeys The path to the SSH CA public key.
AuthorizedPrincipalsFile The path to the file containing the list of SSH principals allowed to authenticate to users.
RevokedKeys The path to the file containing the list of revoked SSH public keys.

Then, you need to create the /etc/ssh/ssh_user_ca file and add the public key of the SSH CA to it:

cat my_ssh_ca.pub > /etc/ssh/ssh_user_ca

For now we don't have any SSH CA public key to revoke, so we only need to create an empty file for the RevokedKeys parameter:

touch /etc/ssh/revoked_keys

Finally, we need to create the /etc/ssh/authorized_principals directory to store the list of SSH principals allowed to authenticate to users:

mkdir /etc/ssh/authorized_principals
Configure principal-based authentication

As an example, we will configure the SSH server to allow me to authenticate to the wabbit user. To do so, we need to create the /etc/ssh/authorized_principals/wabbit file and add the following line to it:

wabbit_ops

This will allow me to authenticate to the wabbit user using the wabbit_ops principal. Attention, a principal is not a username, it's just a name that will be used to identify the user or a role. You can use whatever name you want, but it's better to use a name that is easy to remember.

Apply the configuration

Once the configuration is done, you need to restart the SSH server to apply the changes:

systemctl restart sshd

Configure the SSH client

Now that the SSH server is configured, we need to configure the SSH client to use the SSH CA to authenticate to the SSH server.

Sign the personal SSH public key

First, we need to sign the personal SSH public key using the CA private key. To do so, we need to use the ssh-keygen command:

ssh-keygen \
  -s my_ssh_ca \
  -I lunik@my_server \
  -n wabbit_ops \
  -V +1d \
  my_ssh_key.pub
Parameter Description
-s The path to the CA private key.
-I The identity of the signed public key. This is used to identify the signed public key. It's a good idea to use the username, the hostname and the name of the server. It doesn't have any impact on the authentication.
-n The principal allowed during the authentication.
-V The validity of the signed public key.
my_ssh_key.pub The path to the public key to sign.

This will generate a my_ssh_key-cert.pub file that contains the signed public key.

To check the signature of the signed public key, you can use the ssh-keygen command:

ssh-keygen \
  -L \
  -f my_ssh_key-cert.pub
Parameter Description
-L Check the signature of the public key.
-f The path to the public key to check.

This will print the following output:

my_ssh_key-cert.pub:
        Type: ssh-ed25519-cert-v01@openssh.com user certificate
        Public key: ED25519-CERT SHA256:Nbe7SXv788c0t3g8D8GQ/5dwHXX4zXtoaEC7r97h5oM
        Signing CA: RSA SHA256:jitBsmIydxjgdW7DttD9piKIWmb4RPQQ7i7wfQ+M4Vg (using rsa-sha2-512)
        Key ID: "lunik@my_server"
        Serial: 0
        Valid: from 2023-09-19T19:13:00 to 2023-09-20T19:14:07
        Principals: 
                wabbit_ops
        Critical Options: (none)
        Extensions: 
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

Authenticate to the SSH server

Now that the SSH client is configured, we can authenticate to the SSH server using the signed public key. To do so, we need to use the ssh command:

ssh \
  -i my_ssh_key \
  wabbit@my_server
Parameter Description
-i The path to the private key to use to authenticate.
wabbit@my_server The username and the hostname of the SSH server.