错误信息
ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
也可能输出为
- ssh: unable to authenticate, attempted methods [none], no supported methods remain
方括号中的列表反映了你配置的 `Auth` 方法。只有 `[none]` 表示客户端根本没有可用的方法——通常是 `Auth` 切片为空,或者密钥加载失败。
golang.org/x/crypto/ssh (Go) — ssh.Dial / ssh.NewClientConn
含义
SSH 传输层已经建立(主机密钥已被接受),但客户端尝试的每种身份验证方法都被拒绝,而服务器也没有提供客户端能用的其他方法。方括号中的列表是 Go 客户端尝试过的方法:`none` 是每个 SSH 客户端最先发送的探测,`publickey` 表示你的密钥已经提供但被拒绝。这是 Go 中与 OpenSSH 的“Permission denied (publickey)”相对应的错误。
原因
密钥不在服务器的 authorized_keys 中
常见程序使用的密钥与安装在服务器上的不是同一个(另一个文件、另一个环境的机密),或者密钥被添加给了另一个用户。
没有配置可用的身份验证方法
常见`Auth` 切片为空、某个签名器加载失败后被静默跳过,或者 `ssh.PublicKeysCallback` 背后的 SSH 代理中没有任何密钥。
RSA 密钥使用 ssh-rsa(SHA-1)签名
偶见OpenSSH 8.8 及以上版本的服务器会拒绝 `ssh-rsa` 签名。旧版 x/crypto 默认用 SHA-1 对 RSA 密钥签名;当前版本会协商 `rsa-sha2-256/512`。升级 golang.org/x/crypto,或者改用 Ed25519 密钥。
远程用户错误
偶见密钥授权给的是 `ubuntu`,客户端却以 `root` 或 `deploy` 身份登录。授权是按用户进行的。
修复方法
- 1.
显式加载密钥并验证主机
读取私钥,解析失败时明确报错,并用 `knownhosts` 检查主机密钥,而不是使用 `ssh.InsecureIgnoreHostKey()`。
go keyBytes, err := os.ReadFile(os.ExpandEnv("$HOME/.ssh/id_ed25519")) if err != nil { return err } signer, err := ssh.ParsePrivateKey(keyBytes) if err != nil { return err } hostKeys, err := knownhosts.New(os.ExpandEnv("$HOME/.ssh/known_hosts")) if err != nil { return err } client, err := ssh.Dial("tcp", "server.example.com:22", &ssh.ClientConfig{ User: "deploy", Auth: []ssh.AuthMethod{ssh.PublicKeys(signer)}, HostKeyCallback: hostKeys, }) - 2.
比对指纹并查看服务器日志
sshd 会在日志中记录拒绝密钥的原因(`~/.ssh` 权限不对、算法不被接受、用户未知)。客户端永远无法得知原因。
bash ssh-keygen -lf ~/.ssh/id_ed25519.pub # fingerprint of the key the program uses ssh deploy@server.example.com 'ssh-keygen -lf ~/.ssh/authorized_keys' sudo journalctl -u ssh -n 20 # sshd's reason (modes, algorithms, user)