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

—> Don’t wanna read just 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

  1. Simply append the code above to ~/.bash_profile (or anything else that makes sense for your Linux distro).
  2. 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:

Preview

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:

Single server

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.