617

Just sometime ago I started getting this warning when pushing to GitHub.

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 a host key has just been changed.

Is this normal and how do I resolve it?

Machavity
  • 30,841
  • 27
  • 92
  • 100
Dheeraj Vepakomma
  • 26,870
  • 17
  • 81
  • 104
  • 2
    `ssh-keygen -R github.com` - this command does not update the previous ssh keys (your `~/.ssh/id_rsa` & `~/.ssh/id_rsa.pub` will remain unchanged). – Constantin De La Roche Mar 27 '23 at 07:11
  • 6
    github changed their RSA key in March and announced it in several places. Here is the web page describing what it is and what to do https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/ – Roman Czerwinski Apr 21 '23 at 19:40

7 Answers7

914

This happened because on the 24th of March 2023, GitHub updated their RSA SSH host key used to secure Git operations for GitHub.com because the private key was briefly exposed in a public GitHub repository. You will get that message if you had remembered GitHub’s previous key fingerprint in your SSH client before that date.

As per per the linked blog post, the solution is to remove the old key by running this command:

$ ssh-keygen -R github.com

Now the next git connection (pull, push or clone) should ask if you trust the new SSH key. Before entering yes, ensure the shown new key is valid, using the list:

https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints

Refer to the blog post for other ways to fix the issue.

user3840170
  • 26,597
  • 4
  • 30
  • 62
Dheeraj Vepakomma
  • 26,870
  • 17
  • 81
  • 104
  • 2
    Using Git Bash on Windows, I found that the above command worked, but on `git push` I got a message that the "authenticity of github.com can't be establish". Asked if I wanted to continue, I typed "yes" and now everything works again. – AlainD Mar 24 '23 at 12:31
  • 9
    @AlainD: that's exepcted, because this command basically just says "forget the old public key" and the new one will be trusted the next time. If you want to be correct about it, it's better to save the new, known correct one ahead of time (the blog post tells you how). – Joachim Sauer Mar 24 '23 at 13:24
  • 5
    I had an old RSA key for `ssh.github.com` in addition to the `github.com` ones hiding in `~/.ssh/known_hosts`. Remove that if you see it; it will be updated after you type "yes" as described by @AlainD. – Jacob Crofts Mar 24 '23 at 18:51
  • The _$ ssh-keygen -R github.com_ command works for me, then accept the connection request to use git push command. Thanks! – Guru Bhandari Mar 25 '23 at 21:42
  • Why isn't this message shown instead? `The authenticity of host ‘example.com (bla.bla.bla.bla)’ can't be established. ED25519 key fingerprint is SHA256:blablabla. Are you sure you want to continue connecting (yes/no)?` – amr Mar 26 '23 at 22:34
  • 1
    @amr that's the message when there is no record of it. – OrangeDog Mar 27 '23 at 10:47
  • I really wish they included this command in their error message – jonincanada Apr 14 '23 at 21:08
  • This solution also worked for a weird case where I deleted and recreated a fork of a repository with the exact same name. I got the ssh-key error and running this command solved it. – Joseph Farah Apr 17 '23 at 17:41
  • @JacobCrofts How did you do that? When checking all the files in my .ssh, I see one called `.ssh/known_hosts.old`. How do I remove it? The method works but it still throws an error when I git push saying ... `"Warning: the ECDSA host key for 'github.com' differs from the key for the IP address '140.82.121.3'. Offending key for IP in /home/daniel-iroka/.ssh/known_hosts:1 Matching host key in ...........` And then asking me if I'm sure. I want to remove that error message completely and removing the old key seems to be the solution, so how do I do it please. – Daniel Iroka Apr 28 '23 at 00:03
  • @DanielIroka to clarify, my "old" key for `ssh.github.com` was in the file `~/.ssh/known_hosts`, not `~/.ssh/known_hosts.old`. I did not change the latter file manually at all. I don't know what's wrong in your case, but I see a line in my `known_hosts` file beginning with `github.com ecdsa-sha2-nistp256 ...` that looks related. The next thing I would probably try in your position is to comment out that line and repeat key generation. – Jacob Crofts Apr 29 '23 at 15:09
  • @JacobCrofts I did not see this exact same line you talked about, but I saw a file which looked different from the others in my `known_hosts` file and it looked like this `|1|VC1tJqT1AQ3NMLsL0gkgHTx5hJ8=|kIJZjOGOGSUP64nEgPXF6KDeBaY= ecdsa-sha2-nistp256 ...` and yeah it was shorter than the others. Also, when you mean key generation, do you mean like the whole process of generating my SSH keys and then adding it to Github?? Like everything from afresh?? – Daniel Iroka May 01 '23 at 13:58
  • @DanielIroka I was thinking you could try commenting out that line and then following the steps in the blog post above. If that doesn't remove the error and you have no other ideas, starting afresh is an intuitive choice. – Jacob Crofts May 02 '23 at 20:41
  • @JacobCrofts it still didn't work. I guess I'll just go the route of starting a fresh if I don't find any solution. – Daniel Iroka May 02 '23 at 23:40
