连接远程仓库时出现Git错误:“主机密钥验证失败”

537

我试图连接到一个位于我的 Web 服务器上的远程 Git 存储库,并将其克隆到我的本地计算机。

我正在使用以下格式的命令:

git clone ssh://username@domain.example/repository.git

这对我的团队大多数成员都有效。通常在运行此命令后,Git会提示用户输入密码,然后运行克隆操作。但是,在我其中一台机器上运行时,我遇到了以下错误:

主机密钥验证失败。

致命错误:无法从远程存储库读取。

我们没有使用SSH密钥连接到此存储库,因此我不确定为什么Git正在检查此特定机器上的密钥。


20
你正在使用SSH连接到该代码库,注意你的URL以ssh://开头。 - Brandon
15
注意:GitHub 刚刚重置了他们的主机密钥。他们在博客文章中提供了另一种解决方案。请参阅 https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/。 - Ryan Shillington
我按照上面博客中的指令(使用编辑已知主机文件)进行了操作,昨天Git同步正常,但今天出现了“主机密钥验证失败...”的问题。这篇博客提供的解决方案应该是一个持久性的解决方案,对吗? - Frank_Coumans
33个回答

888

4
除非您已经拥有密钥,否则这是最安全的方法。这是假设您仅运行一次,而不是每次连接到服务器。 - Zenexer
我公司的私有代码仓库使用ECDSA作为密钥,因此如果解决方案不起作用,可能是因为算法不正确。 - Fendy
2
我也遇到了同样的问题,一直在想为什么我无法克隆自己的存储库。 - StackAttack
12
如果您使用的是Windows操作系统,最简单的方法是安装git-for-windows(下载)并打开Git Bash。在这个控制台中,您可以使用ssh-keyscan命令。 - Rafael Araújo
3
你不知道你的回答能够为我省下多少年的挫败感。 它还解决了Github桌面版的身份验证错误。我也需要试一下我的流感XD。 - Diaa
显示剩余6条评论

332
您正在通过SSH协议连接,如克隆URL上的ssh://前缀所示。使用SSH,每个主机都有一个密钥。客户端会记住与特定地址相关联的主机密钥,并在主机密钥似乎发生更改时拒绝连接。这可以防止中间人攻击。 domain.example的主机密钥已更改。如果这对您来说不可疑,请通过编辑${HOME}/.ssh/known_hosts以删除domain.example行或使用SSH实用程序让它为您完成。
ssh-keygen -R domain.example

从这里开始,可以通过以下方式之一来记录更新的密钥:

ssh-keyscan -t rsa domain.example >> ~/.ssh/known_hosts

或者,同样地,让ssh在下次连接git fetchgit pullgit push(甚至是一个普通的ssh domain.example)时为您完成它,当提示时回答“yes”即可。

主机 'domain.example (a.b.c.d)' 的真实性无法确定。
RSA key fingerprint is XX:XX:...:XX.
Are you sure you want to continue connecting (yes/no)?

出现此提示的原因是在删除domain.example并且很可能不在系统的/etc/ssh/ssh_known_hosts中时,domain.example不再在您的known_hosts中,因此ssh无法知道连接另一端的主机是否真的是domain.example。(如果/etc中有错误的密钥,则需要某个具有管理权限的人更新系统范围的文件。)

我强烈建议您也考虑使用密钥进行用户身份验证。这样,ssh-agent可以存储密钥材料以方便使用(而不是每次连接服务器都必须输入密码),密码也不会通过网络传输。


8
有趣的事实是,运行sudo ssh-keygen -R domain.com 命令可以将您现有的 known_hosts 文件重命名为 known_hosts.old,并创建一个只能被 root 用户读取的副本 (-rw------- root root)。您可以轻松地将其 chown 回适当的用户,但您也可能会浪费一下午来调试 Git 出了什么问题。 :D - Andrew Rueckert
30
你确定要继续连接吗(是/否)?不要犯和我一样的错误。你需要输入“是”才行,只是按回车键不能默认选择是。 - JolonB
3
对于像 Jenkins 这样的 CI 环境,当提示时你不能回答“yes”。因此,请确保:
  1. 你已经正确创建了 SSH 密钥,并将其放置在你家目录下的 .ssh 目录中。
  2. 按照这里所述将目标域名添加到 known_hosts 中。
- Sebastian Juarez
5
需要注意的是,你可能需要远程仓库的端口号:ssh-keyscan -p 8888 -t rsa domain.com >> ~/.ssh/known_hosts - andrew
7
随意在命令前添加“sudo”的一个原因是不好的,这只是其中之一。 - jbg
显示剩余5条评论

103

我曾经遇到过类似的问题,但是使用 SSH 密钥时出现了问题。根据上面 Tupy 的回答,我发现问题在于 known_hosts 文件不存在或者 github.com 不在已知主机列表中。以下是我解决此问题所采取的步骤 -

  1. mkdir -p ~/.ssh
  2. ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
  3. ssh-keygen -t rsa -C "user.email"
  4. 使用此命令打开公钥 $ cat ~/.ssh/id_rsa.pub 并将其复制。
  5. id_rsa.pub 密钥添加到 GitHub 资料页的 SSH 密钥列表中。

