本文へスキップ
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` は鍵が提示されて拒否されたことを意味します。これは、OpenSSH の「Permission denied (publickey)」に相当する Go のエラーです。

発生する理由

修正方法

  1. 1.

    鍵を明示的に読み込み、ホストを検証する

    秘密鍵を読み込み、解析に失敗した場合ははっきりとエラーにしてください。ホスト鍵の確認には、`ssh.InsecureIgnoreHostKey()` ではなく `knownhosts` を使ってください。

    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)

関連するエラー

署名エラーデータベースをすべて見る