320

I built several virtual machines during the last few weeks. The problem is, the .ssh/known_hosts gives me the Man in the middle warning. This happens because another fingerprint is associated with the virtual machine IP.

In the .ssh/known_hosts file, however, I don't find the record related to the IP, only two bizarre, key-like strings and "ssh-rsa".

Does anyone have any ideas about how to remove the old key from known_hosts?

karel
  • 13,706
Adam Matan
  • 8,740

11 Answers11

334

There is an ssh-keygen switch (-R) for this. Use like this:

$ ssh-keygen -R example.com
# Host example.com found: line 109
/home/username/.ssh/known_hosts updated.
Original contents retained as /home/username/.ssh/known_hosts.old

man ssh-keygen reads:

-R hostname

Removes all keys belonging to hostname from a known_hosts file. This option is useful to delete hashed hosts (see the -H option above).

Flimm
  • 10,730
user201564
  • 3,441
232

The simplest solution is:

rm -f .ssh/known_hosts

ssh will recreate the file again, but you lose key checking for other hosts!

Or, you can use:

ssh-keygen -R "hostname"

Or the ssh "man-in-the-middle" message should indicate which line of the known_hosts file has the offending fingerprint. Edit the file, jump to that line and delete it.

TTM
  • 239
Sean Staats
  • 3,049
154
sed -i '6d' ~/.ssh/known_hosts

Will modify the file ~/.ssh/known_hosts:6 , removing the 6th line.

In my opinion, using ssh-keygen -R is a better solution for an openssh power user, while your regular Linux admin would do better to keep his/her sed skills fresh by using the above method.

jmort253
  • 1,406
mikewaters
  • 2,367
51

You need to run the following command to get rid of this problem. Open the terminal and type the following command:

For all examples below just replace the value after -R:

ssh-keygen -R server-name
ssh-keygen -R server.ip.addre.ss
ssh-keygen -R 202.54.1.5
ssh-keygen -R server1.example.com
35

All answers are good, but for real SSH pro we have missing information how to remove ssh signature with (non-standard) port number.

  • Simple SSH host signature remove command:

    ssh-keygen -R example.com
    
  • Complex ssh key remove, e.g. you connect to ssh on non-standard port 222:

    ssh example.com -p 222
    

    and you get warning, and to remove this, you need to use square brackets colon port number:

    ssh-keygen -R [example.com]:222
    

Note, that probably there will be IP record for the same host, so you will need to remove that one also.

Hope this helps for non-standard configuration users.

AntonioK
  • 472
Arunas Bart
  • 1,766
20

The warning will tell you the exact line in the known hosts file.

Here's an example:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The RSA host key for foo-bar.net has changed,
and the key for the corresponding IP address 127.0.0.1
is unchanged. This could either mean that
DNS SPOOFING is happening or the IP address for the host
and its host key have changed at the same time.
Offending key for IP in /home/user/.ssh/known_hosts:6
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

See the /home/user/.ssh/known_hosts:6 part? It specifies the file and line number.

innaM
  • 10,412
10

You can also instruct ssh to not check the known_hosts file using the UserKnownHostsFile and StrictHostKeyChecking flags.

For instance:

ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no user@example.com

For ease of use you can alias this:

alias boldssh='ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'

Now you can just boldssh whenever you are sure you trust the server's certificate.

rouble
  • 804
2

Here is a method using Ex editor:

ex +6d -scwq ~/.ssh/known_hosts

where 6th is your line number mentioned in the warning message. Such as this one:

Offending key for IP in /home/user/.ssh/known_hosts:6 <== LINE NUMBER


In general, it's advised to use ex to edit the files non-interactively, instead of sed, which is more a Stream EDitor and its -i parameter which is a non-standard FreeBSD extension.

kenorb
  • 26,615
0

You can also remove a single line from known hosts with e.g. rmknownhost 111 (111 is the line to remove):

#! /usr/bin/env ruby
line = ARGV[0] || raise("gimme line to remove")
hosts = File.expand_path("~/.ssh/known_hosts")
content = File.readlines(hosts)
removed = content.delete_at line.to_i - 1
puts "Removed:\n#{removed}"
File.open(hosts, 'w'){|f| f.write content * ""}

Save this as rmknownhost in a folder from your PATH.

slhck
  • 235,242
grosser
  • 393
0

The entry for the host name or ip should be in the first column. The warning should also list a line number where the offending key lies.

stimms
  • 908
0

It is a text file. You can easily edit with vi(m) and simply delete the line in question (dd), and save the file (wq). But if there is a specific command to remove a host, that's probably the safest method.