UNIX SSH Key Management Approaches

  • Service Provider

    SSH Keys are a bit of a foreign concept to admins coming from the Windows world, they are almost exclusively used in SSH transactions and, to some limited degree, SSL web transactions but are rarely seen in the latter. Because of this, SSH Keys can be a bit daunting and common usage may not be known.

    SSH Keys are meant to represent either a replacement for passwords (allowing for rapid, passwordless logins) or for simple two factor authentication where the key itself requires a password in order to use - which provides for the something you have and the something you know requirements of 2FA.

    SSH Keys allow for additional security by specifying the host identifier of the key allowing the use of a key to be locked down to a specific host or host group limiting risk should a key be exposed. SSH Keys are a standard part of a UNIX security process and are very flexible and useful.

    Two Key Topics (pun intended) when thinking about getting started with SSH Keys is how they will be generated and how they will be distributed. First, a quick overview.

    The key pair concept is one of a public/private pair. When you generate an SSH Key pair you generate a private key (to be kept private, for yourself) and a public key that is literally designed to be published publicly and does not need to be protected in any way. A key pair is designed to identify not only the user of the private key, but also the host from which the key was generated so that we can lock down the device and the user. A private key can be shared to multiple devices and host identification removed. There are cases for this usage but generally it is avoided as it lowers the security of the key.

    Once a key pair is generated, the public key can be distributed to every system to which the user in question should be granted access. Public keys are truly public and can be put onto a public website or other published location for anyone to grab and use when they want to grant the key holder access to a system.

    Private keys are easy, we keep them locked away on our client machine, generally in the spot where they are originally generated. We only deal with them when we replace them.

    Public keys, however, need to be distributed to many systems. How do we do that?

    Five Approaches to Public Key Distribution

    There are many potential methods but five are the most common and basic.

    Manual: As pedestrian and fundamental as it sounds, manual key distribution is feasible in small environments. It is actually quite common to find key management passed to individual users to handle themselves (copying their keys onto every machine that they want passwordless access to) or admins doing this on their behalf where passwords do not also exist on the machines. This gets to be very messy, very quickly.

    Centrally Published: This method is essentially manual but with a maintained central key repository to make key acquisition easier. The best approach is likely a wiki, which can be public, where the users' public keys are stored. This step greatly improves the key distribution process, especially in cases where keys are handed out machine by machine rather than in bulk. Also standard to use would be a repository system like Subversion, GIT or Mercurial.

    DNSSEC: This is a new method that is not yet widely available or supported (or tested.) This method publishes public keys to a DNS server which is used to provide the keys to servers as needed. This is looking to be an extremely popular method for modern cloud computing, elastic environments and highly distributed environments where a common backend is not available.

    Script: It is increasingly common to use scripts to place keys onto each server or workstation that will be accessed. In some cases these would be simple BASH or Shell scripts, they could be run locally or remotely and may contain the keys inside the script or pull them from a central repository such as Subversion, Mercurial, GIT or just a web page. More recently DevOps frameworks like Chef, Puppet and Ansible are becoming the common way to script this in a more standardized way.

    Shared Home Directories: This is the traditional and one of the simplest methods of broad key distribution when servers or workstations exist on a shared LAN. It is very common in UNIX environments to have shared home directories as this is very storage efficient and flexible. The standard approach here is to use NFS to mount home directories providing users with common files no matter where they log in. Keys are normally stored in home directories and because of this a one time key setup to the shared storage creates automatic key distribution to all machines in the environment instantly. Very simple and effective and plays well into other strategies.

  • Service Provider

    I should note, as well, that it is common for companies using VM templates in their virtualization or cloud platform to include a base set of users, groups, permissions and potentially keys in the VM template. This is less a management strategy and more of a bootstrapping strategy - enough users and keys to get started, but generally additional management would be desired or else the addition or removal of a single user would require the updating of the template and the redeployment of the entire server and/or workstation fleet to enact the change.

  • I'd like to quickly point out that I've seen many "tutorials" showing how to add keys by using scp and copying the key to the ~/.ssh folder on the remote host, then using chmod to make it read only. This to me seems akin to the "tutorials" where they have you add sudo users by editing the /etc/sudoers file.

    If you need to do a one off ssh key to a remote server, you can use ssh-copy-id -i [email protected] and it will do all of the work for you.