pondělí 25. dubna 2016

Ignore the boring SSH error message - Host identification has changed!

The problem

If you work with virtual machines in clouds, or you run an SSH server in Docker containers, then you've probably met the following error message during making ssh connection:
(I'm connecting through SSH to a docker container)
~$ ssh -p 8822 root@localhost
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
Please contact your system administrator.
Add correct host key in /home/jcacek/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/jcacek/.ssh/known_hosts:107
  remove with:
  ssh-keygen -f "/home/jcacek/.ssh/known_hosts" -R [localhost]:8822
ECDSA host key for [localhost]:8822 has changed and you have requested strict checking.
Host key verification failed.
And as a result the ssh refused to connect to requested server.

The problem is, you are reusing the host/port combination which was already registered in your system and the SSH client tries to keep you on a safe side. It doesn't connect to a server whose public key doesn't match the one registered in your system.

The obvious solution

Yes, I know. You say, the message suggest me a solution. Just to run
ssh-keygen -f "/home/jcacek/.ssh/known_hosts" -R [localhost]:8822
... and everything works correctly. Or doesn't it? Let's try.
~$ ssh -p 8822 root@localhost
The authenticity of host '[localhost]:8822 ([]:8822)' can't be established.
ECDSA key fingerprint is SHA256:smYv5yA0n9/YrBgJMUCk5dYPWGj7bTpU40M9aFBQ72Y.
Are you sure you want to continue connecting (yes/no)?
Oh My Java! I have to write "yes". And No! the "y", "Y", "yep" etc. don't work.
Are you sure you want to continue connecting (yes/no)? y
Please type 'yes' or 'no': Y
Please type 'yes' or 'no': yep
Please type 'yes' or 'no': I give up!
Please type 'yes' or 'no': 
So it's really irritating and it takes time to handle it.

The real solution

So what can we do with it? Just add some more arguments to our ssh command
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -p 8822 root@localhost
By using the UserKnownHostsFile option we said we don't want to use ~/.ssh/known_host file, but rather the one provided as a value of this option. And the /dev/null is always empty (i.e. it can't cause a conflict with the checked server key).

The "no" value in StrictHostKeyChecking option disables the question if the new key can be stored into the provided known hosts file.

To make it simpler, just add an alias into your system. E.g. this is a line in my ~/.bash_aliases file:
alias sshx='ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'


Use this only if you are aware of risks coming from the relaxing SSH security mechanisms.