为了账号安全,请及时绑定邮箱和手机立即绑定

尝试通过 SSH 连接到远程主机时出错

尝试通过 SSH 连接到远程主机时出错

Go
慕村9548890 2023-07-31 15:18:13
我正在尝试连接到远程主机以发出命令,但在运行代码时收到以下错误消息:ssh:握手失败:ssh:没有通用的密钥交换算法;客户端提供:[curve25519-sha256@libssh.org ecdh-sha2-nistp256 ecdh-sha2-nistp384 ecdh-sha2-nistp521 diffie-hellman-group14-sha1],服务器提供:[diffie-hellman-group1-sha1]恐慌:运行时错误:无效的内存地址或零指针取消引用[信号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}关于如何解决这个问题有什么想法吗?提前致谢。
查看完整描述

2 回答

?
红颜莎娜

TA贡献1842条经验 获得超12个赞

问题是......服务器只愿意通过 diffie-hellman-group1-sha1 进行对话

和:

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


查看完整回答
反对 回复 2023-07-31
?
慕容708150

TA贡献1831条经验 获得超4个赞

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

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

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

您最终告诉 Go 代码使用 diffie-hellman-group1-sha1 作为通道加密。您无需在此处添加任何内容。原因是SSHConfig.Config.Ciphers最初为零。所以你不妨这样写:

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

以获得相同的效果,即:事情不起作用。

您可以在添加到列表之前调用SetDefaults以使列表非空,但是如果没有此模式的实现,则添加到列表是无效的 - 即使使用新的提交,也不允许 Diffie-Hellman 进行其他任何操作比密钥交换本身。请注意,ssh.Dial调用ssh.NewClientConn,以以下内容开头:

fullConf := *config

fullConf.SetDefaults()

SetDefaults依次在这里并包含:


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. 这又在此处定义并以此注释开头:


// 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.


查看完整回答
反对 回复 2023-07-31
?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

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


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 并未列出


查看完整回答
反对 回复 2023-07-31
  • 2 回答
  • 0 关注
  • 239 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信