A couple years back we wrote a guide on how to create good OpenPGP/GnuPG keys and now it is time to write a guide on SSH keys for much of the same reasons: SSH key algorithms have evolved in past years and the keys generated by the default OpenSSH settings a few years ago are no longer considered state-of-the-art. This guide is intended both for those completely new to SSH and to those who have already been using it for years and who want to make sure they are following the latest best practices.
Use OpenSSH 7 or later
Related to SSH keys there have been some relevant changes in versions 5.7, 6.5 and 7.0. Latest version is 7.9. You should be running at least 7.0. Current Debian stable (“Stretch”) shipped version 7.4 and for example Ubuntu 16.04 (“Xenial”) shipped 7.2, so nobody should be running on their laptop any later versions than these.
Generate Ed25519 keys
With a recent version of OpenSSH, simply run
ssh-keygen -t ed25519. This will create a private and public key pair files at
.pub) using the Ed25519 algorithm, which is considered state of the art. Elliptic curve algorithms in general are sleek and efficient and unlike the other well known elliptic curve algorithm ECDSA, this Ed25519 does not depend on any suspicious NIST defined constants. If you encounter a server that is very old and does not support Ed25519 keys, you might need to have a more traditinal RSA keypair. A strong 4k RSA key pair can be generated with
ssh-keygen -b 4096. Hopefully you won’t need to ever do that.
ssh-keygen will prompt for a password. If your laptop is encrypted and well protected you can omit the password and gain some speed and convenience in your SSH commands.
Store the private key securely
Hopefully your laptop is well protected with full disk encryption etc and you can trust that nobody else than yourself has access to your
/home/<username>/.ssh directory. Hopefully you also have securely stored encrypted backups of your laptop so that you can recover the
.ssh directory if your laptop for any reason is lost or broken.
The SSH keyfiles are stored as armored ASCII, which means that you could even print them on paper and store the printed key in a real vault just to be extra sure you never loose your private key (
The public key is indeed designed to be public
The public key
.ssh/id_ed25519.pubon the other hand is meant to be public. Here is mine for example:
~/.ssh$ cat id_ed25519.pub ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMdBlrVoDupARk3pd1Q9sDImaGCxEalcFt7QTqBa36kH otto@XPS-13-9370
You can find a lot of public SSH keys for example on Github using the URL
https://github.com/<username>.keys. You may also want to check out the excellent Github SSH usage docs.
This public key is the one you will distribute to remote servers. Place them on the remote server in the
.ssh/authorized_keys file. The servers you try to access will use the public key to create a challenge, and only your laptop that has the private key pair can solve that challenge, and thus authenticate that your connection to the server is authorized.
On Linux machines a shorthand to copy your SSH key to a remote server is to run
ssh-copy-id remote.example.com. This will ask for a password on the first time, but once the key is in place, a SSH keys will be used instead and no password is asked anymore.
Once you are familiar with SSH key usage basics, please adopt these policies:
- Disable password authentication on the SSH servers you control altogether. The less there are passwords, the less there as ones that can leak or be forgotten etc. For passwords less is indeed more. Only use keys for authentication on SSH connections.
- Use a separate key per client you SSH from. So don’t copy the private key from your laptop to another laptop for use in parallel. Each client system should have only one key, so in case a key leaks, you know which client system was compromised. If you stop using your old laptop and start using a new one it is naturally another case and then you can copy the key.
- Avoid chaining SSH connections. Any system that is used for chaining SSH connections incurs a potential man-in-the-middle situation.
- For the same reasons try to avoid X11 forwarding and agent forwarding. Consider putting these in your
Host * ForwardX11 no ForwardAgent no
You shouldn’t forward SSH agent (
ssh -A), but it’s ok to use
ProxyJump. You can permanently configure it in your
.ssh/config like this:
Host backend.example.com Hostname 18.104.22.168. Port 23 ProxyCommand ssh bastion.example.com -W %h:%p
ssh remote.example.comyields some error messages, don’t ignore them! SSH has an opportunistic key model, which is convenient, but it also means that if you are confronted with warnings that the connection might be eavesdropped you should really take note and not proceed.