Certificate Based SSH Authentication

I have set up a new home server recently, and I needed to be able to connect to it via SSH. I had done it numerous times in the past but creating the private/key pair, copying the public key to the server, etc.

Recently though, I heard that the SSH protocol allows for certificate based authentication. The idea is that you generate a certificate, you give the server the certificate's public key, and then any key signed with this certificate will be allowed to connect! In praactice, it does not change much, but I thought the concept was very cool. If you are curious, here are the steps to follow:

Step 1: Create your CA key pair

This step is about creating a new certificate. In practice, it is still a public/private key, but it is called a certificate because it will be used to sign other things.

ssh-keygen -t ed25519 -f ~/.ssh/ca_key -C "My SSH CA"

This creates a ca_key and ca_key.pub file in your ~./ssh folder. The private key is the one that will be used to sign things. The public key is the one shared with the world. Using it, one can verify if a thing was indeed signed by your certificate!

Step 2: Copy the certificate's public key to your server

This is why I was saying that in practice it does not change much. You still need to transfer a file to the server, even if it is not your user's pubnlic key. That's the only time you need to do that though, and it would be the same file for all the servers you would want to connect to.

Here is the command: scp ~/.ssh/ca_key.pub youruser@your-server-ip:~/ca_key.pub

Step 3: Configure the server to trust your CA

sudo mv ~/ca_key.pub /etc/ssh/ca_key.pub
sudo chmod 644 /etc/ssh/ca_key.pub

Now, back on your local computer.

Step 4: Generate your user key pair

Use the same command as above to generate your user's key pair. This time, those keys represent your user.

ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -C "youruser@macbook"

You should now see a id_ed25519 and a id_ed25519.pub file in your ~/.ssh folder. Those are your keys.

Step 5: Sign your user's public key with the certificate

Here is where it happens. We are signing your user's public key using the certificate's private key:

ssh-keygen -s ~/.ssh/ca_key -I "youruser-macbook" -n youruser ~/.ssh/id_ed25519.pub

Here is what the flags mean:

Right now, the resulting file would be valid forever, without expiration. If you want to add an expiry date, you woud use:

You should see a id_ed25519-cert.pub file now. This is the file you will provide to any ssh client that supports certificate authentication.

You can inspect it with: ssh-keygen -L -f ~/.ssh/id_ed25519-cert.pub

That's it! You can now directly connect to your server using: ssh username@server-ip.

SSH automatically detects id_ed25519-cert.pub sitting next to id_ed25519 and presents both. The server then verifies the certificate was signed by its trusted CA and lets you in.

I can see how small companies could create a small web server responsible for signing and returning new identity files. That would make it easy to allow "just in time" access to their servers. By adding an expiration date of a couple minutes, they would ensure that the key would never be able to work again. It's so much easier to manage accesse than having to distribute and keep track of multiple public/key pairs for all employees!