There comes a time in any Linux systems administrator where he faces an issue while connecting to a new server if an old/known name. Although it is not a difficult problem to solve it can be a PITA to manually edit your know_hosts
file each time it happens, therefore having a script ready to do it for you can be very handy.
The problem
—> TL/DR => take me to the code!
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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 the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
5c:9b:16:56:a6:cd:11:10:3a:cd:1b:a2:91:cd:e5:1c.
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending key in /home/user/.ssh/known_hosts:1
RSA host key for server.example.com has changed and you have requested strict checking.
Host key verification failed.
Who hasn’t faced an issue like this? I personally end up facing this situation a lot in the past days when I was testing some AMIs before putting them in production. For various reasons, it was just easier for me to use the same hostname in all test instances that I brought up. In face of that problem, it put on my shell script hat and created a function to help me solve this issue, the result is a simple function that you can set up as an alias function in your terminal that will help you remove hosts from you know_hosts
file faster.
The code
The code is very simple and it basically uses grep
and mv
to get the job done:
remove_known_hosts(){
known_hosts=~/.ssh/known_hosts
lines_count=$(grep -c $1 ${known_hosts})
if [ "$lines_count" -gt 0 ]; then
echo "Found ${lines_count} host(s):"
echo ""
grep $1 ${known_hosts}
echo ""
echo -n "Do you want to remove these hosts? [Y/n] "
read reply
if [ "$reply" == "Y" ]; then
grep -F -v $1 ${known_hosts} > ${known_hosts}.tmp && mv ${known_hosts}.tmp ${known_hosts}
echo "Those hosts were removed"
fi
else
echo "No hosts matching ${1} were found."
fi
}
Installation
- Simply append the code above to
~/.bash_profile
(or anything else that makes sense for your Linux distro). - Run
source ~/.bash_profile
Usage
You simply need to run the function plus a server name, IP or pattern to look for. E.g. remove_known_hosts server
Since it uses grep
for matching it is possible to delete a series of entries from your know_hosts
file. For example, if you run remove_known_hosts srv
that would give you something like that:
From there you can double-check the server names and remove all entries by answering Y
to the question.
Instead, if you want to remove just a single entry you should use full name/IP of the server to match it accordingly:
Conslusion
I already saved several seconds of my day by simply adding this script to my .bash_profile
. Let me know if it’s helpful for you too. Also, any improvements are welcome as long as they just use bash scripting and standard Linux tools.