I fire up ssh-keygen to create my shiny new SSH key pair. At first, it asks me for the location to store the keys. So far, so good. The default location is just fine. Then it stares me in the face. The question I’m not sure about:
Enter passphrase (empty for no passphrase):
Do I enter a passphrase and enslave myself to hammering an overly complicated sequence of letters, symbols, and numbers every time I log in? Or do I just hit the enter key and enjoy the wonderful world of passwordless authentication for the lifetime of the key pair?
I have been using SSH for so many years, that it has become a fixed part of my life. Yet, I am never really sure if I should have a passphrase or not. What if someone gets access to my private key? What if I want to have a script login to the server without me being present to enter the passphrase?
I am sure that I’m not the only one that is conflicted about this seemingly simple decision. So I decided to do a little research into what others are doing and what might be considered best practice.
There is no yes or no answer to this question, and I don’t claim to have all the answers. But I hope this post will help someone else to come to a conclusion based on their needs.
What’s the purpose of an SSH passphrase anyway?
Your private key is like the key to your house. If you have it, it can grant you access to hosts that have your public key. The public key in this analogy is the lock that the private key fits into. If you need more information on public and private keys, check out the article: “How to generate an SSH key“.
The passphrase adds a layer of security by encrypting the private key. Rendering it useless if it cannot be decrypted.
This makes it difficult for an attacker to get access to your systems. Even though he has your key.
Note that I said difficult but not impossible! There is still a possibility that the key could be decrypted if it falls into the wrong hands. The encryption itself is decently secure in most cases, but an attacker would be able to copy it somewhere else and apply every brute force tactic in the book. All without risking being detected.
Some people are also using an old key pair with keys that are short in length (like 512 bit keys) or that were generated with a cryptographic library that has been found to have bugs that result in weaker keys. You should always generate new keys regularly to avoid having keys that are likely to be insecure.
Disadvantages of having a passphrase
One reason to have passwordless authentication is to have automated scripts or programs access the remote host without any human interaction. As an example, rsync can automatically retrieve files from the remote server via SSH.
This is a bit more complicated if you need to enter a passphrase every time the private key is used.
Can SSH remember the passphrase of my key?
Wouldn’t it be nice if you could have a passphrase and still be able to automatically log in without using it? That seems kind of contradictory. But maybe there is a way.
Here is one method that I found.
Use ssh-agent to remember the passphrase
There is a tool that comes with OpenSSH, called ssh-agent. Ssh-agent will hold your private key within your login session. To enable ssh agent you will need to start it from the session you intend to using. It will output a couple of environment variables that need to be exported to you session. Use eval to catch these variables and automatically apply them:
[email protected]:~$ eval $(ssh-agent) Agent pid 218387
Now you can add your key and passphrase to ssh-agent:
[email protected]:~$ ssh-add Enter passphrase for /home/max/.ssh/id_rsa: Identity added: /home/max/.ssh/id_rsa ([email protected])
Now you can log in to remote hosts without entering the passphrase. The only problem is that you still need to enter the passphrase for every session. So for automated scripts running as cron jobs, this won’t help much. You could save the environment variables from ssh-agent and execute them automatically for every session that is created. But, this would still require that you enter the passphrase after every restart. Since it is only stored in memory.
As far as I know, there is no secure way to store the passphrase for automated jobs other than to enter it after every restart.
Keep your secrets safe
Even if you have a passphrase, the single most important thing you can do, security wise, is to safeguard your private key. Having a passphrase can be a good security measure, but keeping your key safe will always be the most important one.
I have added some good practices to keep in mind when managing your keys.
Don’t store your personal key on a server
It is common for many organizations to have a jump host. A server that you can log on to, remotely, in order to get access to other hosts on the network. Storing your personal private key on such a host is not a good idea. If the jump host is compromised, so will your key.
If you need to use a jump host, a better idea is to to tunnel through the jump host and use the key on your workstation. OpenSSH provides the functionality to do this with one command.
ssh -J [email protected] [email protected]
This command will create an SSH tunnel through the jump host to the destination host. Authentication to the destination host will be handled by the SSH client on the host the command is run from. This means the jump host will never have the private key.
Do not use the same key for everything
When setting up automated tasks such as backup retrieval, it is often tempting to use a key pair that you already have. So you might end up with a copy of the same private key on multiple hosts.
It would be better to create a separate key pair for each host and then only add the public key to the hosts it is supposed to have access to.
Lock down what each key can do
When adding a key to the authorized_keys file on a host, you can actually add restrictions to what the key can do. Such as from what host it is permitted to log in from. You can find more information in the sshd man file. But here are some basic examples:
Only allow key from IP address 10.1.1.1:
from="10.1.1.1" ssh-rsa AAAAB4..21Q== [email protected]
Only allow the key before June 1st 2021:
expiry-time="20210601" ssh-rsa AAAAB4..21Q== [email protected]
Disable port forwarding for this key:
no-port-forwarding ssh-rsa AAAAB4..21Q== [email protected]
Renew your keys regularly
In case your key is compromised and you don’t know about it, it is advisable to create a new key pair every now and then. After adding the new public key to the authorized_keys file, remove the old one.
I think we can safely say, that there is added security in having a passphrase. But it is a hassle and in some cases, it is just not feasible. If you can live with the drawbacks, it is a good idea to have a passphrase and use ssh-agent to decrease the number of times you need to enter the passphrase.
But whatever you do, just make sure you keep your key safe.