66

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
  • 875

1 Answers1

88

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].

grawity
  • 501,077