为什么通过SSH连接到GitHub会抛出错误“警告:远程主机标识已更改”?

tyg4sfes  于 2023-04-04  发布在  Git
关注(0)|答案(6)|浏览(361)

这篇文章涉及到一个快速变化的事件。
就在不久前,我在推送到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.

这是正常的吗?如何解决?

xcitsw88

xcitsw881#

这是因为在2023年3月24日,GitHub updated their RSA SSH host key用于保护www.example.com的Git操作GitHub.com,因为私钥在公共GitHub存储库中短暂暴露。如果您在该日期之前在SSH客户端中记住了GitHub之前的密钥指纹,您将收到该消息。
根据链接的博客文章,解决方案是通过运行以下命令删除旧密钥:

$ ssh-keygen -R github.com

现在,下一个git连接(pull、push或clone)应该询问您是否信任新的SSH密钥。在输入yes之前,请使用以下列表确保显示的新密钥有效:
https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
请参阅blog post以了解解决此问题的其他方法。

vbopmzt1

vbopmzt12#

来自Github:
在UTC [2023] 3月24日05:00左右,出于谨慎考虑,我们更换了用于保护www.example.com的Git操作的RSA SSH主机密钥GitHub.com。我们这样做是为了保护我们的用户免受攻击者冒充GitHub或通过SSH窃听他们的Git操作的任何机会。此密钥不会授予对GitHub基础设施或客户数据的访问权限。此更改仅影响使用RSA通过SSH的Git操作。GitHub的Web流量。com和HTTPS Git操作不受影响。
解决方案:从.ssh/ known_hosts中删除github的旧RSA SSH密钥,并更新新密钥。https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/#what-you-can-do

rqdpfwrv

rqdpfwrv3#

根据Github的blog post,他们的SSH密钥被泄露,因此他们重新生成了密钥。
您需要通过运行以下命令来删除存储的密钥:

$ ssh-keygen -R github.com

它应该输出如下内容:

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

后面跟着一个获取新密钥的命令:

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

完成后,您可以重新运行您尝试的git命令。

6ljaweal

6ljaweal4#

是的,GitHub更新了their blog post中提到的RSA主机密钥。您可以按照那里的说明更新密钥。
然而,有些人发现OpenSSH也通过CheckHostIP选项保存了IP地址的主机密钥。这在OpenSSH 8.5之前是默认启用的,但由于它使旋转变得困难,因此它在那个版本中被禁用。也就是说,它可以像这样工作(在Linux和Git Bash上):

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

在macOS上是这样的:

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

这将删除任何找到的密钥,无论是主机名还是IP地址。由于GitHub使用多个IP地址,因此不可能枚举所有IP地址并使用ssh-keygen将其全部删除,因此手动删除密钥本身是最佳选择。
然后,您可以按照博客文章中的说明自动更新密钥:

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

qoefvg9y5#

在Ubuntu 20.04上,使用Github上的ed 25519键,即使在运行ssh-keygen -R github.com之后,根据main answer,我每次运行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

所以,我终于删除了我的~/.ssh/known_hosts文件,重命名为这样:
(更新:尝试@bk2204的答案,而不是运行下面的mv命令。谢谢,@Guntram Blohm)。

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

...现在git push终于又可以正常工作了!我不在乎每当我再次使用ssh到特定服务器时必须重新验证所有ssh目的地,所以有效地删除~/.ssh/known_hosts文件是可以的。我几乎不使用ssh,除了推送到GitHub和GitLab。
注意:第一次运行git push之后,我必须输入yes,如下所示:

$ 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

然而,在输入yes之前,我首先在GitHub的网站上验证了SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM指纹是正确的,并且从GitHub. GitHub这里有每个密钥类型的指纹:https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints
以下是GitHub的公钥指纹:

  • SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s(RSA)
  • SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ(DSA -已弃用)
  • SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM(ECDSA)
  • SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU(Ed25519)
fcg9iug3

fcg9iug36#

github blog简单地建议:

ssh-keygen -R github.com

不幸的是,这并不容易,我一直收到如下错误,显示github服务器在我的known_hosts中,按IP地址存储。

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

你必须搜索1000个与www.example.com服务相关的IP地址github.com来清理它们。😈
我设计了一个Ruby脚本来搜索通过GitHub meta API发布的github IP地址。它是有限的-它跳过了巨大的“动作”IP范围,并且只适用于IPv4,但希望它可以帮助其他人不必多次按yes
https://gist.github.com/jcward/5a64c17a6b61de0f7a4d85d004e7679e
此处转载以供存档:

#!/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
}

相关问题