512

I'm trying to setup password-less SSH on an Ubuntu server with ssh-copy-id myuser@myserver, but I'm getting the error:

Warning: the ECDSA host key for 'myserver' differs from the key for the IP address '192.168.1.123'

What's causing this, and how do I fix it? I tried deleting the .ssh directory on the remote machine, and running ssh-keygen -R "myserver" locally, but this doesn't resolve the error.

Owen Blacker
  • 146
  • 2
  • 12
Cerin
  • 8,746
  • 16
  • 54
  • 65
  • in my case, I change the server(ip) bind with the domain, then the `The ECDSA host key for server has changed`. My way is remove the related cache string about domain in `~/.ssh/known_hosts`. Then the ssh works. – Ninja Jul 11 '17 at 03:59
  • I backed up the .ssh/known_hosts and let it to be recreated. – Antonio Petricca Apr 07 '21 at 07:13

14 Answers14

749

Remove the cached key for 192.168.1.123 on the local machine:

ssh-keygen -R 192.168.1.123
u1686_grawity
  • 426,297
  • 64
  • 894
  • 966
  • 15
    Didn't work for me on newly install Debian server at work when SSHing in from home. Also, answer is pretty terse. – Krista K Jan 16 '14 at 07:29
  • /home/wf/.ssh/known_hosts updated. Original contents retained as /home/wf/.ssh/known_hosts.old "Warning: Permanently added the ECDSA host key for IP address 'x.x.x.x' to the list of known hosts." is displayed. and then it seems to work – Wolfgang Fahl Jul 25 '14 at 06:55
  • 30
    You can update key instead of removing it. Use `ssh-keyscan -t ecdsa my.server.domain >> ~/.ssh/known_hosts` after that you don't need to verificate new key at first connecting to host. – Alex Jul 13 '16 at 10:01
  • 5
    For whom don't succeed to make it work: I've had registered multiples occurrences of the same IP : 1/ the said IP address (xx.xx.xx.xx), domain (tomsihap.fr), provider's given vps server address (vpsxxx.ovh.net). ssh-keygen -R for each of these did the work. – tomsihap Dec 17 '16 at 23:02
  • Worked for me, but the confusion might be from which host should this command be run? The answer is from the one that exhibited the error. The second question and answer are more obvious, but just in case: which address to pass to ssh-keygen -R? The address that figures in the error statement. – Russ Bateman Oct 27 '17 at 00:27
  • 4
    In case this doesn't cut it, and `ssh 192.168.1.123` displays the warning but doesn't show the offending line number in known_hosts, you can do `ssh -v 192.168.1.123 2>&1 | grep known`, then you can e.g. `sed -i.orig 42d ~/.ssh/known_hosts` to delete line 42 (or whatever it was) – unhammer Mar 11 '18 at 13:19
  • Thanks, It worked for me! In my case I did a Rebuild in my Droplet at DigitalOcean. – rochasdv May 16 '18 at 16:38
  • Take my upvote you wonderful human being. – Danny Bullis Mar 10 '20 at 23:04
  • Thanks! Your answer saved me hours of poking around! – Leo Skhrnkv Apr 23 '20 at 13:11
  • 2
    sometimes you have to specify the port ssh-keygen -R [192.168.1.123]:222 – Hernán Eche Jul 15 '20 at 12:43
  • You made my day! – FastSolutions Nov 09 '20 at 07:25
  • Thank you @Alex this should be the awad wining answer – Shahid Karimi Aug 06 '21 at 08:29
  • @Alex That leaves the line with the differing key in file. Is that desired? By the way, you might want to use `-H` to hash the domain name in the file. – jarno Nov 06 '22 at 12:42
  • 1
    Just to add some context to this answer, it's possible you have to run this command a few times. For me, I had two "offending" keys. I ran the command in this answer for both IP addresses and now everything is as expected. I believe you can also manually edit the file as mentioned in another answer, but multiple runs of this command work well too – ewhiting Apr 17 '23 at 04:09
152

In my case ssh-keygen -R ... didn't fix the warning. I had extra information like this:

