post-images/multiple-ssh-key-management/cover.jpg

Multiple SSH Key Management

I wanted to record an event that I had today and put it in writing so that you can benefit.

When we want to define another ssh key on the server that already has an SSH key definition, you may not want to touch the existing SSH key. In this case, I will tell you how to follow a method.

If we rewind to the source of the subject; When we want to access or manage the codes on our git server (Github, Bitbucket, GitLab etc.) on any machine, you may encounter an error as follows. This message says that you could not handshake between your machine (server, local) and your git server, in summary, the SSH key on your machine and the access key on your git server do not match.

#GitHub
ssh: Could not resolve hostname github.com:username: nodename nor servname provided, or not known
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
#Bitbucket
ssh: Could not resolve hostname bitbucket.org: Name or service not known
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

To solve this problem, you need to generate an SSH key (id_rsa, id_rsa.pub) on your machine and define the public key (id_rsa.pub) of this key to your git server. In this way, when you want to access the repo, these two keys will be compared and if they access each other, your identity will be authenticated. After this process, you can manage the codes on your git server from your machine without any problems.

If we take this process step by step;

Creating SSH Key:

$ ssh-keygen -t rsa -b 4096 -C "your@email.com" 

After the command is entered, you will be greeted with a warning as follows. The .ssh directory will point to the $HOME directory by default. This part is important to us, do not change it unless necessary.

Generating public/private rsa key pair.  
Enter file in which to save the key (/home/emre/.ssh/id_rsa):

As a result, you should see a screen like the one below.

$ ssh-keygen  
Generating public/private rsa key pair.  
Enter file in which to save the key (/home/emre/.ssh/id_rsa):  
Created directory '/home/emre/.ssh'.  
Enter passphrase (empty for no passphrase):  
Enter same passphrase again:  
Your identification has been saved in //home/emre/.ssh/id_rsa.  
Your public key has been saved in /home/emre/.ssh/id_rsa.pub.  
The key fingerprint is:  
4c:80:61:2c:00:3f:9d:dc:08:41:2e:c0:cf:b9:17:69 emre@myhost.local  
The key's randomart image is:  
+--[ RSA 2048]----+  
|*o+ooo.          |  
|.+.=o+ . 	  |  
|. *.* o . 	  |  
| . = E o 	  |  
| o . S 	  |  
| . . 		  |  
| . 		  |  
| 	          |  
| 	          |  
+-----------------+

To see the generated public key:

$ ls ~/.ssh
id_rsa id_rsa.pub

This command shows two files, one for the public key ( id_rsa.pub ) and one for the private key ( id_rsa ).

$ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFQAAAAdzc2gtcn
NhAAAAAwEAAQAAAf8rzyak4sv8oWg2j2XC3zdUogh2639L1UsHUog/8rICc/QnKAJeZrfI
vsHHm9u3mrCYojZ9YmnNNK1lrSdE5lZzfrqfcEkIkC93ghoW+ijEpPvcOpfp8UN9ikedpj
...
fQgfdDa31aFAAABxlbXJlLnlpbGRpcmlt3f5ADAgdAQHNhaGliaW5kZW4uY29tAQIDBA==
-----END OPENSSH PRIVATE KEY-----
$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAB/yvPJqTiy/yhaDaPZcLfN1SiCHbrf0vVa
SwdSiD/ysgJz9CcoAl5mt8i+wceb27easJiiNn1iac00rWWtJ0TmVnN+up9wSQiQL3eC4
a2OZjbm0j79W9QDzSJtSBvpoRSyc+5jg6X2APtS/r+StOoeqAebMOrO3+ENtIkL2+97M5
....
afgZ1FAS0TrZGeQrvX0aXWagXZ856NoFHexNAaMems= emre.yildirim@mryldrm.com

Now we have a special SSH key for our machine. We need to copy the contents of the public key file we have produced and add it to our git server.

SSH Copy Shortcut

Windows

clip < id_rsa.pub

Mac OS X

pbcopy < ~/.ssh/id_rsa.pub

Linux

xclip -sel clip < ~/.ssh/id_rsa.pub

Defining SSH key for GitHub Official Doc: Adding a new SSH key to your GitHub account

Defining SSH key for Bitbucket Official Doc: SSH access keys for system use

Define Multiple SSH

If we come to the reason for writing the article and the exception that I came across; In the light of the information above, let's assume that we have a machine and we create our SSH keys for this machine and make the definitions on our git server.

Considering my situation, what do we do when we need to access another git server from our server or we want to access a new repo? Likewise, we can define the id_rsa.pub that we created earlier for the new git server or repo. But things get a little messy when authorization comes into the event. Namely;

root design

Suppose we have a structure like the one above. Let's say we have one main server ( root ). Let's assume that this main server can create n virtual servers ( S1, S2, S3... ). In this case, instead of assigning SSH to all servers one by one, it is a good solution to transfer the root's profile to all servers and define root's SSH key to git server. In this way, all subservers will be able to access git with the same SSH key.

So what do we do if we only want to access a different git server or repo from one server, but not access it from other servers? We may only want a specific server to have access to the codes. sub server design

We can create a new SSH key for the server we want to differentiate. In this case, we encounter the problem of overriding the actual SSH key ( id_rsa ). If we create a new SSH key, we will have access to all servers that we connect with the old SSH key, as the old SSH key will change. As a workaround, I can generate a key with a new name ( server1.pub ) without overriding the id_rsa file. But there is a problem here, the servers we want to connect will look at the default directory ~/.ssh/id_rsa.pub. Not the ~/.ssh/server1.pub that I created. There is a way to solve this problem too: Configuring SSH.

SSH Configuration

In ~/.ssh/, create a file named config and add the definitions you want to redirect to.

#root
Host root
    HostName github.com
    User root
    IdentityFile ~/.ssh/id_rsa
    IdentitiesOnly yes
     
#server1
Host server1
    HostName bitbucket.org
    User server1
    IdentityFile ~/.ssh/server1
    IdentitiesOnly yes

#server2
Host server2
    HostName bitbucket.org
    User server2
    IdentityFile ~/.ssh/server2
    IdentitiesOnly yes
...

When one server uses GitHub and another server uses bitbucket, you won't have any routing problems, but if both servers need to point to the repo under the same git server (like server1 and server2 going to bitbucket), you can access it with a fake subdomain. Instead of git clone git@bitbucket.org:my-project/repo.git you can use git clone git@server2.bitbucket.org:my-project/repo.git.

Before I finish the article, I would like to talk about this tactic. If you say "I don't want to parse on a per-user basis. If there is an SSH key on the server that will allow me to access the git server, give it to me", you can change your config file as follows.

Host *
    IdentityFile ~/.ssh/id_rsa
    IdentityFile ~/.ssh/server1
SSHSSH KeysSSH ConfigurationGitGitHubBitbucket