跳到主要内容
ecdsa.com
golang.org/x/crypto/ssh (Go)Go

错误信息

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)”相对应的错误。

原因

修复方法

  1. 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. 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)

相关错误

浏览完整的签名错误库