53

According to GitHub's blog post, their SSH key was leaked and therefore they regenerated their key.

You need to remove your stored key by running:

ssh-keygen -R github.com

Which should output something like:

# Host github.com found: line 1
.ssh/known_hosts updated.

If you want to be proactive, you can follow with a command to fetch their new key. This may not work on Windows and isn't required as without it. The next time you attempt to access GitHub, you will be prompted to save the new key.

curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | sed -e 's/^/github.com /' >> ~/.ssh/known_hosts

Once completed, you can rerun the git command you were attempting.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Sators
  • 2,746
  • 1
  • 20
  • 26
  • NOT WORKING.... GIVING ERROR. $ curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | sed -e 's/^/github.com /' >> ~/.ssh/known_hosts bash: jq: command not found % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 0 0 0 0 0 0 0 0 --:--:-- 0:00:07 --:--:-- 0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.haxx.se/docs/sslcerts.html – Kamlesh Mar 26 '23 at 09:00
  • curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above. – Kamlesh Mar 26 '23 at 09:01
  • @Kamlesh possibly jq library is missing on your side, try running this to install it: `brew install jq`. You'll need to have a brew installed as well (https://brew.sh/). – nikitahl Mar 27 '23 at 09:23
45

Yes, GitHub updated their RSA host key as mentioned in their blog post. You can follow the directions there to update your keys.

However, some people find that OpenSSH has also saved the host key for IP addresses via the CheckHostIP option. This was enabled by default before OpenSSH 8.5, but tends to be unhelpful since it makes rotation hard, and so it was disabled in that version. That being said, it can be worked around like so (on Linux and Git Bash):

$ sed -i -e '/AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31\/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi\/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==/d' ~/.ssh/known_hosts

and like so on macOS:

$ sed -i '' -e '/AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31\/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi\/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==/d' ~/.ssh/known_hosts

That removes the key wherever it's found, either for hostnames or IP addresses. Since GitHub uses multiple IP addresses, it's not really possible to enumerate all of them and remove them all with ssh-keygen, so removing the key itself manually is the best option.

You can then follow the directions from the blog post to update the keys automatically:

$ curl -L https://api.github.com/meta | jq -r '.ssh_keys | .[]' | \
  sed -e 's/^/github.com /' >> ~/.ssh/known_hosts
