Coding Stephan

Automate your SSH keys using GitHub

Using Windows Hello for SSH keys makes sure your SSH keys are secure, it also means that they are tied to a single computer. If you only have one computer that should not be too much trouble. But if you’re one of those users that uses multiple computers. You’ll need to distribute all those SSH keys to all the computers you want to use them on. Let me show you how you can automate distributing your SSH keys using GitHub.

Background

If you want to use SSH to connect to another computer the other computer needs to verify you. This can be done in two ways:

  1. Using a password (not recommended), please disable this on all your servers!
  2. Using a public/private key pair.

To use the public/private key pair, you need to generate a key pair (like I showed in the previous post). You then need to save the public key on the server you want to connect to.

By default, the public key(s) are saved in a file called authorized_keys in the .ssh folder in your home directory.

The problem

When you generate a new SSH key pair on your computer, the private key is securely stored in the TPM. This means the private key cannot be simply copied to another computer - a new key pair must be generated for each machine.

If you’re using multiple computers, this results in multiple SSH keys, all of which need to be added to the servers you wish to connect to. If password authentication is disabled, you’ll need to use another computer to transfer your public key to the server. This involves first copying your public key to the other computer, then copying it to the server.

This process can be laborious and error-prone, and it’s easy to overlook that one crucial server.

GitHub to the rescue

GitHub has this public endpoint where you can download the public ssh keys for any user. It also has a special .keys endpoint at https://github.com/{username}.keys that returns the public keys for a user in a format that is ready to be used in the authorized_keys file.

If you added your public keys to your GitHub account (which requires “sudo” mode, aka extra MFA validation), you can use this endpoint to download your public keys on any computer you want to use them on. And you can automate this process using basic tools available on almost every linux system.

Download the public keys once

Be careful this command will overwrite your existing authorized_keys file. If you already have keys in there, you will lose them. If you want to keep them, I suggest adding them to GitHub.

curl https://github.com/{username}.keys > ~/.ssh/authorized_keys

This command is using curl to download the keys from GitHub and then “pipes” the output to the authorized_keys file. Curl also has a -o option, but that will throw an error if the file already exists. And we don’t want that.

Automate the process

The script above is still a manual process, though it’s a little bit easier than copying the keys manually. But we can automate this process using a simple cronjob. This will make sure that your authorized_keys file is always up to date.

Edit your crontab file:

crontab -e

And add the following lines:

# Automatically download the latest SSH keys from GitHub
5 8-23/3 * * * curl https://github.com/{github-username}.keys > /home/{linux-username}/.ssh/authorized_keys

Once you save the crontab file, the crontab will be updated and the cronjob will be scheduled. The cronjob will run every 3 hours between 8am and 11pm. You can change the schedule to whatever you want, use this site if you’re not good a cronjob schedules. I suggest running it at least once a day 5 2 * * *.

Cronjobs are not very good with relative paths ~/, so make sure you use the full path to the authorized_keys file. You can find the full path by running the following command:

cd ~/.ssh
pwd

Security notes

This is a very simple solution. It’s not perfect, but it’s better than manually copying your keys around. There are a few things you should keep in mind:

  • If you lose access to your GitHub account, you might lose access to all your servers.
  • If someone gains access to your GitHub account, they might gain access to all your servers.

That said, if you would deploy this solution, be sure that you have MFA enabled on your github account. Preferably using ONLY a hardware key, which you off course have a backup for stored somewhere safe.

You can also decide to use a special website/url for this, that is only available within your own environment. As long as it’s available via a SECURE webserver (we don’t want a Man-In-The-Middle attack), it does not matter where the file comes from, as long as it can only be edited by authorized users.