Do you have scripts that do remote procedures over ssh? Do host key checks occasionally cause them to break? This entry will show you how to avoid that mess and keep your scripts running smoothly.
BACKGROUND
ssh protocol is designed to verify the host key against a local file to ensure the integrity of the remote server. By default, the user is prompted to accept a new key or warned when the host key changes (like after a server upgrade). This is a nice defense against man-in-the-middle attacks, but it plays havoc on scripts. If a prompt occurs, your script stops and waits for input.
FIX
There are two ways you can avoid this problem. You can pass parameters to ssh or you can change the system setting in ssh_config. If you want to turn off host key checks for scripting, then we recommend using command line parameters. You only type them once when you write your script and they only affect that instance of ssh.
By default, StrictHostKeyChecking is set to ‘ask.’ That’s why you’re prompted to accept a key. In order to avoid the prompt, you can change that to ‘no.’ When it’s set to ‘no’ the key is stored with no questions asked.
Unfortunatley, that’s not as clean as it seems. If the host signature changes due to an upgrade, then ssh stores that key, too. Since you have two, it starts throwing warnings such as this:
key_read: uudecode AAAAAAAB3NzaC1yc2EAAAABIwAAAQEAzh1G5NiiEfawhBhly VLR92Q/+iXZ3Bs56RBLZtso/lEFk9TYZuS+Qp+tKOIv1j5HpuwsoIAZt6A1fJfCHfN3 KYtuWNbdMywuoOUb5Z9S0c/3jyeesy2eTy+ZZjgb0uPdU8cCKg029NF9gQr5tbDlrj+ vW6QvvWJ0KVJFJPWg6u3/Qt/N/xlPXziyHv4HKuzMDoRLQ5ltiC8zk3ZefeRK7ZZKtp qSneTsHZt7alOGOsKTrPL5PA50QwBiNJFbvrnmJs2Xjk3x6MunXFuRSZCEsGboQWDie whcOFxDlkYfWjHNbShPYBY3xuq/MnsL8QHUx9AT75wpl2U0/KFbXsMAKw== failed key_read: uudecode AAAAAAAB3NzaC1yc2EAAAABIwAAAQEAzh1G5NiiEfawhBhly VLR92Q/+iXZ3Bs56RBLZtso/lEFk9TYZuS+Qp+tKOIv1j5HpuwsoIAZt6A1fJfCHfN3 KYtuWNbdMywuoOUb5Z9S0c/3jyeesy2eTy+ZZjgb0uPdU8cCKg029NF9gQr5tbDlrj+ vW6QvvWJ0KVJFJPWg6u3/Qt/N/xlPXziyHv4HKuzMDoRLQ5ltiC8zk3ZefeRK7ZZKtp qSneTsHZt7alOGOsKTrPL5PA50QwBiNJFbvrnmJs2Xjk3x6MunXFuRSZCEsGboQWDie whcOFxDlkYfWjHNbShPYBY3xuq/MnsL8QHUx9AT75wpl2U0/KFbXsMAKw== failed Last login: Fri Jul 13 11:09:36 2012 from jdfulmer-lt.joedog.org RedHat 5Server - LinuxCOE 4.2 Fri May 11 09:48:33 EDT 2012
We can avoid this mess with another setting. Instead of saving host key entries to known_hosts, we can bury them in /dev/null. We can change the file location with the UserKnownHostsFile parameter. If we change it to /dev/null there are no entries for ssh to read. And when it writes a new entry, well it goes to /dev/null
IMPLEMENTATION
There are two ways we can implement this. One is at the script level and the other is at the system level. If we want to continue to prompt for host key checks, then we can add the configuration to our script. This can be done with OpenSSH’s -o option. Here’s an example in which we run the hostname command on a remote server:
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null user@host /usr/bin/hostname -s
To set this configuration system-wide, place these entries in ssh_config:
StrictHostKeyChecking no UserKnownHostsFile /dev/null LogLevel QUIET
NOTE: This configuration applies only to OUTBOUND ssh connections. This does not affect your system’s inbound ssh traffic.
UPDATE: I added LogLevel QUIET to the ssh_config above. This is the same as running ssh with a “-q”. This suppresses all warning messages which may wreak havoc on your scripts.