A Simple Guide To Getting Started With SSH Certificates

SSH keys are the best way of logging into Linux servers. But traditional keys have their limitations.

They never expire

Organizations commonly have workers that need access access to a system for a limited time, employees, move on etc. Managing this is possible by by removing keys as needed but SSH certificates have an expiry date built right into them.

You even can issue new daily certificates to everyone every morning making them worthless the following day.

Host authentication

The client and server both verify each others identity when a login is made if they both trust the CA.

Identity

SSH certificates have given an identity like an employees name. This is recorded in the auth log and is independent to the server use being logged in as. You can always tell who logged in.

Let’s create a simple SSH certificate.

CLIENT: Create An SSH Key Pair

On the client create an SSH key pair as usual:

ssh-keygen -t ed25519 -f .ssh/user-key 

This will create an ed25519 keypair in your .ssh directory. The keys will have the following names:

Private Key: .ssh/user-key
Public Key:  .ssh/user-key.pub

DO NOT PUT THE PUBLIC KEY INTO THE SSH SERVER’S authorized_keys FILE

If you put the client’s public key into the SSH server’s authorized_keys file it will not use the CA certificate for authentication.

CA SERVER: Create A CA Certificate

Note, that the CA server can be the same machine as your SSH server or another trusted server.

First, move to /etc/ssh/ and create a new directory for the CA certificate:

cd /etc/ssh
mkdir CA
chmod 600 CA

Next, create the CA certificate:

ssh-keygen -C CA -f CA/ssh-ca

You can choose to set a password or not. This must be entered to sign the the client keys so consider if you intend to automate any of this.

This creates the public and private CA certificates.

Private cert: /etc/ssh/CA/ssh-ca
Public  cert: /etc/ssh/CA/ssh-ca.pub

CA Server: Sign the Client public key

Create a new directory for your client keys:

mkdir /etc/ssh/client-keys

Then put a copy of the client public key into it.

The following command will sign the key:

ssh-keygen -s /etc/ssh/CA/ssh-ca -I "James Smith" -n root -V +1w -z 1 /etc/ssh/client-keys/user-key.pub

The options here meas as follows:

This creates a new signed public key file:

/etc/ssh/client-keys/user-key-cert.pub

Check the details of the key with ssh-keygen -Lf <SIGNED PUBLIC KEY>:

ssh-keygen -Lf /etc/ssh/client-keys/user-key-cert.pub
/etc/ssh/client-keys/user-key-cert.pub:
        Type: ssh-ed25519-cert-v01@openssh.com user certificate
        Public key: ED25519-CERT SHA256:lJZ7It7jFLm19yQBZhatw79To029boLvt8p0Du+ea/Y
        Signing CA: RSA SHA256:dVk/zfFsADyXv2oti8EF48XFjVJrYai2+54yp3A3Z0g
        Key ID: "James Smith"
        Serial: 1
        Valid: from 2021-09-03T08:31:00 to 2021-09-10T08:32:41
        Principals:
                root
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

Finally, place a copy of the signed public SSH key, user-key-cert.pub, in the clients .ssh directory on their laptop.

SSH Server: Copy and configure the CA public key

Place a copy of the the CA public key you just created into /etc/ssh.

Next, configure SSH to use the CA public key you just created:

nano /etc/ssh/sshd_config

And add the following line with a path to the CA public key:

TrustedUserCAKeys /etc/ssh/ssh-ca.pub

Check that your edit is valid:

sshd -t

And if it is restart SSH:

systemctl restart sshd.service

Check it works

Log back into the server from the client’s laptop using the user-key private key. You can specify which key to use using the -i option:

ssh -i .ssh/user-key root@<SERVER>

Open the auth file on the server (on Ubuntu/Debian /var/log/auth.log) and look for the entry for the new login:

Sep  4 04:48:59 SSH sshd[1137]: Accepted publickey for root from 1.2.3.4 port 51960 ssh2: ED25519-CERT SHA256:lJZ7It7jFLm19yQBZhatw79To029boLvt8p0Du+ea/Y ID James Smith (serial 1) CA RSA SHA256:ZI4osqO3dKCECeLcQblRPaayxTeSueVrsCq/hpltrkM

You can see that CA RSA SHA256:Z.... was used along with ID James Smith and the serial (serial 1). This confirms that the CA was used to verify the key.