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

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

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

}

关于如何解决这个问题有什么想法吗?


提前致谢。


慕村9548890
浏览 253回答 2
2回答

红颜莎娜

问题是......服务器只愿意通过 diffie-hellman-group1-sha1 进行对话和:golang/go 问题 2903 : ssh: 添加 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,其中提交 39a91b和提交 fe5e4ff确实添加了对 diffie-hellman-group1-sha1 的支持。或者安装最新的golang/crypto,其中包括提交 57b3e21。

慕容708150

恐慌有些奇怪。显然,当无法就密钥交换算法达成一致时,就会出现问题。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 := *configfullConf.SetDefaults()SetDefaults依次在这里并包含:if c.Ciphers == nil {    c.Ciphers = preferredCiphers}var ciphers []stringfor _, 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.

梵蒂冈之花

Diffie-hellman-group1-sha1 是一种密钥交换算法。Config 结构中应该是 KeyExchanges 而不是 CiphersSSHConfig.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 并未列出
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go