How do you manage your SSH host keys?
Posted by Steve on Fri 2 Mar 2007 at 11:28
When connecting to a new OpenSSH server for the first time you'll be prompted to accept its host key - but how do you know if it is valid? How do you manage SSH keys for multiple machines?
The first time you connect to a server you'll see a message similar to this:
steve@steve:~$ ssh localhost The authenticity of host 'localhost (127.0.0.1)' can't be established. RSA key fingerprint is 2d:d3:29:bd:4d:e2:7d:a3:b0:15:96:26:d4:60:13:34. Are you sure you want to continue connecting (yes/no)?
This allows you to test that the key is valid, by showing you the a fingerprint (which is a hash of the full key) and prompting you to confirm its validity.
Once accepted this fingerprint will be stored in the file ~/.ssh/knownhosts either in plain text, or if you're running a recent version of OpenSSH it will be stored in a hashed format. (Set "HashKnownHosts no" if you want to disable this behaviour - either in ~/.ssh/options or /etc/ssh/ssh_config.)
The real question now is how do you know whether the key is valid?
Some organisations store OpenSSH fingerprints online so that you may compare what is presented with what is expected, others assume that 99% of people will merely type "yes" when prompted to accept a key - which is pretty dangerous thing to do.
- Build up a global fingerprint list
In the same way that details are stored in ~/.ssh/known_hosts, once accepted, the OpenSSH client program may be configured to read a system-wide list of keys and hostnames.
By default the Debian packages are configured to look at the file /etc/ssh/ssh_known_hosts if it exists.
If you were to build up a list of fingerprints used within your LAN, using the ssh-keyscan command in this file then all your users would avoid prompts connecting to your internal hosts.
As a simple example you could run something like this:
ssh-keyscan -t rsa,dsa cfmaster.my.flat >> /etc/ssh/ssh_known_hosts ssh-keyscan -t rsa,dsa cfmaster >> /etc/ssh/ssh_known_hosts ssh-keyscan -t rsa,dsa mine.my.flat >> /etc/ssh/ssh_known_hosts ssh-keyscan -t rsa,dsa mine >> /etc/ssh/ssh_known_hosts ssh-keyscan -t rsa,dsa yours.my.flat >> /etc/ssh/ssh_known_hosts ssh-keyscan -t rsa,dsa yours >> /etc/ssh/ssh_known_hosts
(Note the use of both "short" and "long" hostnames here; since the machine names must match exactly what the user typed to connect we add both versions. However the users will still be prompted to accept a key if they connect by IP address.)
- Store fingerprints in DNS
If you're using a recent version of OpenSSH then it can be configured to check fingerprints against records stored in DNS. This is obviously only an option if you're running your own nameserver, but with the correct options you can see something like this:
steve@steve:~$ ssh localhost -o "VerifyHostKeyDNS=yes" yes authenticity of host 'localhost (127.0.0.1)' can't be established. RSA key fingerprint is 2d:d3:29:bd:4d:e2:7d:a3:b0:15:96:26:d4:60:13:34. Matching host key fingerprint found in DNS. Are you sure you want to continue connecting (yes/no)?
Here you've not been told that the key is valid and trusted, but you've been told that does match what the DNS server-admin has inserted. By contrast a missing key would look like this:
RSA key fingerprint is 2d:d3:29:bd:4d:e2:7d:a3:b0:15:96:26:d4:60:13:34. No matching host key fingerprint found in DNS. Are you sure you want to continue connecting (yes/no)?
Adding the keys to DNS in the first place is a little outside the scope of this introduction/question but you can use software such as sshfp to do the job.
Now that the simple introduction is out of the way here come the questions:
- How do you manage your SSH fingerprints?
- Blindly assume that all users will type yes and ignore it?
- Centralised lists?
- DNS records?
- Something else?