OpenSSH client with an SSH agent (ssh-agent, gpg-agent, 1Password, Secretive, Windows OpenSSH agent)SSH
错误信息
sign_and_send_pubkey: signing failed for RSA "/path/to/key" from agent: agent refused operation
也可能输出为
- sign_and_send_pubkey: signing failed: agent refused operation
- sign_and_send_pubkey: signing failed for ED25519 "/path/to/key" from agent: agent refused operation
密钥类型和身份文件路径会有所不同(`RSA`、`ED25519`、`ECDSA-SK` 等)。OpenSSH 8.3 及更早版本输出的是较短的“sign_and_send_pubkey: signing failed: agent refused operation”(已在 7.9 和 8.4 的源代码中核实)。
含义
服务器接受了客户端提供的公钥,于是 ssh 请求 SSH 代理对身份验证挑战签名——而代理拒绝了。密钥存在,服务器也会接受它;没有发生的是私钥运算本身。当代理需要用户交互却无法获得(确认、PIN、触摸)时,或者列出的密钥背后的密钥材料已无法使用时,代理就会拒绝。
原因
代理需要确认,却无法显示确认提示
常见用 `ssh-add -c` 添加的密钥、会请求批准的 1Password/Bitwarden/Secretive 代理,或者 macOS 钥匙串的提示,而 ssh 此时运行在 SSH 会话中、容器中,或者没有图形界面会话(缺少 `SSH_ASKPASS`)。
硬件令牌或 gpg-agent 无法签名
常见YubiKey/智能卡已被拔出或没有及时触摸、PIV PIN 已锁定,或者 gpg-agent 没有可用的 pinentry(没有 `GPG_TTY`)。代理仍会列出该密钥,但无法使用它。
代理中的密钥与身份文件不一致
偶见`-i ~/.ssh/key` 旁边的 `.pub` 文件属于另一个密钥,或者磁盘上的密钥已被替换,而代理中仍是旧密钥。把密钥重新加载到代理中即可解决。
修复方法
- 1.
查明是哪个代理在响应,并重新加载密钥
`SSH_AUTH_SOCK` 指明当前使用的是哪个代理;`ssh-add -l` 列出它持有的密钥。删除密钥再重新添加,可以清除过时的条目。
bash echo "$SSH_AUTH_SOCK" # which agent answers: ssh-agent, gpg-agent, 1Password, ... ssh-add -l # keys the agent holds ssh-add -D && ssh-add ~/.ssh/id_ed25519 # reload a key that the agent cannot use anymore - 2.
为 gpg-agent 指定用于提示的终端
gpg-agent 为 SSH 密钥提供服务时,会在它被告知的 TTY 上显示 PIN 提示;需要从当前 shell 更新这个 TTY。
bash # gpg-agent as SSH agent: tell it which terminal can show the PIN/confirmation prompt export GPG_TTY=$(tty) gpg-connect-agent updatestartuptty /bye