77

I have two public keys, one for some servers and one for others. How do I specify which key to use when connecting to a server?

rid
  • 981

4 Answers4

86

Assuming you're on a Unix/Linux environment, you can create or edit the file ~/.ssh/config.

That config file allows you to establish the parameters to use for each host; so, for example:

Host host1
  HostName <hostname_or_ip>
  IdentityFile ~/.ssh/identity_file1

Host Host2
  HostName <hostname_or_ip2>
  User differentusername
  IdentityFile ~/.ssh/identity_file2

Note that host1 and host2 can also be not hostnames, but rather labels to identify a server.

Now you can log onto the to hosts with:

ssh host1
ssh host2
Abdull
  • 207
  • 58
    You can also use -i <keyfile>, but I'd definitely recommend the config file method in the general case. – womble Jul 30 '11 at 08:43
  • I tried this but I keep getting prompted of the passphrase for my key. Even when I enter the passphrase correctly, the ssh login doesn't work. I tried using a blank passphrase too – Hamman Samuel Feb 29 '16 at 20:27
  • I had to do ssh differentusername@host2 for a proper login, but otherwise this worked wonderfully, thank you! – agrippa Jun 21 '19 at 21:57
2

I explicitly mention the key during clone or pull or any git operations.

First you need to create key files with ssh-keygen command, then copy the .pub file to the host.

And during connecting, use the file without any extension.

Simple one liner

git -c core.sshCommand="ssh -i ~/.ssh/id1" pull
git -c core.sshCommand="ssh -i ~/.ssh/id1" clone <github>.git
2

The questioner specifically asked about how they would connect to two different groups of servers using two different public keys, yet the answers see at the time of writing this appear to me to be related to if the user had two different private keys.

I am going to assume a use case here whereby a user may have generated a single private key, and had it's corresponding public key signed twice by two different certificate authorities. Thus they need to use one of the signed public keys for one of the groups of servers, and the other for the other group of servers. Alternatively it may be one certificate authority, but the public keys are signed differently, perhaps for two specifically different users etc. Either way, there is just one private key for which the user needs to use one of two different corresponding public keys in order to connect to the remote servers. I am also assuming we are only dealing with OpenSSH keys rather than using x509 certificate files which may be slightly different (haven't tested).

In such a scenario, assuming that we cannot rely on any of the default behaviours of SSH, so that both the private key and the public key need to be manually specified, then we can specify both when connecting like so:

ssh -i /path/to/private/key -i /path/to/public/key username@hostname

When reading the manual for SSH, it looks like the -i flag for identity file is intended for the private key and not the public key as shown below:

enter image description here

...but this worked when I was testing it out in a local environment using Ubuntu 20.04 and connecting to a Debian 12 server.

However, when I read my local man pages for SSH, I can also see the option to specify CertificateFile, which feels more appropriate and I found works as well.

enter image description here

This can be done like so:

ssh \
  -i /path/to/private/key \
  -o CertificateFile=/path/to/public/key \
  username@hostname

SSH Config File

As others have pointed out, it is generally more convenient to just specify the details in the SSH config file. Luckily I found that during testing, I could use both the IdentityFile and CertificateFile clauses here too.

E.g both of the following would work (assuming you changed the values as appropriate to your setup)

Host my-server-alias
    User myUsername
    Port 22
    Hostname 192.168.0.1
    IdentityFile /path/to/private/key
    CertificateFile /path/to/signed/public/key
Host my-server-alias
    User myUsername
    Port 22
    Hostname 192.168.0.1
    IdentityFile /path/to/private/key
    IdentityFile /path/to/signed/public/key
Programster
  • 515
  • 1
  • 13
  • 23
-2

On Fedora 27, you can put the private/public keys under ~/.ssh/ and then when you ssh to a host, both of them will be tried automatically.

zhigang
  • 117