2
@OJFord FYI:我已经编辑了原始答案,使您的评论过时了。说实话,即使一开始它也不完全正确。如果~/.ssh目录不存在,则touch命令将失败,因此仍需要步骤1。此外,在使用>>重定向之前,您不需要touch文件。如果需要,它将被创建(但只是文件,而不是整个路径,因此仍然需要mkdir -p)。-p选项使其在目录已存在的情况下工作。 - Tad Lispy
2
Github文档中添加新的ssh密钥时缺少第二个“ssh-keyscan”。 - Phil Andrews
2
我在使用 Dockerfile 时遇到了权限不足的问题。在这里添加第二步骤解决了这个问题!感谢你的出色工作。 - Spencer Pollock
我按照上述步骤操作,但失败了,因为我在Spring配置服务器属性文件中将github.com作为hostKey。那些无法连接spring.cloud.config-server从git获取的人,请参考https://tranhoangminh.wordpress.com/2018/09/14/spring-cloud-config-server-and-ssh-git-repository/。这里讲解得非常清楚。 - SHAKU

80
这是因为github目前不在你的已知主机中。
你应该会看到提示让你将github添加到你的已知主机列表中。如果没有出现这个提示,你可以运行ssh -T git@github.com再次获得提示。

4
如果您从未被提示,那么这就是正确答案。 - Matthias Hagemann
Vscode突然出现了无缘无故的错误。使用这个答案就可以解决我的问题。 - Someone Special

38

对我而言,在提示“是否确认继续连接(yes/no)?”时,我只需输入“yes”,而不是直接按回车键。


2
这个答案让我意识到我必须在我的构建服务器上手动克隆我的仓库,以便输入“是”,并将我的Bitbucket服务器添加到我的known_hosts中。 - Sashah
2
如果你只需要在known_hosts中加入bitbucket服务器,你可以手动编辑该文件,无需克隆仓库来实现这一目的。 - Code-Apprentice
2
哇,我在这个问题上卡了一个小时,现在解决了。谢谢! - Akanksha Atrey

21
当终端显示以下内容时:

Are you sure you want to continue connecting (yes/no)?

不要重复不要直接按下Enter

必须先在终端中输入yes,然后再按Enter


天啊。谢谢。 - Alk
- ינון רחמים
这是正确的答案。 - cassi.lup
这个非常令人惊讶地有效。谢谢! - undefined

18
如果您在办公室内部网络(否则很危险),该网络始终受到防火墙的保护,那么请在您的~/.ssh/config文件中添加以下内容。
Host *
  StrictHostKeyChecking no
  UserKnownHostsFile=/dev/null

7
即便有企业防火墙,这仍然存在危险。若未经验证服务器密钥,又如何确信你正在与真正的GitHub通讯? - Mnebuerquo
2
在公司环境中,大多数情况下使用本地Git存储库,而不使用开源的存储库。最坏的情况是,在文件顶部的.ssh配置中可以有与GitHub明确宿主相关的配置行,以便ssh选择更具体的匹配项。 - sunil

14

当被问到:

是否确定要继续连接(是/否)?

回复作为答案

这就是我解决问题的方法。但如果你只是试图按下回车键,它是不起作用的!


10

我在一个新安装的系统上遇到了同样的问题,但这是一个udev问题。没有/dev/tty节点,所以我必须执行以下操作:

mknod -m 666 /dev/tty c 5 0

2
它对我有用,因为/dev/tty被创建为文件,非常奇怪!(所以你必须删除它,然后使用mknod重新创建它) - Doomsday
@Geoffroy,我删除了/dev/tty,现在当我执行sudo时,我遇到了这个错误:sudo: sorry, you must have a tty to run sudo。 - Milad
@xe4me 我从未说过你应该将其删除,根据系统的不同,它实际上是必需的。重新启动应该可以解决问题。 - Geoffroy
@Geoffroy,实际上第一个评论者说我必须删除并重新创建:d 不,重启没有起作用,我不得不告诉管理员,他修复了它:d - Milad

7
我的建议是先添加新计算机的SSH密钥,我按照这篇来自GitLab - add SSH key的说明进行操作。需要注意的是,由于我使用的是Win10系统,所以我必须在Git Bash中执行所有命令(在常规DOS cmd Shell中无法工作)。
接着,在Git Bash中,我必须使用git clone命令克隆我遇到问题的存储库。在我的情况下,我必须将其克隆到不同的名称,因为我已经在本地拥有它,并且不想失去我的提交记录。例如:
git clone ssh://git@gitServerUrl/myRepo.git myRepo2

随后我收到提示,要将其添加到已知主机列表中,可能会出现以下问题:

您确定要继续连接吗(yes/no)?

我输入了"yes"然后它最终起作用了,你通常应该得到类似这样的消息:

警告:已永久添加 '[your repo link]'(ECDSA)到已知主机列表中。

注意:如果您使用Windows,请确保对所有命令使用Git Bash执行。这在普通cmd shell或powershell中无法正常工作,我确实需要在Git Bash中执行此操作。

最后,我删除了第二个克隆存储库(例如中的myRepo2),并回到了我的第一个存储库,现在我终于可以像平常一样在我喜欢的编辑器VSCode中进行所有Git操作了。


我的Cygwin提示符看起来几乎和我的git bash提示符一模一样,但它只在git bash提示符中有效! - Josiah Yoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接