Old ssh known_hosts entries
If you regularly rebuild Linux servers you will almost certainly come across a message that looks something like the following when you try to login via ssh:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
c0:87:77:8f:e8:5c:26:11:53:4d:7b:1b:7a:04:e9:06.
Please contact your system administrator.
Add correct host key in /home/example/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/example/.ssh/known_hosts:39
ECDSA host key for example has changed and you have requested strict checking.
Host key verification failed.
Quickly removing old entries
You can quickly remove old host entries using ssh-keygen:
ssh-keygen -R "example"
Alternatively I've had the following bash function in my .bashrc
for a little
while now:
ssh-del-knownhost() {
last_cmd="$(history|grep '^ *[0-9]* *ssh '|sed 's/^ *[0-9]* *//'| tail -n 1)"
if [ ! "$last_cmd" ]; then
echo "Unable to find last ssh command!" 1>&2
return 1
fi
if ! $last_cmd 2>&1 | grep -q 'WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!'; then
echo "No conflicting know hosts entry found!" 1>&2
return 2
fi
$last_cmd 2>&1 | \
grep '^Offending .*key in '| \
sed -r 's/^Offending .*key in ([^:]*):([0-9]*).*$/sed -i \2d \1/' | \
bash -x
}
The above function essentially runs through the following steps:
- Check
history
for the last used ssh command. - Run the command to make sure it displays a warning message.
- Extract the path to the
known_hosts
file and the line number of the offending entry. - Use
sed
to remove the offending entry
Running the function looks something like this:
$ ssh-del-knownhost
+ sed -i 39d /home/example/.ssh/known_hosts
Checking new entries
Once you've removed any old entries you should get a message that looks something like this when you try to connect:
$ ssh example
The authenticity of host 'example (127.0.0.1)' can't be established.
ECDSA key fingerprint is c0:87:77:8f:e8:5c:26:11:53:4d:7b:1b:7a:04:e9:06.
Are you sure you want to continue connecting (yes/no)?
If you completely trust your network you can just type yes
and carry on with
what you were doing. If you want to be a little more paranoid you can run the
following command directly on the server and compare the fingerprint before
accepting it.
$ ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub
256 c0:87:77:8f:e8:5c:26:11:53:4d:7b:1b:7a:04:e9:06 (ECDSA)
Note: the file you need to check will depend on how OpenSSH has been configured on the server and which public key encryption algorithm you are using.