Offending key for IP in /home/myuser/.ssh/known_hosts:8
Matching host key in /home/myuser/.ssh/known_hosts:24

I simply manually edited ~/.ssh/known_hosts and deleted line 8 (the "offending key"). I tried reconnecting, the host was permanently added, and everything was fine after that!

aardvarkk
  • 2,119
  • 5
  • 17
  • 23
  • 7
    Works like a charm. Can fix this in one line with `sed -e '8d' /home/myuser/.ssh/known_hosts`, replacing the line number `8` and the filename with those displayed on your system. – Alex P. Miller Jun 22 '17 at 14:57
  • My issue with this approach was that it's a bit confusing if the `known_hosts:8` refers to a zero-indexed value or not. Good to know that it's a 1:1 mapping... – Daniel F Feb 18 '19 at 16:14
  • 3
    I noticed this happens if you use a non-standard port like 2022. In that case, you need to do `ssh-keygen -R [hostname]:2022` – Alexander Malfait Jul 10 '19 at 14:55
  • If I delete `~/.ssh/known_hosts`, I get the message that the authenticity can't be established and "Are you sure you want to continue connecting". Answering "yes" tries and fails to connect. If I try to connect a 2nd time, I get the same ECDSA host key error I started with. – Aaron Franke Oct 10 '19 at 20:12
  • I changed ports for ssh on a router to reduce load... this fixes the message. – Ray Foss Aug 28 '20 at 19:46
  • worked for me, thanks! – keypoint Apr 26 '23 at 23:05
26

I do lots of ssh-ing around between my LAN computers and my two webhosting accounts, so I've sorted out all kinds of odds and ends with SSH, including authentication problems using ssh -v to see where and what went wrong.

Having just resolved this issue and not being happy with the answers, I wanted to really know "why" myself...

The trigger for my case is: installed new server OS at work and upon installing openssh-server package, a new set of host keys were generated on work's server. Previously, all of my server OSs were Ubuntu and this time it changed to Debian (and I suspect there is a nuanced difference in permissions).

When all OSs were Ubuntu and I reinstall a server's OS, upon the first SSH in to it, I get this kind of warning, which I prefer over the silent warning above!

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    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
06:ea:f1:f8:db:75:5c:0c:af:15:d7:99:2d:ef:08:2a.
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:4
RSA host key for domain.com has changed and you have requested strict checking.
Host key verification failed.

Then I open up ~/.ssh/known_hosts on the computer initiating the ssh, delete that line, reconnect and this happens:

chris@home ~ $ ssh work
The authenticity of host '[work]:11122 ([99.85.243.208]:11122)' can't be established.
ECDSA key fingerprint is 56:6d:13:be:fe:a0:29:ca:53:da:23:d6:1d:36:dd:c5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[work]:11122 ([99.85.243.208]:11122)' (ECDSA) to the list of known hosts.
Linux rock 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64

That bit about :11122 is the port number I route SSH from on the firewall

I checked backups from a former Ubuntu server and diff'd against my new Debian install:

Ubuntu:                                            Debian:
# Package generated configuration file             # Package generated configuration file
# See the sshd(8) manpage for details              # See the sshd_config(5) manpage for details

# What ports, IPs and protocols we listen for      # What ports, IPs and protocols we listen for
Port 22                                            Port 22
# Use these options to restrict which interface    # Use these options to restrict which interfaces
#ListenAddress ::                                  #ListenAddress ::
#ListenAddress 0.0.0.0                             #ListenAddress 0.0.0.0
Protocol 2                                         Protocol 2
# HostKeys for protocol version 2                  # HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key                  HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key                  HostKey /etc/ssh/ssh_host_dsa_key
------------------------------------------------   HostKey /etc/ssh/ssh_host_ecdsa_key
#Privilege Separation is turned on for security    #Privilege Separation is turned on for security
UsePrivilegeSeparation yes                         UsePrivilegeSeparation yes

So yes, likely, the host started using ecdsa keys recently, which based upon Ubuntu's changes lately, I would blame on an update. Ubuntu's shift away from the rock-solid linux OS I counted on is why I installed Debian this time around.