bk2204
  • 64,793
  • 6
  • 84
  • 100
  • 1
    They list their ip addresses and it is possible to enumerate them (there are over 14000), however the list is incompete, so yours is the best answer. – Jasen Mar 29 '23 at 00:25
  • Any insight into [the discussion under my answer](https://stackoverflow.com/questions/75830783/warning-remote-host-identification-has-changed-did-github-change-their-rsa/75837944?noredirect=1#comment133832388_75837944) would be helpful. You may have the answer to @Isikyus 's comment. – Gabriel Staples Mar 29 '23 at 06:12
  • 1
    This fixed the issue for me after following the github blog post recommendations (provided as an answer here by Sators) and seeing the error, "Warning: the ECDSA host key for 'github.com' differs from the key for the IP address" when pushing from the terminal. I was also getting an error and could not push using the button in the RStudio GUI, but this answer fixed it all. – Heidi Rodenhizer May 05 '23 at 11:49
  • Thank you! I kept getting errors `"Warning: the ECDSA host key for 'github.com' differs from the key for the IP address '140.82.121.4' Offending key for IP in /home/gabriele/.ssh/known_hosts:10 Are you sure you want to continue connecting (yes/no)? no"` with every fetch and I did not understand why, I started removing the lines manually one by one but I was getting mad, you explained the problem very well and this command fixed it once and for all for me! – Gabriele Buondonno May 16 '23 at 13:44
37

From GitHub's We updated our RSA SSH host key, What you can do:

At approximately 05:00 UTC on March 24 [2023], out of an abundance of caution, we replaced our RSA SSH host key used to secure Git operations for GitHub.com. We did this to protect our users from any chance of an adversary impersonating GitHub or eavesdropping on their Git operations over SSH. This key does not grant access to GitHub’s infrastructure or customer data. This change only impacts Git operations over SSH using RSA. Web traffic to GitHub.com and HTTPS Git operations are not affected.

Solution: Remove the old RSA SSH key of GitHub from file .ssh/known_hosts and update the new one.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dishant Walia
  • 701
  • 5
  • 8
15

On Ubuntu 20.04, using an Ed25519 key on GitHub, even after running ssh-keygen -R github.com, per the main answer, I kept seeing these notifications each time I ran git push:

$ git push
Warning: the ECDSA host key for 'github.com' differs from the key for the IP address '140.82.112.4'
Offending key for IP in /home/gabriel/.ssh/known_hosts:14
Matching host key in /home/gabriel/.ssh/known_hosts:15
Are you sure you want to continue connecting (yes/no)? yes
Warning: the ECDSA host key for 'github.com' differs from the key for the IP address '140.82.112.4'
Offending key for IP in /home/gabriel/.ssh/known_hosts:14
Matching host key in /home/gabriel/.ssh/known_hosts:15
Are you sure you want to continue connecting (yes/no)? yes
Warning: the ECDSA host key for 'github.com' differs from the key for the IP address '140.82.112.4'
Offending key for IP in /home/gabriel/.ssh/known_hosts:14
Matching host key in /home/gabriel/.ssh/known_hosts:15
Are you sure you want to continue connecting (yes/no)? yes

So, I finally just removed my ~/.ssh/known_hosts file by renaming it like this:

(Try @bk2204's answer instead of running the mv cmd below. Thanks, @Guntram Blohm).

mv ~/.ssh/known_hosts ~/.ssh/known_hosts.bak

...and now git push finally works just fine again! I don't care that I have to re-authenticate all my SSH destinations whenever I use SSH again to a particular server, so effectively removing the ~/.ssh/known_hosts file is fine. I hardly use SSH except for pushing to GitHub and GitLab anyway.

Note: the first time I ran git push after that I had to type yes, as shown below:

$ git push
The authenticity of host 'github.com (140.82.112.4)' can't be established.
ECDSA key fingerprint is SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com,140.82.112.4' (ECDSA) to the list of known hosts.
Everything up-to-date

Before typing yes, however, I first verified on GitHub's website that the SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM fingerprint was correct, and from GitHub. GitHub has the fingerprints for each key type here: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints

These are GitHub's public key fingerprints:

  • SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s (RSA)
  • SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ (DSA - deprecated)
  • SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM (ECDSA)
  • SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU (Ed25519)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
  • 4
    This might be a workaround if you're not using ssh for anything else, but if you have other servers you connect to, this means any changes to their keys will go unnoticed. (And obviously you have some others as the keys are on lines 14 and 15 of your `known_hosts`. Better delete the key like in @bk2204's answer, or note the line number (14 in your case) and delete line 14 manually. – Guntram Blohm Mar 24 '23 at 21:24
  • You know that the key is correct, because you verified the fingerprint, according to the GitHub website, which you verified with the new key? – Davislor Mar 24 '23 at 21:34
  • 9
    HTTPS and SSH use different private keys. The HTTPS private key was not leaked, just the SSH private key. – JBYoshi Mar 24 '23 at 22:01
  • 2
    @JBYoshi, I see several upvotes on your comment, so can you explain more about what that means and how it is pertinent? I don't understand what you're telling me or if you're indicating I should do something differently, but want to learn more. – Gabriel Staples Mar 25 '23 at 19:57
  • 3
    Gabriel, JBYoshi is replying to Davislor who implied there was a circularity in checking the fingerprints with the key that you're trying to check. In reality, you're verifying SSH keys with fingerprints that are verified through HTTPS, that had not been affected by the leak. So no circularity. All good. – Luca Citi Mar 26 '23 at 01:54
  • 2
    Yep, they answered my question. There have been breaches where someone “verified” with a key or checksum that they got from a site the attacker controls. – Davislor Mar 26 '23 at 15:52
  • 2
    @LucaCiti I did mean for my earlier comment to be a reply to Davislor. Sorry about the confusion - I’m new to StackOverflow so I didn’t know that was needed. – JBYoshi Mar 26 '23 at 20:16
  • 2
    It's all clear now . Btw, it's an interesting discussion and it's always worth raising the issue of not verifying with something that an attacker may control! – Luca Citi Mar 27 '23 at 03:35
  • Are you sure the error you're seeing (about ECDSA) is related to GitHub's change? According to their blog post, "If you are using our ECDSA or Ed25519 keys, you will not notice any change and no action is needed." – Isikyus Mar 29 '23 at 05:28
  • Or is the ECDSA warning because those IPs are now using ECDSA keys, where they were using RSA before? – Isikyus Mar 29 '23 at 05:31
  • @Isikyus, I have the same question. I don't pretend to understand (yet) the nuances of `openssh` nor the `known_hosts` file. bk2204 seems to provide some insight [in their answer](https://stackoverflow.com/a/75838045/4561887) though when they say: "However, some people find that OpenSSH has also saved the host key for IP addresses. This tends to be unhelpful, but it can be worked around like so..." In other words, it seems that openssh also saves a unique entry line for each IP address, not just each website URL. This seems to be where my problem lies. – Gabriel Staples Mar 29 '23 at 06:11
  • @GuntramBlohm, after only a few days of using nothing but GitHub, with no other ssh activity whatsoever, `cat ~/.ssh/known_hosts | wc -l` now shows `6` lines. So, apparently just pushing to a couple repos on GitHub (2 or 3 max) has added all of these entries to `~/.ssh/known_hosts`. I suspect all of my 16 or so lines in my old file before deleting it were all for GitHub and GitLab repos. – Gabriel Staples Mar 29 '23 at 07:36
  • This is the `CheckHostIP` option which was disabled by default in OpenSSH 8.5 because it "provides insignificant benefits while making key rotation more difficult." – bk2204 Mar 29 '23 at 21:34
  • @GabrielStaples I agree with you and bk2204 that the ECDSA keys are for IP addresses. What's puzzling me is that I'm getting errors for ECDSA keys, when GitHub's ECDSA key isn't supposed to have changed. – Isikyus Mar 31 '23 at 01:27
  • Removing your `known_hosts` file is a "big hammer" that will affect other keys stored there. I wrote a script to remove only the github IP addresses in [my answer](https://stackoverflow.com/a/75859237/1026023). – Jeff Ward Mar 31 '23 at 14:05
15

The GitHub blog suggests simply:

ssh-keygen -R github.com

Unfortunately, it's not that easy and I keep getting errors like the following, showing that GitHub servers are in my known_hosts file stored by IP address.

Warning: the ECDSA host key for 'github.com' differs from the key for the IP address '192.30.255.113'
Offending key for IP in /.ssh/known_hosts:19
Matching host key in /.ssh/known_hosts:178
Are you sure you want to continue connecting (yes/no)? yes

You'd have to search 1000's of IP addresses associated with github.com's services to clean them up...

I devised a Ruby script to search for GitHub IP addresses published via the the GitHub meta API. It is limited—it skips the huge "actions" IP address ranges, and only works for IPv4, but hopefully it helps someone else not have to press yes a bunch of times.

https://gist.github.com/jcward/5a64c17a6b61de0f7a4d85d004e7679e

It is reproduced here for archival purposes:

#!/usr/bin/env ruby
#
# https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
# https://stackoverflow.com/questions/75830783
#
# Scan for github IP addresses in your knwon_hosts and remove them
# - Takes ~1.5 minutes on my machine
# - Skips the huge "actions" IP ranges
# - Skips IPv6

require 'json'

meta = JSON.parse `curl -s https://api.github.com/meta`

def num_to_ipv4 v
  (v >> 24 & 255).to_i.to_s + "." +
  (v >> 16 & 255).to_i.to_s + "." +
  (v >> 8 & 255).to_i.to_s + "." +
  (v >> 0 & 255).to_i.to_s
end

def get_ips_for octals, bits
  ips = []
  base = (octals[0] << 24) | (octals[1] << 16) | (octals[2] << 8) | octals[3]
  num = 2**(32-bits)
  0.upto(num) { |add|
    ips.push( num_to_ipv4( base + add ) )
  }
  return ips
end

meta.each { |key, value|
  next if key=="actions" # These ranges are too large
  if (value.is_a?(Array)) then
    value.each { |ip|
      if (ip.match(/(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)/)) then
        octals = [$1, $2, $3, $4].map(&:to_i)
        bits = $5.to_i
        ips = get_ips_for(octals, bits)
        puts "# Scanning #{ key } range -- #{ ips.length } IPs"
        ips.each { |ip|
          search = `ssh-keygen -H -F #{ ip }`
          if (search.length > 10) then
            puts "Running: ssh-keygen -R #{ ip }"
            `ssh-keygen -R #{ ip }`
          end
        }
      end
    }
  end
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeff Ward
  • 16,563
  • 6
  • 48
  • 57
  • 1
    @jasen - it does when I log the output of the script. It's in this block: `140.82.112.0 / 20` -- which starts at 140.82.112.1 and ends at 140.82.127.255 – Jeff Ward Mar 30 '23 at 15:31
1

If curl commands are giving you an error just edit your ~/.ssh/known_hosts' github.com entry with:

github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=
Rivera
  • 10,792
  • 3
  • 58
  • 102