Best system for managing ssh keys?


Solution 1

I use Option 3: One keypair per client machine and it makes the most sense to me. Here are some of the reasons:

  • If a client is compromised then that key (and only that key) needs to be removed from servers.
  • It's flexible enough to decide what I can access from where, without granting blanket access to all servers from all clients.
  • Very convenient. There's only 1 key for ssh-add, no confusion.
  • Easy to set up and administer over Option 4

Option 4 is nice, but is just too much work. Option 3 gets you 98% there with much less hassle.

Solution 2

I use a solution that is a bit more complicated but very versatile as I want to maintain some separation in SSH identity keys used for my home network servers, office servers, consulting client network servers and other various systems I have accounts on.

Now that said I work from Linux workstations almost exclusively so I have a USB key that is setup using LUKS encryption and my X11 window manager along with the HAL daemon detect the LUKS encrypted drive and prompt for the decryption passphrase when it is inserted and attempted to be mounted. By storing this on an encrypted drive the way I do I don't ever store my SSH keys on any workstation.

I then have the following configuration in my ~/.ssh/config file:

Host *
    Protocol 2
    IdentityFile %d/.ssh/keys.d/id_rsa.%l
    IdentityFile %d/.ssh/keys.d/id_dsa.%l
    IdentityFile %d/.ssh/keys.d/%[email protected]%l

The %d is translated to be the user's home directory by OpenSSH and in the ~/.ssh directory I have created keys.d as a symlink to the directory path on the encrypted USB drive when it is properly mounted.

The %l expression is translated to be the local client machines hostname and %u will be translated to the local client's username.

What this configuration does is allow SSH to look for a key using 3 different expressions. For instance if my local client's username was jdoe and my local client machine name were examplehost it would look in the following order until it found a key that both existed and was accepted by the remote server.

/home/jdoe/.ssh/keys.d/[email protected]

You could even use the %r expression to look for a key specific for the remote server username or %h for the remote server hostname just like %u and %l were used.

Update: Now I actually utilize the GnuPG gpg-agent with ssh-agent compatibility to just read and use the authentication key off my OpenPGP v2 smartcard.

Solution 3

I would eliminate both your option 1s (of which I suspect one was supposed to be option 2 ;-) because private keys are sensitive data, and it makes sense to keep them in as few places as possible. I personally would never copy a private key from one computer to another (or even from one file to another on the same computer), except maybe for making backups. Although unlike most encryption keys, if an SSH key gets lost it's not the end of the world (just create a new one, you don't lose any data).

Solution 4

Option 3.

This also allow you to control which servers a client can access. e.g. if client X needs access to servers A and B, but C or D, you copy it's public key to only those hosts.

Solution 5

Option 3 and use something like Puppet to handle the key management.


Related videos on Youtube

Author by


Updated on June 20, 2022


  • slacy
    slacy less than a minute

    I've got several client computers (i.e. laptops, desktops, etc.), and I connect to several server machines that I manage, and I log into them all via SSH. I can imagine several schemes of managing ssh keys that would make sense, and I'm curious about what others do.

    Option 1: One global public/private keypair.

    I would generate one public/private keypair, and put the private key on every client machine, and the public key on every server machine.

    Option 2: One keypair per server machine.

    I would generate one keypair on each server machine, and put each private key on my client machines.

    Option 3: One keypair per client machine.

    Each client machine would have a unique private key, and each server machine would have the public keys for every client machine that I'd like to connect from.

    Option 4: One keypair per client/server pair

    Totally overboard?

    Which of these is best? Are there other options? What criteria to you use for evaluating the right configuration?

  • slacy
    slacy about 13 years
    Yeah, renamed to a proper "Option 2" I like the rule of "never copy a private key." That's a good rule.
  • Andy
    Andy about 13 years
  • diq
    diq about 13 years
    Yes, that's it. Be sure to check out some of the examples on the site. Helps to see what others have already done -- no need to reinvent the wheel.
  • niXar
    niXar about 13 years
    I fail to see the point of Option 4. It serves no purpose whatsoever.
  • slacy
    slacy almost 13 years
    Wow, great solution, thanks! I love the universal config in ~/.ssh/config
  • Jeremy Bouse
    Jeremy Bouse almost 13 years
    It's proven itself quite convenient to keep things separate for work, personal and consulting client network servers... I don't want to mix authentication between them but also want it to be easy for me.
  • balu
    balu over 11 years
    Amazing! I really love this one.
  • Halil Özgür
    Halil Özgür about 9 years
    I assume you are using different USB keys for different client machines. Otherwise what is the point in separate keys if all of them are stored in the same place? In case of a breach you would need do revoke all of them. Unless (and probably) I'm missing something this just seems to complicate things.
  • Jeremy Bouse
    Jeremy Bouse almost 9 years
    @HalilÖzgür, Yes I do consulting and don't always want to use the same key. As the USB key is encrypted and not connected to any computer unless I need it to make a connection there is no concern of the server being breached and the passphrase to decrypt the drive filesystem is sufficiently long enough to make revoking keys simple enough.