Сообщение об ошибке
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`, подписант (signer), который не удалось загрузить и который был молча пропущен, или `ssh.PublicKeysCallback`, работающий через SSH-агент без ключей.
Подпись ключом 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.
Загружайте ключ явно и проверяйте хост
Читайте закрытый ключ, явно завершайте работу с ошибкой, если разобрать его не удалось, и проверяйте ключ хоста через `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)