git - 服务器主机密钥未缓存

Posted

技术标签:

【中文标题】git - 服务器主机密钥未缓存【英文标题】:git - Server host key not cached 【发布时间】:2011-06-23 07:34:26 【问题描述】:

我尝试将更改从本地存储库推送到远程存储库。当我输入时:

git push origin

我收到以下错误:

The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
Connection abandoned.
fatal: The remote end hung up unexpectedly

我该如何解决这个问题?我在 Windows 7 的命令行中使用 git。

编辑

当我尝试做一个简单的 ssh 时

ssh user@hostname

我收到以下错误:

Could not create directory '/c//%HOMEDRIVE%%HOMEPATH%/.ssh'.
percent_expand: unknown key %H

不知何故,它不会创建目录,因为路径无效。如何解决这个问题?

@eckes:Edit2

我的主页设置为%HOMEDRIVE%%HOMEPATH%,对吗?

【问题讨论】:

似乎$HOME 设置不正确。尝试使用My Computer在windows上设置HOME环境变量->右键单击->Properties->选项卡Advanced->按钮Environment Variables 我不是 Windows 用户,但在/c//(可能是驱动器号)之后,你仍然有%HOMEDRIVE%,这确实让我感到奇怪……你也许可以拯救自己有一段时间自己摆弄价值,然后回应它? 展开 HOMEDRIVEHOMEPATH 并将 HOME 设置为结果值... 【参考方案1】:

对于那些通过标准命令提示符使用 PuTTY 在 Windows 上设置 MSYS Git 的人来说,将主机添加到 PuTTY 缓存的方法是运行

> plink.exe <host>

例如:

> plink.exe codebasehq.com

The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 2e:db:b6:22:f7:bd:48:f6:da:72:bf:59:d7:75:d7:4e
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n)

只需回答y,然后 Ctrl+C 其余部分。

请检查指纹。这个警告是有充分理由的。一些 git 服务的指纹(请编辑添加更多):

GitHub:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48 比特桶:97:8c:1b:f2:6f:14:6b:5c:3b:ec:aa:46:46:74:7c:40 豪言壮语:7e:af:8d:ec:f0:39:5e:ba:52:16:ce:19:fa:d4:b8:7d

【讨论】:

这应该是公认的答案。这正是错误消息所指的内容。在我克隆的情况下,我使用了 FQDN,但在我的新机器上,我只使用短本地域名登录。我必须通过 putty 或 plink 作为 FQDN 登录,以缓存源主机名的密钥。使用“git remote -v”可以帮助交叉检查用作远程的主机名。 它也适用于对您尝试使用的主机使用交互式 PuTTY。例如,如果您第一次尝试在新的 Windows 机器上克隆 Github 存储库,请使用 PuTTY 打开与主机 'github.com' 的会话,接受有关服务器信任的提示,然后在命令行应该可以工作。 你可以告诉 MSYS git 正在尝试使用 plink,方法是运行 $ set | grep GIT_SSH 并检查 GIT_SSH='C:\Program Files (x86)\PuTTY\plink.exe' 我最终通过将我的密钥添加到 Pageant 并使用 Putty 直接访问主机来解决此问题。这要求您将主机添加到缓存中。做同样的事情。 如果您的 git 存储库在自定义 SSH 端口上提供服务,请使用 -P 选择端口,例如:plink.exe example.com -P 2222。我可以从 github 克隆,但不能从我的个人服务器克隆,这让我很困惑。【参考方案2】:

尝试在 Git Bash 提示符下执行“set | grep -i ssh”

如果你的设置和我的一样,你可能有这些设置:

GIT_SSH='C:\Program Files (x86)\PuTTY\plink.exe'
PLINK_PROTOCOL=ssh
SVN_SSH='"C:\\Program Files (x86)\\PuTTY\\plink.exe"'

我做了一个

unset GIT_SSH
unset PLINK_PROTOCOL
unset GIT_SVN