I read a security.SE q/a on ecdsa and have already removed that line from sshd_config my new Debian server. (and ran service ssh restart)

Krista K
  • 1,025
  • 2
  • 12
  • 21
  • 3
    +1 for the nice side-by-side comparison block. Could you add a URL clariying "Ubuntu's shift away from the rock-solid linux OS" means? – bgoodr Feb 09 '14 at 16:43
  • @bgoodr it's my opinion & solely based upon setting up my own RAID fileserver several times over the past few years. :/ Crap for answer, but start googling `ubuntu debian server` and you'll see what I mean. – Krista K Feb 10 '14 at 07:00
  • 2
    @ChrisK You, sir, are a boss. Thanks for the detailed, yet concise, answer. – sargas Aug 12 '16 at 15:46
16

I added the following lines to my ~/.ssh/config, thus disabling strict host checking for all .local addresses. (with DHCP address allocation, ip addresses of my local machines are always changing)

host *.local
    StrictHostKeyChecking no

You still get the warning, though, which is fine by me.

KimSJ
  • 261
  • 2
  • 2
  • 3
    Please note that **ONLY** DO THIS on things that you can closely monitor since this is essentialy says "I don't care who they are, so just cut the cr-p out and just connect me". Do not do this on production servers or machine that are connected to the internet. – Chris Qiang Dec 03 '20 at 04:20
  • 11
    For this use case, it isn't necessary to disable `StrictHostKeyChecking`. You can disable `CheckHostIP`, which will verify the key for the host but not for the IP address it resolves to. – Esme Povirk Dec 23 '20 at 17:20
  • @EsmePovirk `CheckHostIP` seems to be disabled by default in latest Ubuntu releases (that is 22.04 and later). – jarno Nov 06 '22 at 12:00
  • @EsmePovirk SSH v8.5 changed the default https://serverfault.com/a/1109184/333603 – jarno Nov 06 '22 at 13:00
11

The prompt occurs every time because the IP addresses change all the time when using dynamic addressing. Try to use static IP so you only have to add the key only once.

Gaurav Joseph
  • 1,725
  • 13
  • 24
  • 1
    Good point, did I miss where someone mentioned dynamic ips? – Krista K Jan 16 '14 at 20:13
  • Any suggestions on how to deal with the problem when you have no control over what the IP addresses are? – Michael Apr 01 '20 at 19:16
  • @Michael, what are we working with here? Do you have access to the router page? Is there a server which you can control (to act as a rendezvous point)? You can also consider about multicast DNS (mdns: Apple Bonjour / Avahi). Make a script that changes the IP address in the `known_hosts` file. – Gaurav Joseph Apr 02 '20 at 09:15
  • In a corporate environment using DHCP one often doesn't have permissions to fiddle with IP address assignments. The script idea is interesting, but I think you would need to change the known_hosts file on another machine, right? Sometimes trust only flows one direction (i.e. B trusts A to log in but not vice versa) which might make this more tricky. – Michael Apr 02 '20 at 22:46
  • Nope, only your machine needs to change the IP of the host (ssh server) in your local known_hosts file, since the keys remain the same. If you need it to be done on both the machines, just install the script in both of them. Contact me if you need more help creating a solution. – Gaurav Joseph Apr 02 '20 at 23:26
8

ssh-keygen -f "/root/.ssh/known_hosts" -R 192.168.1.123

This should replace the existing keys under known_hosts.old and create a new one. This solution worked for me in the same scenario

Jignesh Rawal
  • 196
  • 1
  • 2
2

At my side this happens due to something which I consider an ssh bug of newer (OpenSSH_7.9p1 and above) clients, when it tries to learn a more secure ecdsa server key where there already is an older rsa type key known. It then presents this misleading message!

I do not know a good fix for this, the only workaround I found is to remove all "good but old rsa keys" such that the client can re-learn the "new more secure ecdsa keys". So:

  1. The first step is to remove all the good old RSA keys (Warning! This loses protection against MitM):

    $ sed -i '/ ssh-rsa /d' ~/.ssh/known_hosts
    
  2. The second step then is to re-learn all host keys, which must be done manually by connecting to each IP again using ssh.

