エラーメッセージ
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 のエラーです。
発生する理由
鍵がサーバーの authorized_keys に含まれていない
よくあるプログラムが、サーバーに登録されている鍵とは別の鍵(別のファイル、別の環境のシークレット)を使っているか、鍵が別のユーザーに対して追加されています。
使用できる認証方式が設定されていない
よくある`Auth` スライスが空である、読み込みに失敗した署名者が警告なしにスキップされた、または鍵を保持していない SSH エージェントに基づく `ssh.PublicKeysCallback` を使っている、といったケースです。
RSA 鍵による署名に ssh-rsa(SHA-1)を使っている
ときどきOpenSSH 8.8 以降のサーバーは `ssh-rsa` の署名を拒否します。古いバージョンの x/crypto は、デフォルトで RSA 鍵による署名に SHA-1 を使いますが、現行のバージョンは `rsa-sha2-256/512` をネゴシエートします。golang.org/x/crypto をアップグレードするか、Ed25519 鍵を使ってください。
リモートのユーザーが間違っている
ときどき鍵は `ubuntu` に対して許可されていますが、クライアントは `root` や `deploy` としてログインしています。認可はユーザー単位で行われます。
修正方法
- 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.
フィンガープリントを比較し、サーバーのログを確認する
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)