You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

gCloud Ubuntu22.04实例goph库SSH公钥认证失败问题排查

问题根因

Ubuntu 22.04 预装的 OpenSSH 服务端版本为 8.9p1,该版本默认禁用了基于 SHA-1 哈希的 ssh-rsa 公钥签名算法(SHA-1 已被证明存在碰撞风险,属于不安全的哈希算法)。
你使用的 goph 库依赖 Go 官方的 golang.org/x/crypto/ssh 模块,低于 v0.0.0-20210616213533-5ff15b29337e 版本的该模块,默认未启用 rsa-sha2-256、rsa-sha2-512 这两个安全的 RSA 签名算法,因此和 Ubuntu 22.04 的 SSH 服务端协商认证算法失败,触发公钥认证报错。
手动执行 ssh 命令可以正常连接,是因为系统自带的 OpenSSH 8.x 以上版本客户端默认支持上述两个 SHA-2 系列的 RSA 签名算法;Ubuntu 16.04 预装的 OpenSSH 版本为 7.2p2,尚未默认禁用 ssh-rsa 算法,因此旧版本实例可以正常连通。

解决方案

优先选择客户端侧修复(安全性更高,不需要调整服务端配置),如果暂时无法修改客户端代码,再选择服务端配置兼容。

方案一:升级客户端依赖(推荐)

  • 升级项目依赖的 golang.org/x/crypto 版本到最新稳定版:
go get golang.org/x/crypto/ssh@latest
go mod tidy
  • 由于 goph 库默认的 SSH 配置未显式声明启用 RSA-SHA2 算法,你需要替换 goph 默认的配置逻辑,手动在 SSH 客户端配置中添加签名算法支持,修改连接代码如下:
package main

import (
	"net"
	"time"
	"fmt"
	"log"

	"github.com/briandowns/spinner"
	"github.com/melbahja/goph"
	"golang.org/x/crypto/ssh"
)

func Connect(privateKey, username string, ip net.Addr) (*goph.Client, error) {
	// 解析私钥
	priKey, err := goph.Key(privateKey, "")
	if err != nil {
		return nil, fmt.Errorf("读取私钥 %s 失败: %v", privateKey, err)
	}

	// 自定义SSH配置,补充RSA-SHA2签名算法支持
	sshConfig := &ssh.ClientConfig{
		User: username,
		Auth: []ssh.AuthMethod{priKey},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
		// 显式指定支持的公钥算法,包含rsa-sha2系列
		PublicKeyAlgorithms: []string{
			ssh.KeyAlgoRSA,
			ssh.KeyAlgoRSASHA256,
			ssh.KeyAlgoRSASHA512,
			ssh.KeyAlgoED25519,
			ssh.KeyAlgoECDSA256,
			ssh.KeyAlgoECDSA384,
			ssh.KeyAlgoECDSA521,
		},
		Timeout: 10 * time.Second,
	}

	c := 0
	for {
		log.Printf("尝试连接SSH: %v", ip)

		s := spinner.New(spinner.CharSets[9], 100*time.Millisecond)
		s.Start()
		time.Sleep(20 * time.Second)
		s.Stop()

		// 使用自定义配置建立连接,替换原有goph.NewUnknown调用
		client, err := goph.NewConn(&goph.Config{
			User:     username,
			Addr:     ip.String(),
			Port:     22,
			Auth:     []goph.Auth{priKey},
			Callback: sshConfig.HostKeyCallback,
			Config:   sshConfig,
		})
		if err != nil {
			c++
		} else {
			log.Printf("成功连接: %v", ip.String())
			return client, nil
		}

		if c >= 3 {
			return nil, fmt.Errorf("连接 %v 失败,重试次数耗尽,最后一次错误: %v", ip.String(), err)
		}
	}
}

方案二:调整服务端SSH配置兼容旧客户端(不推荐,存在安全风险)

如果暂时无法修改客户端代码,可以在 Ubuntu 22.04 实例侧调整 SSH 服务配置,重新启用 ssh-rsa 算法支持:

  • 编辑 SSH 服务配置文件:
sudo nano /etc/ssh/sshd_config
  • 在文件末尾添加以下配置行:
PubkeyAcceptedAlgorithms +ssh-rsa
HostKeyAlgorithms +ssh-rsa
  • 保存退出后,重启 SSH 服务生效:
sudo systemctl restart sshd
验证说明

修改完成后重新运行Go代码即可正常连接,你之前尝试的私钥权限600配置、ssh-add添加私钥操作和当前算法协商问题无关联,不需要额外调整。


内容的提问来源于stack exchange,提问作者amb1s1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:21:37