Public Key Authentication
Connecting without passwords, incluidng across multiple jumps.
Passwords aren’t the only way to authenticate with SSH. SSH public keys allow you to authenticate without needing to enter a password, including across multiple host jumps. They are also the only way to authenticate with the SSH support on Git hosts like GitHub, GitLab, and Codeberg, so if you want to use SSH URLs to push/pull from such services, you will need to set up public key authentication.
To use SSH public key authentication, you need to generate a keypair consisting of two parts: a private key and a public key. Keep your private key safe on your computer, and record the public key with the various services you want to access. When you connect, SSH uses your private key to generate a signature that proves you have access to the private key, and the remote system verifies that signature with the public key. Since the only way to generate a signature that is valid for a particular public key is to have its corresponding private key, it works as a secure authentication method.
Public-key authentication can be done via authentication agents, in which you can load your key once and reuse it for multiple connections without needing to re-load the key or re-enter your key’s passphrase. The SSH agent protocol also allows for further protection of your credentials, such as storing them in the Secure Enclave on a Mac.
If you keep your private key properly secured, public-key authentication is also more secure than password-based authentication.
Setting Up Remote Access
Your public key looks something like this:
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP6owqQRBkU/+sxBE922X1iyNOXk35+5sySyZ9CW1TfM mde48@drexel.edu
The first part is the key algorithm, the second part is the key itself, and the third part is a comment. The comment is ignored for checking the key, but is helpful for you to know where a key came from.
For normal Linux and UNIX servers, the file ~/.ssh/authorized_keys (on the remote system) defines the public keys that are valid for logging in to your account. This is a text file listing the valid public keys, one per line. To set up your keypair to log in to a system, just connect to the system with your password (or another key) and add your public key (not your private key) to this file.
For systems like GitHub or GitLab, you need to add your public key in your user settings through the web interface. Log in, go to your account settings, and there is usually an option for “SSH Keys” (or “SSH & GPG Keys”).
Protecting your Private Key
It is absolutely critical to keep your private key private: if someone obtains a copy of your private key, they can authenticate as you to any system where the public key is enrolled. It isn’t much different from a password in this regard, but private keys are always stored as files on your system, as opposed to being memorized. So long as you keep that file secure, it is more secure than most memorized passwords.
SSH will, by default, encrypt your private key with a passphrase, so anyone with a copy of the file also needs to know the passphrase. I’ll talk about that later, but keep reading for easier ways to manage your private key.
Password Manager
The easiest way I know to work with SSH private keys across platforms is to generate and store them directly in a password manager that has SSH Agent capabilities. You should be using a password manager anyway, as using unique passwords stored in a password manager is well-established best practice.
The details will differ between password managers, but some of them support saving your SSH keys and acting as an SSH Agent to allow your SSH connections to directly use the key stored in the password manager.
I use 1Password, and you can find its SSH Agent instructions here.
There are a couple of steps to using SSH keys with your password manager:
- Generate the SSH key in the password manager.
- Configure your SSH client according to your password manager’s instructions.
- Copy the public key, and add it to your remote systems (see below).
Access to the SSH private key is then handled like access to your passwords: if the password manager is locked, it will prompt you for your unlock password or your biometrics.
If you know of other password managers that work as SSH agents, file an issue with info about them and a link to their instructions, and I will see about expanding this list.
Mac Secure Enclave
Mac computers have a secure enclave for storing authentication information securely, where it cannot be leaked even if someone steals your computer.
Secretive is a program that implements an SSH Agent using the Secure Enclave to store your private key. If you don’t use a password manager with native SSH support, this is the method I recommend on macOS.
Using Secretive is somewhat like a password manager: you will generate your private key in Secretive, and it will give you the public key to copy. The private key is protected by the Secure Enclave, and will only unlock with proper authentication (your Mac password, your fingerprint, or activation on an Apple Watch). Secure Enclave security is handled directly by the hardware, so it is highly secure: nothing — not even Secretive — has access to your primary key. Secretive sends an authentication request to the Secure Enclave, the Enclave asks for password or biometric authentication, and then the Enclave replies with the authentication data. It’s one of the best ways I know to manage private keys without the risk of even accidentally leaking your key.
There are two downsides to Secretive:
- Your private key is bound to that specific computer, and each computer will need a different private key. This is good practice anyway, at least if you are not using a password manager, so it isn’t much of a problem.
- You need to authenticate with the Enclave for every authentication action. For example, if you are using a jump host, you will need to authenticate twice. With biometric authentication, it isn’t a big deal, but it is something you should be aware of.
OpenSSH Agent
OpenSSH — the standard software for making SSH connections — also includes an SSH agent. Most Linux distributions and macOS configure this to run automatically when you log in graphically (SSH connections to a remote Linux machine will not usually set up an agent on that machine), so it’s widely available without configuration.
The default OpenSSH agent is a little harder to use securely than either Secretive or a good password manager, because once your key is added to the agent there are no further checks on when that key is used or which programs use it. Secretive requires you to verify every authentication, and 1Password is configurable but will periodically re-confirm, and will also require you to verify when a different program is trying to use the SSH agent.
You can check if it is running with:
$ ssh-add -l
The agent has no identities.If the agent is not running, it will instead respond with:
$ ssh-add -l
Could not open a connection to your authentication agent.To use the native SSH agent:
Generate an SSH keypair with
ssh-keygen, and encrypt it with a passphrase. This passphrase should be strong — Diceware is a good option.$ ssh-keygen -t ed25519 Generating public/private ed25519 key pair. Enter file in which to save the key (/home/mde48/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/mde48/.ssh/id_ed25519 Your public key has been saved in /home/mde48/.ssh/id_ed25519.pub The key fingerprint is: SHA256:mtQRNvM1205m0L1VpUuGtOQSjBdATEexMnoxRB5+GvU mde48@tux1 The key's randomart image is: +--[ED25519 256]--+ | =%=Bo*. .=| | =oOoO B..o| | X.= E O o| | o X . B o | | o S o | | . + | | o | | | | | +----[SHA256]-----+Add your key to the agent:
$ ssh-add ssh-add Enter passphrase for /home/mde48/.ssh/id_ed25519: Identity added: /home/mde48/.ssh/id_ed25519 (mde48@tux1)You need to do this for each login session to your computer (but not each separate terminal session). You can use
ssh-add -las above to check if your key is already added. Since the agent is shared across your entire graphical session, adding your key in the terminal will let it work for other programs like VS Code.You can also specify a timeout for your key, to automatically unload it after a specified time. Do this with
-t:$ ssh-add -t 10mConnect to remote machines!
If someone gets a copy of your encrypted SSH key file, there are no limits on how long or hard they can try to crack the passphrase to get access to your key. The passphrase should be very strong to ensure your key is not compromised.
Built-In Agents
Several programs, such as ShellFish and MobaXTerm, have their own SSH agents and key management built in. Consult their documentation for details on how to create keys and enable SSH agents, as well as their features for protecting your private key.
It has been a while since I have used Windows as a daily driver, but if you don’t have a password manager, MobaXTerm might be the easiest way to get a working SSH agent set up on Windows.
Directly Using the File
If you don’t have an agent set up, but you do have a private key, OpenSSH will prompt you for the passphrase for the private key and use it. This is just as annoying as using passwords all the time, if not more annoying, so it’s really easiest to use an agent if you’re using public keys.
Forwarding the Agent
The SSH tool also supports agent forwarding: setting up your remote shell session to call back to your local machine’s agent to handle further authentication. This is very useful for things like pushing/pulling from remote Git repositories, because you can forward your agent and then use Git SSH URLs in your remote Git working directories.
To enable SSH forwarding on a single session, use -A:
$ ssh -A tux.cs.drexel.eduTo turn on SSH forwarding by default for one or more computers, you can add to your ~/.ssh/config:
Host *.cci.drexel.edu
ForwardAgent yesOnly enable agent forwarding for connections to systems where you trust the system administrator. This is because root administrators on the remote system can access any user’s forwarded agent.