然后它就起作用了,..我猜腻子将它的密钥保存在其他地方作为 $HOME/.ssh 或其他东西......(我在 $HOME 设置为“C: \Users\usrnam" 而不是 "/C/Users/usrnam/"

无论如何,您的里程可能会有所不同,但这对我来说是固定的。 :-)

(可能只做未设置的 GIT_SSH 就足够了,但我很顺利)

注意:如果未设置对您不起作用,请尝试以下操作:

set GIT_SSH=

【讨论】:

"unset GIT_SSH" 为我工作。我之前为不同的服务器设置了 Pageant / putty,但是当我使用 Git Bash 提示构建新密钥时,我需要返回。感谢您的帮助。 采取您的步骤后,我走得更远,但现在我收到“输入时 mac 损坏”错误...见过吗? 安装 git 时,您可以选择不设置这些变量。它甚至是默认变体。虽然我也选择了 plink 集成,但这就是我在这里的原因)谢谢。 这对我也适用于 Win7。显然 git bash 的 plink 设置导致了我的问题。 unset GIT_SSH 也为我工作,但我每次启动 git bash 时都必须这样做,这很无聊。关于如何自动化的任何想法?【参考方案3】:

该消息表示origin 的主机密钥不在您的受信任主机文件中。

要解决此问题,请打开到 origin 的普通 SSH 连接,SSH 会询问您是否要信任远程主机(来自 Git 控制台):

$ ssh 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
RSA key fingerprint is <FINGERPRINT>.
Are you sure you want to continue connecting (yes/no)?

如果您信任远程主机(即键入yes),SSH 会将其密钥添加到已知主机列表中。

在那之后,你应该可以做你的git push origin

作为替代方案,您也可以手动将origin 的键添加到.ssh/known_hosts,但这要求您遵守sshd 手册页中所述的known_hosts 文件格式(第AUTHORIZED_KEYS 文件格式)。

【讨论】:

我在推送到 github 时收到了同样的消息,但我可以 ssh 到 github,而且我的 known_hosts 文件中有 github.com。 在这种情况下请看下面的答案 您可以在 windows 上使用 PuTTY 来代替命令行 SSH 客户端。 确保主机名完全相同。例如,如果您在本地安装了 git 并使用名称“home.mydomain.com”作为远程,但使用 putty 存储密钥以连接到“localhost”,那将无法正常工作。您需要准确连接到远程 url 中的主机名。 对我来说修复了尝试使用 putty 连接到服务器的问题。假设 git url 是 ssh://git@example.ex.com:222/something/shop.git 所以我输入了腻子主机名字段 example.ex.com 和端口 222。然后连接失败但我猜它添加了手指在需要的地方打印。我只是不明白它在哪里添加,因为在我的主目录 known_hosts - 当我删除旧密钥时文件没有受到影响【参考方案4】:

我怀疑您的GIT_SSH 环境变量设置为%ProgramFiles(x86)%\putty\plink.exe。 出于某种原因,PLink 不使用用户目录中的.ssh/known_hosts 文件来存储远程主机密钥。

如果你真的是这种情况,如果你想使用选美可能是故意的,你需要先使用PLink连接到主机。

"$GIT_SSH" user@hostname

您应该会收到类似的消息

The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 86:7b:1b:12:85:35:8a:b7:98:b6:d2:97:5e:96:58:1d
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n)

一旦您回答了y 的问题并成功连接到远程主机,您就应该准备好了。继续尝试再次推送。

【讨论】:

这就是我在带有 PLink/Pageant 的 Windows 上使用 Git Bash 的目的。非常感谢! 使用 Stash(现在是 Bitbucket)存储库,我不得不使用 "$GIT_SSH" -P 7999 git@stash.domain.local【参考方案5】:

至少在 Windows 上,仅 ssh'ing 到主机是不够的。这会将主机密钥添加到ssh/known_hosts,但错误仍然存​​在。

您需要关闭 git bash 窗口并打开一个新窗口。然后清除注册表缓存,然后推/拉工作。

【讨论】:

