【问题标题】:Error while trying to connect via SSH to remote host尝试通过 SSH 连接到远程主机时出错
【发布时间】:2020-02-15 23:25:58
【问题描述】:

我正在尝试连接到远程主机以发出命令,但在运行代码时收到以下错误消息:

ssh:握手失败:ssh:没有通用的密钥交换算法;客户端提供:[curve25519-sha256@libssh.org ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 diffie-hellman-group14-sha1],服务器提供:[diffie-hellman-group1-sha1]panic:运行时错误:无效的内存地址或 nil 指针取消引用 [信号SIGSEGV:分段违规代码=0x1 addr=0x10 pc=0x759836]

这是我正在使用的代码:

func (SSHClient *SSH) Connect(mode int) {
    var SSHConfig *ssh.ClientConfig
    var auth []ssh.AuthMethod

    if mode == CERT_PUBLIC_KEY_FILE {
        auth = []ssh.AuthMethod{SSHClient.readPublicKeyFile(SSHClient.Cert)}
    }

    SSHConfig = &ssh.ClientConfig{
        User:            SSHClient.User,
        Auth:            auth,
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
        Timeout:         time.Second * DEFAULT_TIMEOUT,
    }

    SSHConfig.Config.Ciphers = append(SSHConfig.Config.Ciphers, "diffie-hellman-group1-sha1")

    client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%d", SSHClient.IP, SSHClient.Port), SSHConfig)

    if err != nil {
        fmt.Printf("ERROR - While trying to Dial to the host %s with error: %s", SSHClient.IP, err.Error())
        return
    }

    session, err := client.NewSession()
    if err != nil {
        fmt.Printf("ERROR - While trying to create a new session on host %s with error: %s", SSHClient.IP, err.Error())
        client.Close()
        return
    }

    SSHClient.session = session
    SSHClient.client = client
}

关于如何解决此问题的任何想法?

提前致谢。

【问题讨论】:

  • 从错误来看,它看起来像是密码不匹配,即diffie-hellman-group14-sha1 vs diffie-hellman-group1-sha1。尽管所有错误都已得到处理,但我不确定您为什么会在那里收到 panic
  • +1 用于提出与编程和开发有关的 SSH 问题。
  • @happugopher 问题解决了吗?

标签: go encryption ssh


【解决方案1】:

问题是....服务器只愿意讨论 diffie-hellman-group1-sha1

还有:

  • golang/go issue 2903: ssh: add diffie-hellman-group1-sha1,6天前已关闭
  • golang/go/issue 17230:提案:x/crypto/ssh:支持来自 RFC 4419 的 Diffie-Hellman Group Exchange,现在正在实施。

因此,您的客户需要 golang.org/x/crypto/ssh 的分支,例如 bored-engineer/ssh,其中 commit 39a91bcommit fe5e4ff 确实添加了对 diffie-hellman-group1-sha1 的支持。
或者安装最新的golang/crypto,包括commit 57b3e21

【讨论】:

  • 非常感谢 VonC,我会安装最新的 golang/crypto 看看这个问题是否解决了,我明天会发布和更新,希望有一些好消息! :)
  • 更新到最新的golang/crytpo 后,我仍然收到ssh: handshake failed: ssh: no common algorithm for key exchange,也许我需要更改代码中的其他内容?
  • @happygopher 你用的是什么版本的 Go?
  • 我正在使用go version go1.11 linux/amd64
  • @happygopher 你可以试试 Go 1.13.3 吗?
【解决方案2】:

恐慌有点奇怪。显然,当无法就密钥交换算法达成一致时,就会出现问题。作为VonC notes,Diffie-Helman 密钥交换 是最近才添加的(6 月 3 日)。由于您的服务器仅提供该算法,因此没有它您将无法开始。

这不是恐慌的原因(这似乎发生在 ssh.Dial 本身内部),但我会注意到,当你这样做时:

SSHConfig.Config.Ciphers = append(SSHConfig.Config.Ciphers, "diffie-hellman-group1-sha1")

你最终告诉 Go 代码使用 diffie-helman-group1-sha1 作为通道加密。您没有添加到这里的任何东西。原因是 SSHConfig.Config.Ciphers 最初为 nil。所以你不妨写:

SSHConfig.Config.Ciphers = []string{"diffie-hellman-group1-sha1"}

为了达到同样的效果,那就是:事情不行了。

您可以调用SetDefaults 以便在添加到列表之前列表不为空,但是如果没有实现此模式,添加到列表是无效的——即使使用新的提交,Diffie-Helman除了密钥交换本身之外,不允许其他任何事情。请注意ssh.Dial 调用ssh.NewClientConn,即here,并以:

fullConf := *config
fullConf.SetDefaults()

SetDefaults 又是 here 并包含:

if c.Ciphers == nil {
    c.Ciphers = preferredCiphers
}
var ciphers []string
for _, c := range c.Ciphers {
    if cipherModes[c] != nil {
        // reject the cipher if we have no cipherModes definition
        ciphers = append(ciphers, c)
    }
}
c.Ciphers = ciphers

首先表示如果未设置配置的Ciphers,则应使用默认值,然后立即过滤掉任何不在cipherModes 中的字符串。这又被定义为here,并以这条评论开头:

// cipherModes documents properties of supported ciphers. Ciphers not included
// are not supported and will not be negotiated, even if explicitly requested in
// ClientConfig.Crypto.Ciphers.

该短语不在文档中。它应该是! 即使在ClientConfig.Crypto.Ciphers 中明确要求,不支持且不会协商未包含的密码。

(请参阅上面的最后一个链接,了解 支持的密码集。请注意,此列表随着时间的推移而增加。)

【讨论】:

  • 嗨 Torek,感谢您的回复和解释,就像我说我会尝试 VonC 回复关于安装最新的 golang/crypto 并查看是否解决了我的问题,明天将发布和更新。谢谢你们两个:)
【解决方案3】:

Diffie-hellman-group1-sha1 是一种密钥交换算法。应该是 KeyExchanges 而不是 Config 结构中的密码

SSHConfig.Config.KeyExchanges = append(SSHConfig.Config.KeyExchanges, "diffie-hellman-group1-sha1")

代替

SSHConfig.Config.Ciphers = append(SSHConfig.Config.Ciphers, "diffie-hellman-group1-sha1")

如果没有指定 KeyExchanges,则使用的默认算法可以在 ssh/common.go 中找到

// preferredKexAlgos specifies the default preference for key-exchange algorithms
// in preference order.
var preferredKexAlgos = []string{
    kexAlgoCurve25519SHA256,
    kexAlgoECDH256, kexAlgoECDH384, kexAlgoECDH521,
    kexAlgoDH14SHA1,
}

如您所见,kexAlgoDH1SHA1 或 diffie-hellman-group1-sha1 目前没有列出

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2011-08-08
    • 1970-01-01
    • 2021-04-19
    • 1970-01-01
    相关资源
    最近更新 更多