6

Im trying to make my .ssh/config support different ssh keys for the same host so that I can commit to bitbucket as either my personal or work user, and other ssh stuff still uses my work user.

My config file looks like this:

Host bitbucket-personal HostName bitbucket.com User git IdentityFile ~/.ssh/personal IdentitiesOnly yes Host * AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/work 

when I ssh bitbucket-personal it is using the ~/.ssh/work key which is not what I'm expecting (see below docs, it should use the first matching IdentityFile). But all the other params are correctly referenced (eg [email protected]). If I remove the Host * section it uses the correct key.

What am I doing wrong? I'm guessing I have missunderstood how the precedence here works.

For each parameter, the first obtained value will be used. The configuration files contain sections separated by “Host” specifications, and that section is only applied for hosts that match one of the patterns given in the specification. The matched host name is the one given on the command line.

Since the first obtained value for each parameter is used, more host-specific declarations should be given near the beginning of the file, and general defaults at the end.

Full verbose trace below:

luke$ ssh -v bitbucket-personal OpenSSH_7.8p1, LibreSSL 2.7.3 debug1: Reading configuration data /Users/luke/.ssh/config debug1: /Users/luke/.ssh/config line 1: Applying options for bitbucket-personal debug1: /Users/luke/.ssh/config line 7: Applying options for * debug1: Reading configuration data /etc/ssh/ssh_config debug1: /etc/ssh/ssh_config line 48: Applying options for * debug1: Connecting to bitbucket.com port 22. debug1: Connection established. debug1: identity file /Users/luke/.ssh/luke type 0 debug1: identity file /Users/luke/.ssh/luke-cert type -1 debug1: identity file /Users/luke/.ssh/luke-cx type 0 debug1: identity file /Users/luke/.ssh/luke-cx-cert type -1 debug1: Local version string SSH-2.0-OpenSSH_7.8 debug1: Remote protocol version 2.0, remote software version conker_1.1.15-49a70a8 app-154 debug1: no match: conker_1.1.15-49a70a8 app-154 debug1: Authenticating to bitbucket.com:22 as 'git' debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug1: kex: algorithm: [email protected] debug1: kex: host key algorithm: ssh-rsa debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none debug1: expecting SSH2_MSG_KEX_ECDH_REPLY debug1: Server host key: ssh-rsa SHA256:qqq debug1: Host 'bitbucket.com' is known and matches the RSA host key. debug1: Found key in /Users/luke/.ssh/known_hosts:52 debug1: rekey after 134217728 blocks debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug1: SSH2_MSG_NEWKEYS received debug1: rekey after 134217728 blocks debug1: SSH2_MSG_SERVICE_ACCEPT received debug1: Authentications that can continue: publickey debug1: Next authentication method: publickey debug1: Offering public key: RSA SHA256:qqqq /Users/luke/.ssh/luke-cx debug1: Server accepts key: pkalg ssh-rsa blen 535 debug1: Authentication succeeded (publickey). Authenticated to bitbucket.com ([18.205.93.3]:22). debug1: channel 0: new [client-session] debug1: Entering interactive session. debug1: pledge: network debug1: Sending environment. debug1: Sending env LANG = en_NZ.UTF-8 PTY allocation request failed on channel 0 debug1: client_input_channel_req: channel 0 rtype exit-status reply 0 logged in as lukemcgregor-x. 
9
  • 1
    Add -v when you run ssh and look at the output for more information. Commented Nov 25, 2018 at 10:59
  • 2
    Agree. Most likely ssh is trying your ~/.ssh/personal key, but somehow it's not working. In this scenario, ssh tries the next match (here, your ~/.ssh/work key). Commented Nov 25, 2018 at 11:21
  • 3
    Your understanding of precedence among directives is right, but note that the IdentityFile directive differs from others in that it can be supplied many times: the keys in matching directives are tried in sequence (see paragraph IdentityFile in man ssh_config). Commented Nov 25, 2018 at 11:55
  • Ive had a bit of a look through the verbose output. I can see it using the ~/.ssh/work key but it never tries the personal one, it jump straight to Offering public key: .../.ssh/work Commented Nov 25, 2018 at 12:27
  • 1
    Please, provide the complete log and try to reproduce the issue with this minimal configuration (I assume you might have more things in there). With this sparse information, it is not possible to answer your question. Commented Nov 25, 2018 at 13:05

2 Answers 2

5

I just came across this same issue recently. The SSH Host config allows for an exclusion, so this would do what you want (use one identity file every except for the bitbucket.com alias)

Host bitbucket-personal HostName bitbucket.com User git IdentityFile ~/.ssh/personal IdentitiesOnly yes Host * !bitbucket-personal AddKeysToAgent yes UseKeychain yes IdentityFile ~/.ssh/work 

The man page for ssh_config (for some version) says that the first value set is used, which seems to imply that the original config should work. But I found that this exclusion was necessary (for ssh on OSX, ssh -V OpenSSH_8.1p1, LibreSSL 2.7.3)

4
  • Thank you! Can confirm this on macOS 12.1 Commented Jan 19, 2022 at 14:10
  • I can't upgrade to Monterrey yet, so I cannot. Monterrey has OpenSSH_8.6 but my GUESS would be it works the same. Why not just try? Commented Jan 19, 2022 at 19:41
  • * I can confirm this answer solves the issue on macOS 12.1! Commented Jan 19, 2022 at 19:55
  • Thanks, but wtf. I find this rather distasteful. Commented May 14, 2022 at 10:02
2

I assume you are using ssh-agent or something like that to cache your decrypted private keys, which might change the order in which the keys are offered. This would be visible in more verbose log level (with multiple -v).

Also the IdentitiesOnly option has a slightly different meaning than you might assume -- it will limit the keys that will be offered to the server, but does not limit it to the one preceding the option. It is mostly used to avoid offering identities in default location loaded automatically (~/.ssh/id_{rsa,dsa,ecdsa,ed25519}).

The IdentitiyFile option is also slightly different than you assume. Is allowed to be specified multiple times (see the manual page) so also the one in Match * section will be used.

If you want to use some key by default and other only for this specific host, move the "default" one to the default location ~/.ssh/id_rsa and remove it from the configuration file. It should solve your problems.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.