ssh/known_hosts 与什么相关?,%USERPROFILE% 我在 Win 7 上遇到此问题,但没有解决方案...【参考方案6】:

Rene,您的 HOME 变量设置不正确。将其更改为 c:\Users\(your-username) 或仅更改为 %USERNAME%

【讨论】:

【参考方案7】:

Plink 解决方案

将this python script保存到known_hosts.py

#! /usr/bin/env python

# $Id$
# Convert OpenSSH known_hosts and known_hosts2 files to "new format" PuTTY
# host keys.
#   usage:
#     kh2reg.py [ --win ] known_hosts1 2 3 4 ... > hosts.reg
#       Creates a Windows .REG file (double-click to install).
#     kh2reg.py --unix    known_hosts1 2 3 4 ... > sshhostkeys
#       Creates data suitable for storing in ~/.putty/sshhostkeys (Unix).
# Line endings are someone else's problem as is traditional.
# Developed for Python 1.5.2.

import fileinput
import base64
import struct
import string
import re
import sys
import getopt

def winmungestr(s):
    "Duplicate of PuTTY's mungestr() in winstore.c:1.10 for Registry keys"
    candot = 0
    r = ""
    for c in s:
        if c in ' \*?%~' or ord(c)<ord(' ') or (c == '.' and not candot):
            r = r + ("%%%02X" % ord(c))
        else:
            r = r + c
        candot = 1
    return r

def strtolong(s):
    "Convert arbitrary-length big-endian binary data to a Python long"
    bytes = struct.unpack(">%luB" % len(s), s)
    return reduce ((lambda a, b: (long(a) << 8) + long(b)), bytes)

def longtohex(n):
    """Convert long int to lower-case hex.

    Ick, Python (at least in 1.5.2) doesn't appear to have a way to
    turn a long int into an unadorned hex string -- % gets upset if the
    number is too big, and raw hex() uses uppercase (sometimes), and
    adds unwanted "0x...L" around it."""

    plain=string.lower(re.match(r"0x([0-9A-Fa-f]*)l?$", hex(n), re.I).group(1))
    return "0x" + plain

output_type = 'windows'

try:
    optlist, args = getopt.getopt(sys.argv[1:], '', [ 'win', 'unix' ])
    if filter(lambda x: x[0] == '--unix', optlist):
        output_type = 'unix'
except getopt.error, e:
    sys.stderr.write(str(e) + "\n")
    sys.exit(1)

if output_type == 'windows':
    # Output REG file header.
    sys.stdout.write("""REGEDIT4

[HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys]
""")

