How to SSH - Organising Multiple Identities
One challenge with SSH is that the default behaviour of ssh-keygen
becomes inadequate when managing more than one key.
Creating the first SSH key pair is easy. Running ssh-keygen
creates two files - id_ed25519
and id_ed25519.pub
- in the ~/.ssh
folder.
The problems begin when creating additional key pairs. Re-running the ssh-keygen
command tries to overwrite the same files. Assigning a custom name to the private key, such as id_2.0
, requires explicitly referencing the file name in subsequent commands, such as ssh -i id_2.0
, which is tedious.
A possible solution involves two components. First, using the ~/.ssh/config
file to map key files to specific hosts. Second, using long, descriptive names for each key file to remember the key's purpose.
Scenario
Assume one has three devices - a personal macOS laptop, a work Windows laptop, and a shared Windows desktop - and two GitHub accounts: alex783890
and pagnul
. They also have a virtual machine hosted on Vultr.
With three client devices and three servers, there are nine connections, each requiring its own SSH key pair. As such, each client device stores three private keys - one for each server. And each server stores three public keys - one for each client.
When a device is no longer in use, one removes the corresponding public keys from each server. Similarly, when a server is retired, one removes the associated private keys from each device.
Solution
An example key naming format is: id_{encryption algorithm}_{device}_{server}_{account}
. Using this format, the nine keys in the scenario could be named as follows:
id_ed25519_macos_github_alex783890
id_ed25519_macos_github_pagnul
id_ed25519_macos_vultr_root
id_ed25519_work-laptop_github_alex783890
id_ed25519_work-laptop_github_pagnul
id_ed25519_work-laptop_vultr_root
id_ed25519_shared-windows-desktop_github_alex783890
id_ed25519_shared-windows-desktop_github_pagnul
id_ed25519_shared-windows-desktop_vultr_root
These names are clear and unambiguous, assuming a single work laptop, Vultr virtual machine, etc. When more devices or servers are introduced, the names can be made more specific. A passphrase further secures private keys, particularly on shared computers.
To generate such a key pair, the following command can be used: ssh-keygen -t ed25519 -f id_ed25519_macos_github_alex783890 -C 'MacOS Alex 783890'
. The documentation on ssh-keygen
can be accessed through the man ssh-keygen
command or online, for example here.
The second component of the solution is the ~/.ssh/config
file. SSH config documentation is available here. Here is an example configuration:
Host github-alex783890
HostName github.com
IdentityFile ~/.ssh/id_ed25519_macos_github_alex783890
IdentitiesOnly yes
Host github-pagnul
HostName github.com
IdentityFile ~/.ssh/id_ed25519_macos_github_pagnul
IdentitiesOnly yes
Host vultr
HostName abc.def.ghi.jkl
User root
IdentityFile ~/.ssh/id_ed25519_macos_vultr_root
IdentitiesOnly yes
Host aliases - such as github-alex783890
and github-pagnul
- distinguish multiple accounts on the same host. They can also provide a shorter identifier, such as vultr
instead of root@abc.def.ghi.jkl
.
The connections can be now be established with commands such as ssh vultr
or explicit ssh -i ~/.ssh/id_ed25519_macos_vultr_root root@abc.def.ghi.jkl
.
And for GitHub, the commands look like ssh -T git@github-pagnul
and git remote add origin git@github-pagnul:pagnul/myproject.git
.