Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use multiple SSH keys on GitHub?

Tags:

git

github

ssh

The SSH configuration on GitHub seems to be a nightmare. I have multiple GitHub accounts, but for which I can have multiple SSH keys. In the GitHub SSH configuration section they mention this:

ssh-keygen -t rsa -C "[email protected]"
# Creates a new ssh key, using the provided email as a label
# Generating public/private rsa key pair.

We strongly suggest keeping the default settings as they are, so when you're prompted to "Enter a file in which to save the key", just press Enter to continue.

# Enter file in which to save the key (/Users/you/.ssh/id_rsa): [Press enter]

Why should I always use an id_rsa file? It will overwrite my existing keys. Anyway, I give a new name here and generate the key. I do all the other steps of adding it to the agent, updating in the GitHub SSH keys section.

After completing all those steps I come to the final step which is:

$ ssh -vT [email protected]
Hi animesh11! You've successfully authenticated, but GitHub does not provide shell access.
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 3128, received 1976 bytes, in 0.5 seconds
Bytes per second: sent 6077.0, received 3838.9
debug1: Exit status 1

Everything is hunky dory, but somehow git clone still complains:

$ git clone [email protected]:regentmarkets/devbox.git
Cloning into 'devbox'...
ERROR: Repository not found.
fatal: Could not read from remote repository.

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

I am up to my wits end why the ssh -vT works and simple cloning doesn't.

like image 289
coffeequant Avatar asked Mar 13 '15 01:03

coffeequant


People also ask

Can you have multiple SSH keys for GitHub?

For instance, you can run an Organization's GitHub account and another one for your personal projects all on the same computer. In this article, you will learn how to use multiple SSH keys for different GitHub accounts. While working with two different GitHub accounts, you must set them up using an SSH key.

Can I use multiple SSH keys?

You use SSH for connecting to remote servers, which also includes managing your code using Git and syncing with remote repositories. Even though it is considered a good practice to have one private-public key pair per device, sometimes you need to use multiple keys and/or you have unorthodox key names.

How many SSH keys can you have on GitHub?

So, when you (as a user) setup your git environment you can create only one ssh-key for each machine you would like to give permission to your GitHub's account. As a user, you are not limited to one SSH key.


2 Answers

I'd use .ssh config to set up different configurations for each particular user.

For example, edit (or create) the config file in the .ssh folder under your users root, and add something similar to this:

Host user1-github
    HostName github.com
    User git
    IdentityFile ~/.ssh/user1_rsa
Host user2-github
    HostName github.com
    User git
    IdentityFile ~/.ssh/user2_rsa

Where user1_rsa and user2_rsa are the outputs of ssh-keygen -t rsa -C "[email protected]" and ssh-keygen -t rsa -C "[email protected]"

Then, when testing simply use ssh -vT user1-github and ssh -vT user2-github.

Also, when cloning repos use git clone user1-github:username1/project.git or git clone user2-github:username2/project.git.

like image 130
Serban Constantin Avatar answered Sep 28 '22 11:09

Serban Constantin


As a complement to Serban's solution, here is another way to use the .ssh/config file to distinguish the users. A bit more hacky, but does not require changing the host names.

Let's say you have a pro and a personal account, and that you set up your keys like this:

$ ssh-keygen -t rsa -f ~/.ssh/perso_rsa -C "[email protected]"
$ ssh-keygen -t rsa -f ~/.ssh/pro_rsa   -C "[email protected]"

Now most of the time, there is something you can use to distinguish the two identities. Typically, when working on a git repo, your git configuration is tied to the identity you want to use, and for example git config user.email will return one of the two email addresses, the one associated to the identity for this repo.

Based on that, we can use the Match exec <cmd> filtering directive in the .ssh/config, and write something like this:

Match host github.com exec "[ $(git config user.email) = [email protected] ]"
    IdentityFile ~/.ssh/perso_rsa

Host github.com
    IdentityFile ~/.ssh/pro_rsa

And just use the regular [email protected]:user/project.git for both identities.

It works as follows: When the host is github.com, the first matching rule is used to determine the IdentityFile to use. For the first rule, the exec command is run and the rule is selected if that command returns a zero exit status. Our test (passed to the user's shell) checks whether git config user.email returns [email protected]. If this is the case, the check returns true, the rule match, and ~/.ssh/perso_rsa is picked. If not, the second rule acts as a catch-all for github.com, and ~/.ssh/pro_rsa is picked instead.

We could have added another check for the second identity, but with only two rules it is not necessary, the “catch-all” behaviour should be enough.

We could also adapt the check to test other parameters insted of the user.email from git. For example, we could check the name of the current working directory. See man ssh_config for more details on Match exec.

Additional remarks (credits to Acumenus):

  • If supported by the user's shell (bash, zsh at least), double square brackets are necessary if part of the check (in our case, $(git config user.email)) evaluates to multiple words, as single brackets will break. Ideally we would like to enquote that between double quotes, but they are used for the argument for exec already and I did not find a way to escape them.
  • With this setup, cloning new repositories through SSH will use the key associated to the default user email (first user.email entry in git config -l). To clone a repository with the other key, one solution is to first create the repository, then add a remote and pull: mkdir foo; cd foo; git init; git config ...; git remote add origin <URL>; git pull.
  • The catch-all rule is of course unnecessary if the file for the key is one that ssh looks for by default, such as $HOME/.ssh/id_rsa.
  • The host directive can be used to match several comma-separated hosts at once if necessary (Match host github.com,gitlab.com exec ...).
like image 23
Qeole Avatar answered Sep 28 '22 12:09

Qeole