# Now process all known_hosts input.
for line in fileinput.input(args):

    try:
        # Remove leading/trailing whitespace (should zap CR and LF)
        line = string.strip (line)

        # Skip blanks and comments
        if line == '' or line[0] == '#':
            raise "Skipping input line"

        # Split line on spaces.
        fields = string.split (line, ' ')

        # Common fields
        hostpat = fields[0]
        magicnumbers = []   # placeholder
        keytype = ""        # placeholder

        # Grotty heuristic to distinguish known_hosts from known_hosts2:
        # is second field entirely decimal digits?
        if re.match (r"\d*$", fields[1]):

            # Treat as SSH-1-type host key.
            # Format: hostpat bits10 exp10 mod10 comment...
            # (PuTTY doesn't store the number of bits.)
            magicnumbers = map (long, fields[2:4])
            keytype = "rsa"

        else:

            # Treat as SSH-2-type host key.
            # Format: hostpat keytype keyblob64 comment...
            sshkeytype, blob = fields[1], base64.decodestring (fields[2])

            # 'blob' consists of a number of
            #   uint32    N (big-endian)
            #   uint8[N]  field_data
            subfields = []
            while blob:
                sizefmt = ">L"
                (size,) = struct.unpack (sizefmt, blob[0:4])
                size = int(size)   # req'd for slicage
                (data,) = struct.unpack (">%lus" % size, blob[4:size+4])
                subfields.append(data)
                blob = blob [struct.calcsize(sizefmt) + size : ]

            # The first field is keytype again, and the rest we can treat as
            # an opaque list of bignums (same numbers and order as stored
            # by PuTTY). (currently embedded keytype is ignored entirely)
            magicnumbers = map (strtolong, subfields[1:])

            # Translate key type into something PuTTY can use.
            if   sshkeytype == "ssh-rsa":   keytype = "rsa2"
            elif sshkeytype == "ssh-dss":   keytype = "dss"
            else:
                raise "Unknown SSH key type", sshkeytype

        # Now print out one line per host pattern, discarding wildcards.
        for host in string.split (hostpat, ','):
            if re.search (r"[*?!]", host):
                sys.stderr.write("Skipping wildcard host pattern '%s'\n"
                                 % host)
                continue
            elif re.match (r"\|", host):
                sys.stderr.write("Skipping hashed hostname '%s'\n" % host)
                continue
            else:
                m = re.match (r"\[([^]]*)\]:(\d*)$", host)
                if m:
                    (host, port) = m.group(1,2)
                    port = int(port)
                else:
                    port = 22
                # Slightly bizarre output key format: 'type@port:hostname'
                # XXX: does PuTTY do anything useful with literal IP[v4]s?
                key = keytype + ("@%d:%s" % (port, host))
                value = string.join (map (longtohex, magicnumbers), ',')
                if output_type == 'unix':
                    # Unix format.
                    sys.stdout.write('%s %s\n' % (key, value))
                else:
                    # Windows format.
                    # XXX: worry about double quotes?
                    sys.stdout.write("\"%s\"=\"%s\"\n"
                                     % (winmungestr(key), value))

    except "Unknown SSH key type", k:
        sys.stderr.write("Unknown SSH key type '%s', skipping\n" % k)
    except "Skipping input line":
        pass

在 Win7x64 和 Python 2.7 上测试。

然后运行:

ssh-keyscan -t rsa bitbucket.org >>~/.ssh/known_hosts
python --win known_hosts.py >known_hosts.reg
start known_hosts.reg

并选择导入到注册表中。 keyscan 将检索域的公钥(我遇到了 bitbucket 的问题),然后 python 脚本将其转换为 Plink 格式。

【讨论】:

【参考方案8】:

遇到同样的问题,忘记在实际存储库所在的端口上连接 SSH,而不仅仅是一般的 SSH 端口,那么主机密钥不同!

【讨论】:

也使用完全相同的方式指定主机,例如不是 gitserver.example.com 用于 ssh 和 gitserver 用于 git。【参考方案9】:

只需打开 Putty 并尝试与要推送代码的远程服务器建立连接。 当对话框出现时按是(你信任远程)然后一切都会好的。

【讨论】:

【参考方案10】:

工作环境:

Windows 10 混帐 腻子

首先:根据Regedit删除注册表中的putty known_hosts。然后:在Window的cmd中执行%GIT_SSH% user@hostname命令即可解决问题。

希望对大家有帮助。

【讨论】:

【参考方案11】:

当我尝试在我的 Windows 7 机器上克隆存储库时,我也遇到了同样的问题。我尝试了这里提到的大部分答案。他们都没有为我工作。

对我有用的是运行 Pageant(腻子身份验证代理)程序。一旦选美在后台运行,我就可以从/向存储库进行克隆、推送和拉取。这对我有用,可能是因为我已经设置了我的公钥,以便在第一次使用它时需要密码并且选美会启动。

【讨论】:

当它是选美问题时,您会收到其他错误消息。不是Connection abandoned,而是类似Access denied (private key)【参考方案12】:

从 PuTTY 更改为 OpenSSH 为我解决了这个问题,无需取消设置 GIT_SSH 等。

【讨论】:

如果您在使用 ATLASSIAN SOURCETREE 执行 git push/pull 操作时收到有关无法识别的主机密钥的消息,则您无法回答 y/n,并且 push/pull 操作将在没有缓存的情况下中止钥匙。但是,转到 SourceTree Tools->Options(常规选项卡)并将(在 SSH 客户端配置下)下的 SSH 客户端从 PuTTY 更改为 OpenSSH 将允许在不更改任何其他内容的情况下缓存密钥。【参考方案13】:

