98

I have a personal account and a company account on Unfuddle. On Unfuddle SSH keys can only be used on a single account, so I need to create a seperate SSH key on my laptop for both accounts. I ran ssh-keygen -t rsa to generate two keys with different names (personal is default name and company is {company}_rsa). The problem now is that it appears that my default key is used everywhere and I can't find out how to specify a key to use in Git for individual repos.

So my question is: How do I specify an SSH key to use on a repo-to-repo basis?

I setup my ssh_config (~/.ssh/config) but it still doesn't seem to work.

config:

Host {personalaccount}.unfuddle.com
     HostName {personalaccount}.unfuddle.com
     User git
     IdentityFile /Users/dave/.ssh/id_rsa

Host {companyaccount}.unfuddle.com
     HostName {companyaccount}.unfuddle.com
     User git
     IdentityFile /Users/dave/.ssh/cage_rsa

My Git repo config file for a repo on my company unfuddle account looks like this:

[remote "origin"]
     url = git@{companyaccount}.unfuddle.com:{companyaccount}/overall.git
     fetch = +refs/heads/*:refs/remotes/origin/*

So I am not sure if there is something wrong with my ssh config or my git config.

| improve this question | | | | |
  • Your ssh config looks right, I'm using a similar configuration. – Paŭlo Ebermann Apr 18 '11 at 15:39
111

If you have an active ssh-agent that has your id_rsa key loaded, then the problem is likely that ssh is offering that key first. Unfuddle probably accepts it for authentication (e.g. in sshd) but rejects it for authorization to access the company repositories (e.g. in whatever internal software they use for authorization, possibly something akin to Gitolite). Perhaps there is a way to add your personal key to the company account (multiple people are not sharing the same corp_rsa public and private key files, are they?).


The IdentitiesOnly .ssh/config configuration keyword can be used to limit the keys that ssh offers to the remote sshd to just those specified via IdentityFile keywords (i.e. it will refuse to use any additional keys that happen to be loaded into an active ssh-agent).

Try these .ssh/config sections:

Host {personalaccount}.unfuddle.com
     IdentityFile ~/.ssh/id_rsa
     IdentitiesOnly yes

Host {companyaccount}.unfuddle.com
     IdentityFile ~/.ssh/{companyaccount}_rsa
     IdentitiesOnly yes

Then, use Git URLs like these:

git@{personalaccount}.unfuddle.com:{personalaccount}/my-stuff.git
git@{companyaccount}.unfuddle.com:{companyaccount}/their-stuff.git

If you want to take full advantage of the .ssh/config mechanism, you can supply your own custom hostname and change the default user name:

Host uf-mine
     HostName {personalaccount}.unfuddle.com
     User git
     IdentityFile ~/.ssh/id_rsa
     IdentitiesOnly yes

Host uf-comp
     HostName {companyaccount}.unfuddle.com
     User git
     IdentityFile ~/.ssh/{companyaccount}_rsa
     IdentitiesOnly yes

Then, use Git URLs like these:

uf-mine:{personalaccount}/my-stuff.git
uf-comp:{companyaccount}/their-stuff.git
| improve this answer | | | | |
  • 7
    If you have multiple accounts on the same Unfuddle subdomain (with different SSH keys), you will need to use the second method. – leolobato Dec 20 '11 at 18:25
  • IdentitiesOnly was essential for me in my gitolite setup, thanks! – Koen. Jan 12 '13 at 18:00
  • 1
    Awesome this fixes the issue that all my keys get sent to github. However, on OS X I have to type in my passphrase everytime. Is there a way to say only use key specified in config but continue to use ssh agent? – Drew Mar 18 '13 at 15:50
  • 1
    @Drew: If the key is already loaded into the agent, then the command should still draw it from the agent. Are you sure your key is pre-loaded? Check with ssh-add -l before you use your Git host alias. Also the public key file needs to be present so that ssh can recognize the key that ssh-agent is storing. You can regenerate a lost .pub file with a command like ssh-keygen -f blah -y > blah.pub. – Chris Johnsen Mar 18 '13 at 19:09
  • 1
    Using IdentityFile essentially disables ssh-agent. So you would have to type your passwords and wouldn't be able to use ssh forwarding. – Vanuan Feb 5 '19 at 3:23
4

IdentityFile and IdentitiesOnly work well. What bothers me is having to remember to use different host names to connect to, and the fact that the forwarded agent connection still holds all keys, meaning that if the remote host is compromised, they can use any of my identities while I'm in.

I've recently started using:

https://github.com/ccontavalli/ssh-ident

it's a wrapper around ssh, it:

  • keeps an entirely separate agent for each identity you define.
  • automatically shares agents across login sessions, nothing to do in your .bashrc.
  • loads the agent and the corresponding keys on demand the first time you need them.
  • determines which agent to use either based on ssh command line (hostname & such) or your current working directory. This is particularly handy as I tend to work from different paths depending on what I am doing.
| improve this answer | | | | |
3

man ssh_config

Something like

Host personal_repo
  User personal
  IdentityFile .ssh/personal_rsa

Host company_repo
  User company
  IdentityFile .ssh/company_rsa

And use personal_repo as host in your git repo.

| improve this answer | | | | |
  • Tass, could you review my changes made above? I added my ssh_config and my git config. – Dave Long Apr 18 '11 at 14:55
  • Host is just an identifier - no need for full domain name. That probably creates some hidden bugs. If you change that, you don't need to spell the full name in your git config. – Tass Apr 18 '11 at 15:18
  • for gitorious, user = git and host gitorious.org: e.g. git@gitorious.org:~revelut/qt/bruce-sandbox-qt.git How do you match in your Host a part of the url ? (typically ~revelut for me) – Bruce Apr 18 '11 at 15:53
  • @Tass so if I give the name company_unfuddle to the SSH config should my URL be git@company_unfuddle:{company}/overall.git? @Bruce - I am not sure what you are asking. Could you expand a little more? – Dave Long Apr 18 '11 at 18:58
1

Here's a proper way if you want to use ssh agent:

# Create public keys to make sure they exist
# this is a must if you use ssh agent forwarding
# or want to use ssh-agent at all
ssh-add -L | grep personal > ~/.ssh/personal_identity.pub
ssh-add -L | grep company > ~/.ssh/company_identity.pub


# Add to ~/.ssh/config
Host {personalaccount}.unfuddle.com
  IdentityFile ~/.ssh/personal_identity.pub

Host {companyaccount}.unfuddle.com
  IdentityFile ~/.ssh/company_identity.pub

Explanation: if you have private key in your ~/.ssh directory, ssh-agent won't be used. So we create public key under another name, so that ssh is forced to use ssh-agent. This also helps if you don't have access to private keys (e.g. ssh agent forwarding)

| improve this answer | | | | |
  • this might be ssh-add -L, not ssh-agent. – ives Aug 1 '19 at 4:02
  • @ives thanks, fixed – Vanuan Aug 15 '19 at 0:45
  • Thank you for this tip. I was using ssh-agent forwarding and all the other answers are not relevant when the private key is not on the computer you are running git push on. – ender.qa Mar 30 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.