Edit for Windows:

  • On Windows there is no sed, hence the best fix probably is to remove the known_hosts file with

    del %USERPROFILE%\.ssh\known_hosts`
    
  • Warning! This loses protection against MitM until all keys are re-learned.


Here is what I observe:

$ sftp test@136.243.197.100
Connected to test@136.243.197.100
sftp> 

$ sftp test@valentin.hilbig.de
Connected to test@valentin.hilbig.de.
sftp> 

Now try to connect to a newly introduced alias of this same already known good server:

$ sftp test@gcopy.net
Warning: the ECDSA host key for 'gcopy.net' differs from the key for the IP address '136.243.197.100'
Offending key for IP in /home/test/.ssh/known_hosts:45
Matching host key in /home/test/.ssh/known_hosts:44
Are you sure you want to continue connecting (yes/no)? 

Please have a look at the IP address. It's the same IP as above! So it looks like the (good) key of the (known) IP suddenly is offending itself (it isn't, as the ssh client mixes two incompatible keys, see below).

Now we try to fix it:

$ ssh-keygen -R 136.243.197.100
# Host 136.243.197.100 found: line 45
/home/test/.ssh/known_hosts updated.
Original contents retained as /home/test/.ssh/known_hosts.old

Let's try again:

$ sftp test@gcopy.net
Warning: Permanently added the ECDSA host key for IP address '136.243.197.100' to the list of known hosts.
Connected to test@gcopy.net.

$ sftp test@valentin.hilbig.de
Warning: the RSA host key for 'valentin.hilbig.de' differs from the key for the IP address '136.243.197.100'
Offending key for IP in /home/test/.ssh/known_hosts:45
Matching host key in /home/test/.ssh/known_hosts:10
Are you sure you want to continue connecting (yes/no)? 

WTF? What happened here? The new fresh key learned from the server fails again? And the problem even switched sides?!?

Nope, it's not the key, nor the server. Everything is correct!

It's the ssh client which fails to verify the correct key! Entry 45 in known_hosts now carries a key of type ecdsa-sha2-nistp256 while the key, which was pulled from the server by the client, is of type rsa-sha2-512 (and therefor cannot match the other key!).

$ sftp -v test@valentin.hilbig.de

shows:

debug1: kex: host key algorithm: rsa-sha2-512

while

$ sftp -v test@gcopy.net

shows:

debug1: kex: host key algorithm: ecdsa-sha2-nistp256

Apparently the ssh client has a bug somewhere! It cannot cope with a host key existing in more than one variant! Or it falls into the trap to request an outdated variant of a key.

How to fix?

I really have no idea. This probably can only be fixed upstream.

But there is a manual but clumsy workaround:

You have to manually remove all traces of the old key of type rsa. The key in question is shown in the output, but it is not directly marked as the problem:

Warning: the RSA host key for 'valentin.hilbig.de' differs from the key for the IP address '136.243.197.100'
Offending key for IP in /home/test/.ssh/known_hosts:45
Matching host key in /home/test/.ssh/known_hosts:10

check:

awk 'NR==45 { print $2 }' /home/test/.ssh/known_hosts
awk 'NR==10 { print $2 }' /home/test/.ssh/known_hosts

gives

ecdsa-sha2-nistp256
ssh-rsa

So here the matching host key is the offending one and the offending key is the right one which must be kept! So let's remove the wrong (matching) one:

ssh-keygen -R valentin.hilbig.de
# Host valentin.hilbig.de found: line 10
/home/test/.ssh/known_hosts updated.
Original contents retained as /home/test/.ssh/known_hosts.old

Now check again:

$ sftp test@valentin.hilbig.de
The authenticity of host 'valentin.hilbig.de (136.243.197.100)' can't be established.
ECDSA key fingerprint is SHA256:tf7lwe10C2p1lK2UG9p//m/4sUBCpX+i9k5Ub63c6Os.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'valentin.hilbig.de' (ECDSA) to the list of known hosts.
Connected to test@valentin.hilbig.de.
sftp> 

$ sftp test@gcopy.net
Connected to test@gcopy.net.
sftp> 

sftp test@136.243.197.100
Connected to test@136.243.197.100.
sftp>

YAY! Problem finally gone. But with several 100 entries in .ssh/known_hosts, this "solution" really becomes a major PITA (and an Error Prone Security Nightmare on Elm Street. YMMV.)

Tino
  • 1,186
  • 1
  • 13
  • 23
2

Are you using the same user for connecting?

If you are logged into a local PC like user John and connected to the server B like user Adolf@B and everything is OK, it does not mean that everything is OK if you are logged to local PC like user Jane and connecting to the server B like user Adolf@B.

If you want to login on server B as user Beda from PC A without password, try this command, all from PC A:

ssh-keygen -t rsa

This command generates the key and stores the key in the file. Please leave passphrase empty.

ssh Beda@B mkdir -p .ssh

This command creates the directory, if they do not already exist. Otherwise, do not print an error message.

cd ~/.ssh

This command changes the directory to your users home directory ./ssh.

cat id_rsa.pub | ssh Beda@B 'cat >> .ssh/authorized_keys'

This command prints the file id_rsa.pub (your public key) into authorized_keys on the server.

IMPORTANT: Beda is your username on the server which you are connecting, B is your server IP.

Now, you can connect to the server B without a password or passphrase:

ssh Beda@B
Jamal
  • 455
  • 1
  • 6
  • 17
  • 2
    Or just use ssh-copy-id to populate an authorized_keys file with your id_rsa.pub key without all the extra hassle. – BlakBat Aug 27 '18 at 11:03
1

This error kept annoying me for a long time. For some reason it made a difference whether i would do a

ssh host

or

ssh host.domain

https://askubuntu.com/questions/87449/how-to-disable-strict-host-key-checking-in-ssh

then pointed me to the option of changing the config file. See my script https://askubuntu.com/a/949731/129227 there for automating the process.

Wolfgang Fahl
  • 218
  • 1
  • 2
  • 14
  • 1
    Using configuration values `CanonicalizeHostname` and `CanonicalDomains` would avoid removing strict checking and would make ssh consider host and host.domain to be same. – BlakBat Nov 03 '18 at 15:02
1

Question: What's causing this, ...?

So the ssh server host key changed.  What caused the change?  It is hard to say.  Here are some guesses:

  • Did sshd on myserver start using ECDSA keys, so it is a new key type?
  • Was myserver recently re-installed?
  • Was sshd on myserver recently re-insalled so a new ssh host key was generated?
  • Did someone re-generate or replace the sshd host key?
  • Has the IP address of myserver changed so that a different host is answering to that IP address?

Question: ... and how do I fix it?

As others have already answered, remove the cached ECDSA host key for myserver that your account has cached.

Lars Nordin
  • 168
  • 6
1

The thread here may help.

Essentially, you want to remove both the RSA and ECDSA keys for that host, then use ssh-keyscan to put them back into your known_hosts file in a way that won't cause this conflict. It worked for me when I had the same issue.

ergosys
  • 265
  • 2
  • 14
Paul A Jungwirth
  • 643
  • 1
  • 5
  • 7
0

Here is how to remove a known host fingerprint (from known_hosts file) on a Chrome OS:

Find the index of the offending host entry in the ssh output when the connection fails. For example in the line below offending index is 7:

Offending ECDSA key in /.ssh/known_hosts:7

Open the JavaScript console (CTRL+Shift+J) of Secure Shell window and type the following, replacing INDEX with the appropriate value (e.g. 7):

term_.command.removeKnownHostByIndex(INDEX);

This solution was borrowed from Leo Gaggl's Blog.

Alex Yursha
  • 101
  • 2
0

The error message came with solution included in one line, just ran it and it worked like a charm.

ssh-keygen -f "/home/mymachine/.ssh/known_hosts" -R "[192.168.200.2]:2222"
0xFK
  • 111
  • 3
0

I fixed this on a Chromebook by uninstalling and reinstalling Secure Shell... It worked like a charm.