Reputation: 6262
I'm having some trouble getting two different SSH keys/GitHub accounts to play well together. I have the following setup:
Repos accessible from one account using git@github.com:accountname
Repos accessible from another account using git@github.com:anotheraccount
Each account has its own SSH key. Both SSH keys have been added and I have created a config file. I don't believe the config file is correct though. I'm not quite sure how to specify that repos accessed using git@github.com:accountname
should use id_rsa
and git@github.com:anotheraccount
should use id_rsa_anotheraccount
.
Upvotes: 362
Views: 193498
Reputation: 4481
Andy Lester's response is accurate but I found an important extra step I needed to make to get this to work. In trying to get two profiles set up, one for personal and one for work, my ~/.ssh/config
was roughly as follows:
Host me.github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/me_rsa
Host work.github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/work_rsa
My work profile didn't take until I did a ssh-add ~/.ssh/work_rsa
. After that connections to github used the correct profile. Previously they defaulted to the first public key.
If you encounter problems, they are likely from using the wrong account. You can troubleshoot things from the command line with a command like this (use ssh -vvv
for max verbosity):
$ GIT_SSH_COMMAND='ssh -v' git pull --verbose
For Could not open a connection to your authentication agent when using ssh-add
,
check https://stackoverflow.com/a/17695338/1760313
For defaulted to the first public key, add IdentitiesOnly
to the Host *
section at the bottom of your ~/.ssh/config
file. This tells ssh to only use specified identities rather than all unlocked keys in your agent.
If your Host *
section has an IdentityFile
line, this will not work. Remove that line and add it to a new Host !work.github.com *
secion.
If you use ControlMaster
and you try to use different Github accounts before the ControlPersist
timeout expires, it will use the persisted connection, which may be for the other account. Change your ControlPath
to include %k
(the host key alias if specified, otherwise this is identical to %h
, the hostname). If you prefer, you can limit this to just one Github account's path with e.g. ControlPath ~/.ssh/control-%C-2
solely in the Host work.github.com
stanza.
Upvotes: 431
Reputation: 5180
You don't have to edit your ssh config and deal with weird remote URLs at all. Leverage gitconfig!
# ~/.gitconfig, only used in this directory
[includeIf "gitdir:/home/user/work/"]
path = ~/.work.gitconfig
# ~/.work.gitconfig
[user]
email = "my_other_email@address.com"
name = John Doe
[core]
sshCommand = ssh -i ~/.ssh/id_rsa_work # use my other ssh key
Upvotes: 5
Reputation: 6479
Let's say alice
is a github.com user, with 2 or more private repositories repoN
.
For this example we'll work with just two repositories named repo1
and repo2
https://github.com/alice/repo1
https://github.com/alice/repo2
You need to be to pull from these repositories without entering a passwords probably on a server, or on multiple servers.
You want to perform git pull origin main
for example, and you want this to happen without asking for a password.
You don't like dealing with ssh-agent, you have discovered (or you're discovering now) about ~/.ssh/config
a file that let's your ssh client know what private key to use depending on Hostname and username, with a simple configuration entry that looks like this:
Host github.com
HostName github.com
User git
IdentityFile /home/alice/.ssh/alice_github.id_rsa
IdentitiesOnly yes
So you went ahead and created your (alice_github.id_rsa, alice_github.id_rsa.pub)
keypair, you then also went to your repository's .git/config
file and you modified the url of your remote origin
to be something like this:
[remote "origin"]
url = "ssh://git@github.com/alice/repo1.git"
And finally you went to the repository Settings > Deploy keys
section and added the contents of alice_github.id_rsa.pub
At this point you could do your git pull origin main
without entering a password without issue.
So your instinct will be to grab that key and add it to repo2
's Deploy keys, but github.com will error out and tell you that the key is already being used.
Now you go and generate another key (using ssh-keygen -t rsa -C "alice@alice.com"
without passwords of course), and so that this doesn't become a mess, you will now name your keys like this:
repo1
keypair: (repo1.alice_github.id_rsa, repo1.alice_github.id_rsa.pub)
repo2
keypair: (repo2.alice_github.id_rsa, repo2.alice_github.id_rsa.pub)
You will now put the new public key on repo2
's Deploy keys configuration at github.com, but now you have an ssh problem to deal with.
github.com
domain?Your .ssh/config
file points to github.com
and it doesn't know which key to use when it's time to do the pull.
So I found a trick with github.com. You can tell your ssh client that each repository lives in a different github.com subdomain, in these cases, they will be repo1.github.com
and repo2.github.com
So first thing is editing the .git/config
files on your repo clones, so they look like this instead:
For repo1
[remote "origin"]
url = "ssh://git@repo1.github.com/alice/repo1.git"
For repo2
[remote "origin"]
url = "ssh://git@repo2.github.com/alice/repo2.git"
And then, on your .ssh/config
file, now you will be able to enter a configuration for each subdomain :)
Host repo1.github.com
HostName github.com
User git
IdentityFile /home/alice/.ssh/repo1.alice_github.id_rsa
IdentitiesOnly yes
Host repo2.github.com
HostName github.com
User git
IdentityFile /home/alice/.ssh/repo2.alice_github.id_rsa
IdentitiesOnly yes
Now you are able to git pull origin main
without entering any passwords from both repositories.
If you have multiple machines, you could copy the keys to each of the machines and reuse them, but I'd advise doing the leg work to generate 1 key per machine and repo. You will have a lot more keys to handle, but you will be less vulnerable if one gets compromised.
Upvotes: 61
Reputation: 1201
I find solution of this problem and try to explain it.
We should make change in both file ~/.ssh/config
and in ~/.gitconfig
Let's show.
You will need one key for each different account you will use on either GitHub or BitBucket.
Whichever site you have more identities with determines how many keys you will need.
A single key can act both as a GitHub and BitBucket key but cannot be associated with more than one BitBucket or GitHub account.
If you already have created a key in ~/.ssh/id_rsa (the default location), you may use that in place of the ~/.ssh/msmith key in my examples or you can leave that key and add additional keys for the other identities.
Create the keys and ssh-add them (make sure to enter a secure password and do not just leave it blank)
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/key1_rsa -C "msmith@example.com"
Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): ************ Enter same passphrase again: Your identification has been saved in /Users/me/.ssh/key1_rsa. Your public key has been saved in /Users/me/.ssh/key1_rsa.pub. The key fingerprint is: ...
$ ssh-add ~/.ssh/key1_rsa
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/key2_rsa -C "jblige@example.com"
Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): ************ Enter same passphrase again: Your identification has been saved in /Users/me/.ssh/key2_rsa. Your public key has been saved in /Users/me/.ssh/key2_rsa.pub. The key fingerprint is: ...
$ ssh-add ~/.ssh/key2_rsa
Create a file in ~/.ssh/config (if it does not already exist). You must make sure it is readable only by the owner and the group and public bits are set off.
touch ~/.ssh/config
chmod 600 ~/.ssh/config
We now need to add SSH configuration that specifies the github and bitbucket hostnames but with a suffix appended to qualify which key to use. We set the HostName to the correct github.com or bitbucket.org address.
Note: Linux users should either omit UseKeychain yes or add IgnoreUnknown UseKeychain (thanks soulofmischief)
~/.ssh/config
...
Host github.com-msmith
HostName github.com
UseKeychain yes
AddKeysToAgent yes
User git
IdentityFile ~/.ssh/msmith_rsa
IdentitiesOnly yes
Host bitbucket.org-msmith
HostName bitbucket.org
UseKeychain yes
AddKeysToAgent yes
User git
IdentityFile ~/.ssh/msmith_rsa
IdentitiesOnly yes
Host github.com-jblige
HostName github.com
UseKeychain yes
AddKeysToAgent yes
User git
IdentityFile ~/.ssh/jblige_rsa
IdentitiesOnly yes
Host bitbucket.org-jblige
HostName bitbucket.org
UseKeychain yes
AddKeysToAgent yes
User git
IdentityFile ~/.ssh/jblige_rsa
IdentitiesOnly yes
...
Log into GitHub for each user and add the keys from ~/.ssh/xxxxx.pub to the respective users authorized SSH keys.
For more information on this see: https://confluence.atlassian.com/bitbucket/set-up-an-ssh-key-728138079.html
or
https://help.github.com/en/articles/adding-a-new-ssh-key-to-your-github-account
You will need a single directory where all code that corresponds to a given key will be checked out to.
I prefer to keep all those directories in one directory in my home ~/src and I name them according to the account name associated with the key
mkdir -p ~/src/msmith
mkdir -p ~/src/jblige
In each directory put a .gitconfig file.
~/src/msmith/.gitconfig
...
[user]
email = msmith@example.com
[url "git@bitbucket.org-msmith"]
insteadOf = git@bitbucket.org
[url "git@github.com-msmith"]
insteadOf = git@github.com
~/src/jblige/.gitconfig
...
[user]
email = jblige@example.com
signingkey = ABCD1234
[url "git@bitbucket.org-jblige"]
insteadOf = git@bitbucket.org
[url "git@github.com-jblige"]
insteadOf = git@github.com
[commit]
gpgsign = true
This way, I use the correct email address for both keys and have even set up automatic commit signing for jblige. I also rewrite all the hostnames for the original SSH connections to the correctly suffixed hostnames I created in the SSH config file.
For more information about GPG signing see:
https://help.github.com/en/articles/signing-commits
or
https://confluence.atlassian.com/bitbucketserver/using-gpg-keys-913477014.html
To activate the .gitconfig files in ~/src/*, edit the .gitconfig file in your home directory and add an includeif statement for each of the .gitconfig files referencing the directory they are in
~/.gitconfig
...
[includeif "gitdir:~/src/msmith/"]
path = ~/src/msmith/.gitconfig
[includeif "gitdir:~/src/jblige/"]
path = ~/src/jblige/.gitconfig
Do not forget the trailing slash in the [includeif "gitdir:... statement.
You then clone the code using the SSH clone address (i.e. git@bitbucket.org... or git@github.com..., not https://bitbucket.org... nor https://github.com...) into the directory that corresponds to the key you want to use for that clone.
$ cd ~/src/msmith
$ git clone git@github.com:someuser/somerepo.git
...
Because of the rewriting, git will actually attempt to clone using the suffixed address corresponding to the configuration in the SSH config file but because of the SSH configuration it will use the original hostname when actually connecting to the host ensuring you use the right key.
All commits/pulls/pushes to/from those repositories will use the corresponding config/key/account.
Upvotes: 9
Reputation: 10609
This is the only config that worked for me to be able to use two GitHub accounts with different SSH keys.
Replace id_ed25519
(representing my work SSH key) and id_ed25519-personal
(representing my personal SSH key) with your SSH keys' filenames.
Host github.com
IdentitiesOnly yes
IdentityFile ~/.ssh/id_ed25519
IdentityFile ~/.ssh/id_ed25519-personal
Upvotes: 1
Reputation: 320
Simplest way to use multiple Git accounts and clone without any changes would be to add your username to the ssh config.
~/.ssh/config
. Create if one doesn't existHost github.com:<YOUR_GITHUB_USERNAME>
AddKeysToAgent yes
IdentityFile ~/.ssh/<YOUR_SSH_KEY_FILENAME>
Replace <YOUR_GITHUB_USERNAME> with your desired github username (personal or work) Replace <YOUR_SSH_KEY_FILENAME> with your keyfile name in .ssh folder (ex: id_ed25519). Add a host record for each of the github account you want to maintain.
Now git clone would be simple as git clone github.com:<YOUR_GITHUB_USERNAME>/your-repo.git
. No custom gihub domains to remember when cloning ;-)
Made a gist with further information https://gist.github.com/udantha/fed5439630eaf4651272f4fba6e1c6a3
Upvotes: 4
Reputation: 14532
A possibly simpler alternative to editing the ssh config file (as suggested in all other answers), is to configure an individual repository to use a different (e.g. non-default) ssh key.
Inside the repository for which you want to use a different key, run:
git config core.sshCommand 'ssh -i ~/.ssh/id_rsa_anotheraccount'
If your key is passhprase-protected and you don't want to type your password every time, you have to add it to the ssh-agent. Here's how to do it for ubuntu and here for macOS.
It should also be possible to scale this approach to multiple repositories using global git config and conditional includes (see example).
Upvotes: 21
Reputation: 31189
I spent a lot of time to understand all the steps. So lets describe step by step:
ssh-keygen -t rsa
. Give it an alternative like proj1.id_rsa
and hit with no doubt because you don't need a passphrase.Add new section in .ssh/config
:
Host proj1.github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/proj1.id_rsa
Take into account the first section and note that proj1.github.com
we will back to the section later.
ssh-add ~/.ssh/proj1.id_rsa
proj1.github.com
(exactly the host from the config file).
git clone git@proj1.github.com
.Don't mess up with hosts
Upvotes: 9
Reputation: 24944
I have 2 accounts on github, and here is what I did (on linux
) to make it work.
ssh-keygen
, name them properly, so that make life easier.ssh-add path_to_private_key
~/.ssh/config
Host github-kc
Hostname github.com
User git
IdentityFile ~/.ssh/github_rsa_kc.pub
# LogLevel DEBUG3
Host github-abc
Hostname github.com
User git
IdentityFile ~/.ssh/github_rsa_abc.pub
# LogLevel DEBUG3
Set remote url for repo:
For repo in Host github-kc
:
git remote set-url origin git@github-kc:kuchaguangjie/pygtrans.git
For repo in Host github-abc
:
git remote set-url origin git@github-abc:abcdefg/yyy.git
Options in ~/.ssh/config
:
Host
github-<identify_specific_user>
Host could be any value that could identify a host plus an account,
it don't need to be a real host,
e.g
github-kc
identify one of my account on github for my local
laptop,
When set remote url for a git repo, this is the value to put after git@
, that's how a repo maps to a Host, e.g git remote set-url origin git@github-kc:kuchaguangjie/pygtrans.git
Host
]Hostname
github.com
for github,User
git git
for github,IdentityFile
LogLevel
DEBUG3
gives the most detailed info.Upvotes: 52
Reputation: 2932
In my case none of the solutions above solved my issue, but ssh-agent does. Basically, I did the following:
Generate key pair using ssh-keygen shown below. It will generate a key pair (in this example .\keyfile
and .\keyfile.pub
)
ssh-keygen -t rsa -b 4096 -C "yourname@yourdomain" -f keyfile
Upload keyfile.pub
to the git provider
ps -ef | grep ssh-agent
to see if it is running already)ssh-add .\keyfile
to add credentialsgit clone git@provider:username/project.git
Upvotes: 5
Reputation: 1933
As a complement of @stefano 's answer,
It is better to use command with -f
when generate a new SSH key for another account,
ssh-keygen -t rsa -f ~/.ssh/id_rsa_work -C "your@mail.com"
Since id_rsa_work
file doesn't exist in path ~/.ssh/
, and I create this file manually, and it doesn't work :(
Upvotes: 3
Reputation: 4027
I used,
Host github.com
HostName github.com
IdentityFile ~/.ssh/github_rsa
User abc@gmail.com
It wokred fine.
Use the above setting in your .ssh/config file for different rsa keys for different usernames.
Upvotes: 2
Reputation: 4083
I recently had to do this and had to sift through all these answers and their comments to eventually piece the information together, so I'll put it all here, in one post, for your convenience:
Step 1: ssh keys
Create any keypairs you'll need. In this example I've named me default/original 'id_rsa' (which is the default) and my new one 'id_rsa-work':
ssh-keygen -t rsa -C "stefano@work.com"
Step 2: ssh config
Set up multiple ssh profiles by creating/modifying ~/.ssh/config. Note the slightly differing 'Host' values:
# Default GitHub
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa
# Work GitHub
Host work.github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_work
Step 3: ssh-add
You may or may not have to do this. To check, list identity fingerprints by running:
$ ssh-add -l
2048 1f:1a:b8:69:cd:e3:ee:68:e1:c4:da:d8:96:7c:d0:6f stefano (RSA)
2048 6d:65:b9:3b:ff:9c:5a:54:1c:2f:6a:f7:44:03:84:3f stefano@work.com (RSA)
If your entries aren't there then run:
ssh-add ~/.ssh/id_rsa_work
Step 4: test
To test you've done this all correctly, I suggest the following quick check:
$ ssh -T git@github.com
Hi stefano! You've successfully authenticated, but GitHub does not provide shell access.
$ ssh -T git@work.github.com
Hi stefano! You've successfully authenticated, but GitHub does not provide shell access.
Note that you'll have to change the hostname (github / work.github) depending on what key/identity you'd like to use. But now you should be good to go! :)
Upvotes: 241
Reputation: 93745
Use the IdentityFile
parameter in your ~/.ssh/config
:
Host github.com
HostName github.com
IdentityFile ~/.ssh/github.rsa
User petdance
Upvotes: 21