54

I've set up two GitHub accounts, but I can't get ssh keys to work correctly. I've tried various configs.


Host github_username1
    HostName github.com
    IdentityFile ~/.ssh/rsa_1
    User username1
Host github_username2
    HostName github.com
    IdentityFile ~/.ssh/rsa_2
    User username2

git push:

Permission denied (publickey).
fatal: The remote end hung up unexpectedly

Works for username1:

Host github.com
    HostName github.com
    IdentityFile ~/.ssh/rsa_1
    User username1
Host github.com
    HostName github.com
    IdentityFile ~/.ssh/rsa_2
    User username2

git push at username2's repo:

ERROR: Permission to username2/repo.git denied to username1.
fatal: The remote end hung up unexpectedly

I've also tried git push with both IdentityFile and User settings under same Host. The output is the same as with the last config.

I think git automatically searches for Host "github.com" because the remote is such. It is said that Host can be anything you want (https://stackoverflow.com/a/3828682). Is there any way to change what Host from ssh config should specific repo use?

It would be ideal if I could solve this just from ~/.ssh/config.

usr
  • 755
  • 2
  • 6
  • 8

1 Answers1

75

Yes, only the section headers (the Host or Match lines) are searched for – everything else is only applied as a setting. In other words, if you connect to foo@bar.com, OpenSSH will only look for a section titled Host bar.com.

So if you have Host github_username2, you must use this exact same "hostname" in your Git remotes as well. OpenSSH will not find this section if you use git@github.com.

However, that is not what causes authentication failures. When connecting to GitHub via SSH, you must use git as your username – the server will recognize you based on the key alone. (In other words, the "git@" in "git@github.com" is actually the SSH username that GitHub uses – not some kind of URI scheme.)

So a correct SSH configuration would be:

Host github_username1
    Hostname github.com
    User git
    IdentityFile ~/.ssh/rsa_1
    IdentitiesOnly yes

Host github_username2
    Hostname github.com
    User git
    IdentityFile ~/.ssh/rsa_2
    IdentitiesOnly yes

with this Git configuration:

[remote "origin"]
    url = github_username1:username2/repo.git

(It doesn't matter where you specify the SSH username – you can have git@ in the URL, or you can have User git in .ssh/config, or both.)


Alternative Git configuration to automatically switch accounts depending on repo path:

  1. Create a file ~/.config/git/config.user1 containing:

    [url "github_username1:"]
        insteadOf = git@github.com:
    
  2. Create a config.user2 file that's the same except with "github_username2".

  3. In your main ~/.config/git/config file, tell Git to "include" one of the two files depending on which directory you're at:

    [includeIf "gitdir:~/projects/"]
        path = ~/.config/git/config.user1
    
    [includeIf "gitdir:~/src/work/"]
        path = ~/.config/git/config.user2
    
  4. Now, whenever you're at ~/src/work/, cloning anything from git@github.com:[etc] will automatically rewrite the URL to github_username2:[etc].

u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • 6
    In some cases you might need to add `IdentitiesOnly=yes` on each `host` section to make sure ssh will only pick the chosen identity file and don't default / try anything else.. – TCB13 Dec 26 '15 at 01:19
  • 1
    This solution is not foolproof, when you have submodules you are stuck with a broken .gitconfig – mars Mar 22 '21 at 10:18
  • Your local .git/config can use `[url ...] insteadOf = ...` to automagically substitute the real submodule URLs with your customized ones. – u1686_grawity Mar 22 '21 at 10:26
  • 2
    @TCB13 your hint about `IdentitiesOnly` just saved me after I couldn't figure out why my config hasn't been working. Thanks a lot! – Bunkerbewohner Sep 23 '22 at 19:23
  • 1
    `IdentitiesOnly` was also required for me. Should be added to the main answer! – Dziad Borowy Oct 05 '22 at 11:45
  • An alternative to this answer is to use [SSH config matchers](https://unix.stackexchange.com/questions/691210/matching-both-user-and-host-simultaneously-in-ssh-config), which allows matching a unique host + user combination. – holocronweaver Oct 25 '22 at 02:52