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


101

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

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%正确吗?


2
好像$HOME没有正确设置。尝试HOME使用My Computer->右键单击-> Properties->选项卡Advanced->按钮在Windows上设置环境变量Environment Variables
eckes 2011年

1
我不是Windows专家,但确实令我感到奇怪,因为在/c//您仍然拥有(可能是驱动器号)之后%HOMEDRIVE%……您可以通过摆弄自己的值并回显它来节省一些时间?
卡斯卡贝尔2011年

1
展开HOMEDRIVEHOMEPATH设置HOME为结果值...
eckes 2011年

Answers:


54

该消息表示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

或者,您也可以手动添加originto 的键,.ssh/known_hosts但这要求您遵循(Section AUTHORIZED_KEYS FILE FORMATknown_hosts手册页中所述的文件格式sshd


4
当推送到github时,我得到了相同的消息,但是我可以ssh到github,并且我的known_hosts文件中确实有github.com 。
Magnus Lindhe

1
在这种情况下,请在下面寻找答案
Nikita Koksharov 2013年

3
出于相同目的,您可以在Windows上使用PuTTY代替命令行SSH客户端。
brianmearns 2014年

1
确保主机名完全相同。例如,如果您在本地安装了git,并使用名称“ home.mydomain.com”作为远程主机,但是使用腻子存储密钥以连接到“本地主机”,则将无法使用。您需要准确连接到远程URL中的主机名。
杰森·古玛

对我来说,修复了将腻子连接到服务器的问题。可以说git url是ssh://git@example.ex.com:222 / something / shop.git,所以我输入了腻子主机名字段example.ex.com和端口222。然后连接失败,但我猜它添加了手指在需要的地方打印。我只是不明白它的添加位置,因为在我的主目录中known_hosts-删除旧密钥时,文件不受影响
Darius.V 2015年

157

对于通过标准命令提示符使用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服务的指纹(请编辑以添加更多):


15
这应该是公认的答案。这正是错误消息所指的含义。在我克隆的情况下,我使用的是FQDN,但在新机器上,我仅使用短本地域名登录。我必须通过putty或plink作为FQDN登录,才能在源上缓存主机名的密钥。使用“ git remote -v”可以交叉检查用作远程主机的主机名。
豌豆

3
它还可以将交互式PuTTY用于您要使用的主机。例如,如果您是第一次尝试在新的Windows计算机上克隆Github存储库,请使用PuTTY打开与主机“ github.com”的会话,接受有关服务器信任的提示,然后在服务器上进行克隆。命令行应该工作。
杰里米·麦基2014年

1
您可以plink通过运行$ set | grep GIT_SSH并检查GIT_SSH='C:\Program Files (x86)\PuTTY\plink.exe'
shuckc

2
我最终通过将密钥添加到Pageant并直接使用Putty访问主机来解决了这个问题。这要求您将主机添加到缓存。做同样的事情。
Knossos 2014年

1
如果您的git信息库在自定义SSH端口上提供,请使用-P来选择端口,例如:plink.exe example.com -P 2222。我可以从github克隆,但不能从我的个人服务器克隆,这使我困惑不已。
干草

79

尝试从Git Bash提示符下执行“设置| 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=

1
“未设置GIT_SSH”对我有用。我以前为另一台服务器设置了Pageant / putty,但是当我使用Git Bash提示符构建新密钥时,我需要返回。谢谢您的帮助。
supermitch 2012年

采取您的步骤后,我走得更远,但现在出现“输入时损坏的Mac”错误……见过那个吗?
CD Smith

2
安装git时,您可以选择不设置这些变量。它甚至是默认变体。尽管我也选择了plink集成,但这就是为什么我在这里)谢谢。
Antony Hatchkins 2013年

1
这在Win7上也对我有用。显然,在我的情况下git bash的plink设置引起了问题。
nhylated

2
unset GIT_SSH也为我工作,尽管每次启动git bash时我都要这样做,这很无聊。关于如何自动化的任何想法?
卢瓦克

19

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

如果这确实是您的情况,并且如果您要使用Pageant,则可能是故意的,则需要先使用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的结果。非常感谢!
amsross

1
使用Stash(现在为Bitbucket)存储库,我不得不使用"$GIT_SSH" -P 7999 git@stash.domain.local
Julien 2015年

4

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

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


ssh/known_hosts是相对于什么?,%USERPROFILE%我在Win 7上遇到了这个问题,没有解决方案...
Frank Nocke 2012年

2

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


2

Plink解决方案

将此python脚本保存到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格式。


2

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


也可以使用完全相同的方式指定主机,例如,对于ssh不使用gitserver.example.com,对于git不使用gitserver。
Matthijs P 2014年

2

只需打开Putty并尝试建立与您要推送代码的远程服务器的连接。当对话框出现时,按是(您信任远程),则一切正常。


2

工作环境:

  • Windows 10
  • 吉特
  • 油灰

第一:根据Regedit删除腻子已知的主机。
然后:%GIT_SSH% user@hostname在Window的cmd中执行命令即可解决该问题。

希望对您有帮助。


1

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

对我有用的是运行Pageant(Putty身份验证代理)程序。一旦Pageant在后台运行,我就可以克隆,从存储库中推入/拉入。这对我有用,可能是因为我已经设置了我的公共密钥,以便每次首次使用它都需要输入密码并启动选美。


当它的选美问题时,您收到其他错误消息。不是Connection abandoned,而是类似Access denied (private key)
Andrey Regentov

1

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


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

1

我使用此替代方法解决了类似的问题。

您只需要切换到Embedded Git,推动,按Yes按钮,然后再切换回System Git。

您可以在以下位置找到此选项

Tools -> Options -> Git

1
现在位于v2.5.5.0位置:C:\Users\{UserName}\AppData\Local\SourceTree\app-2.5.5\tools\putty> .\plink.exe {YourNewHost}
John_J

1

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

对于使用Git Extensions的人

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

(用实际路径代替)

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

例如

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

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


0

使用Bash直接添加主机不能解决问题,在Git Extensions中使用“全部获取”时仍然会发生错误。通过在一个分支上使用“拉”,所需的主机由Git Extensions随Bash弹出屏幕自动添加。完成此操作后,我可以再次使用“全部提取”。不知道Git Extensions会做什么。


0

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

希望对您有帮助。


0

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

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



0

在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。


0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.