Switch SSH Keys by Host
When we are using multiple SSH keys for our accounts and projects, key management could become challenging. Running the SSH CLI command with the secret key option every single time could also be tedious.
Today, I would like to share a clean and easy way to manage SSH keys by hosts.
TL;DR
How to Assign Keys to a Host
In short, we can add a ~/.ssh/config
file and define each host.
.ssh/config - Syntax
Host CONNECTION_NAMEHostName HOST_NAMEIdentityFile SSH_KEYUser USER_NAMEPort PORT_NUM
CONNECTION_NAME
: A name you will pass to run ssh. e.g. github.workHOST_NAME
: Actual host domain or IP. e.g. github.comSSH_KEY
: The path to your key. e.g. ~/.ssh/id_rsa_workUSER_NAME
: The user name you ssh into. e.g. gitPORT_NUM
: Usually 22
Now let's take a look at actual use cases.
Use Case 1 - Multiple Git Accounts
Let's pick the example where you have multiple git accounts and have registered a different secret key for each.
Generate a Key for Each Account
If you use different email addresses for each account, it would be easier to identify each one if you include the email in the comment.
In this example, let’s use _work
and _personal
suffixes for the key names.
# For a work account$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_work.pub -C "workie@email.com"# For a personal account$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_personal.pub -C "foo@email.com"
Edit .ssh/config
Now, this is the core part of this management trick. We will define ssh hosts on the ssh/config
file.
$ vim ~/.ssh/config
Host Setting Example
Host github.wHostName github.comIdentityFile ~/.ssh/id_rsa_workUser gitPort 22Host github.pHostName github.comIdentityFile ~/.ssh/id_rsa_personalUser gitPort 22
Just in case you were wondering, the default key id_rsa
would be used if you haven’t set any key for the git domain.
I won’t cover how to register an ssh key to the git remote. Once the editing is done, check the connection with the command below:
$ ssh github.w# This is equivalent to below:# ssh -i ~/.ssh/id_rsa_work git@github.com
If you successfully connected, let’s move on to the git repo config.
Edit .git/config
You can set the remote host either by directly editing .git/config or the Git CLI.
All you have to do is to replace git@github.com
with the Host CONNECTION_NAME you defined on .ssh/config.
# Work Account[remote "origin"]url = github.w:workie/REPOSITORY.gitfetch = +refs/heads/*:refs/remotes/origin/*# Personal Account[remote "origin"]url = github.p:foo/REPOSITORY.gitfetch = +refs/heads/*:refs/remotes/origin/*
Git CLI
# Update$ git remote set-url origin github.w:workie/REPOSITORY.git# Add$ git remote add origin github.w:workie/REPOSITORY.git
Voila! Git will use the assigned keys for remote repo connections from now on.
Use Case 2 - SSH into an EC2 Bastion Host
Another example of an SSH connection is for an EC2 bastion host.
When you are running EC2 instances in a private subnet, you would probably add a bastion host in a public subnet through which you would be able to talk to the ones in the private subnet. (Side note: You can log in to the EC2 instance shell via SSM Session Manager or EC2 dashboard now. So no bastion hosts are required.)
Launch an EC2
When you launch an EC2 instance, make sure you assign a key pair.
Allocate an EIP and Associate It to the Instance
This is not mandatory. However, the default public IP address will change if you make changes such as the instance type, or Stop/Start (except Reboot) the instance. So, let’s make the IP persistent since EIP is free as long as it’s attached to an instance.
Add EIP to .ssh/config
Now, let's add the public IP of the EIP to our .ssh/config
file.
Copy and paste the EIP address to the new host:
Host tokyo-bastionHostname 52.193.31.148User ec2-userPort 22IdentityFile ~/.ssh/aws/tokyo_bastion.pem
Change the Key Permissions
As many of you know, AWS enforces you to change the permissions of your keys to make sure they are securely managed on your end.
If you run an ssh command without changing the permissions, you will get an error like the below:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: UNPROTECTED PRIVATE KEY FILE! @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Permissions 0644 for '~/.ssh/aws/tokyo_bastion.pem' are too open.
To prevent this, you can simply run the following command to remove the read permissions from the group and anyone:
$ chmod 600 ~/.ssh/aws/tokyo_bastion.pem
SSH Into the Instance
Finally, we are ready to run the ssh command.
$ ssh tokyo-bastion, #_~\_ ####_ Amazon Linux 2023~~ \_#####\~~ \###|~~ \#/ ___ https://aws.amazon.com/linux/amazon-linux-2023~~ V~' '->~~~ /~~._. _/_/ _/_/m/'[ec2-user@ip-172-31-45-46 ~]$
Beautiful. Now let it fly!