我用这个workaround解决了类似的问题。

您只需切换到 Embedded Git,按下,按是按钮,然后切换回 System Git。

您可以在

中找到此选项
Tools -> Options -> Git

【讨论】:

现在在 v2.5.5.0 位置:C:\Users\UserName\AppData\Local\SourceTree\app-2.5.5\tools\putty&gt; .\plink.exe YourNewHost【参考方案14】:

正如Roman Starkov 的回答,plink 需要将主机添加到它的缓存中。

对于使用 Git 扩展的人:

    打开 Git 扩展 转到工具 -> 设置 -> SSH 将路径复制到“plink.exe”(如果使用 PuTTY)/“klink.exe”(如果使用 KiTTY) 在控制台中,运行以下命令:

(替换为实际路径)

<the path to plink/klink.exe> <address to the server>

例如

%ProgramData%\chocolatey\lib\kitty\tools\klink.exe codebasehq.com

注意:确保使用与 Git Extensions 相同的 plink/klink!

【讨论】:

【参考方案15】:

直接使用 Bash 添加主机并没有解决问题,在 Git Extensions 中使用 'Fetch all' 时仍然出现错误。通过在一个分支上使用“Pull”,Git Extensions 使用 Bash 弹出屏幕自动添加了所需的主机。完成此操作后,我可以再次使用“获取全部”。不确定 Git Extensions 做了什么不同。

【讨论】:

【参考方案16】:

我已经尝试了上述所有方法,但它们都无法解决我笔记本电脑上的相同问题。最后,我没有在 git bash 中将分支推送到原点,而是使用 TortoiseGit 的 push 选项进行推送,然后弹出一个窗口要求我将新的主机密钥添加到缓存,单击是按钮后,一切正常现在好了。

希望对大家有帮助。

【讨论】:

【参考方案17】:

我换了一个硬盘,安装了 Windows。尝试上传文件时收到此命令窗口。

我按“y”,然后按Ctrl + C。打开putty.exe,添加一个旧键然后返回到git并推送文件。

【讨论】:

【参考方案18】:

在 Windows 7 或 10 中,对我有用的技巧是删除 GIT_SSH 系统变量。之前设置使用 Plink,现在被 Putty 取代。这导致了 Plink.exe 错误

由于 PC 是 64 位操作系统,还安装了旧版 Git(32 位版本)并更新到 Git(例如 Git-2.20.1-64-bit.exe)。

无论如何,Git 甚至都没有使用 Putty/Plink,因为在 Git 安装中它默认使用 Open SSH。

【讨论】:

【参考方案19】:

如果您在使用 ATLASSIAN SOURCETREE 执行 git push/pull 操作时收到有关无法识别的主机密钥的消息,则您无法回答 y/n,并且 push/pull 操作将在不缓存密钥的情况下中止。但是,转到 SourceTree 工具-> 选项(常规选项卡)并将(在 SSH 客户端配置下)下的 SSH 客户端从 PuTTY 更改为 OpenSSH 将允许在不更改任何其他内容的情况下缓存密钥。

【讨论】:

【参考方案20】:

只需卸载 Git 扩展并通过选择 OpenSSH 而不是再次安装

【讨论】:

以上是关于git - 服务器主机密钥未缓存的主要内容,如果未能解决你的问题,请参考以下文章

无法“git pull” - 主机密钥验证失败

克隆 git repo 导致错误 - 主机密钥验证失败。致命:远端意外挂断

记一次使用Xshell登陆提示所选用户密钥未在远程主机上注册

GitLab runner 获取子模块的“主机密钥验证失败”

xshell进行ssh链接报错“所选的用户密钥未在远程主机上注册”处理

由于 ssh 密钥,Git 推送失败:主机密钥验证失败。从码头工人内部